From 42a788002007b7088673569974f20cc4c3a21509 Mon Sep 17 00:00:00 2001 From: Idan Elhalwani Date: Sun, 9 Jul 2023 10:22:37 +0300 Subject: [PATCH] feat: add agent version not supported error (#680) * feat: add agent version not supported error * feat: add agent version not supported message * fix: unsupported agent version message * Fix flaky test --------- Co-authored-by: avivm --- app/src/renderer/lang/locales/en_US.ts | 2 ++ .../components/health/AgentUnhealthy.tsx | 11 ++++++++ daemon/build.gradle.kts | 1 + .../daemon/agent/AgentHealthConverter.kt | 25 ++++++++++++++++--- .../boost/daemon/agent/AgentHealthService.kt | 4 +-- .../daemon/agent/model/AgentHealthDTO.kt | 10 ++++++++ .../AgentHealthServiceIntegrationTest.kt | 14 ++++++++++- 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/app/src/renderer/lang/locales/en_US.ts b/app/src/renderer/lang/locales/en_US.ts index ace6d1b4..1f972663 100755 --- a/app/src/renderer/lang/locales/en_US.ts +++ b/app/src/renderer/lang/locales/en_US.ts @@ -538,6 +538,8 @@ export default { agentIsEmpty: 'Agent is empty', agentNotFindInstances: 'The agent did not find any instances yet. You can run the discovery again by right clicking the agent and selecting "Sync Agent".', + currentAgentVersion: 'The current agent version is {version}.', + agentVersionNotSupported: 'Agent version not supported', agentUrl: 'Agent URL', checkAgentUrl: 'Check Agent URL', apiKey: 'API Key', diff --git a/app/src/renderer/layout/agent/components/health/AgentUnhealthy.tsx b/app/src/renderer/layout/agent/components/health/AgentUnhealthy.tsx index 658bf651..891a1e20 100644 --- a/app/src/renderer/layout/agent/components/health/AgentUnhealthy.tsx +++ b/app/src/renderer/layout/agent/components/health/AgentUnhealthy.tsx @@ -56,6 +56,13 @@ export default function AgentUnhealthy({ item }: AgentUnhealthyProps) { {` (${health.message})`} ); + case -5: + return ( + <> + + {` (${health.message})`} + + ); case -999: default: return ( @@ -85,6 +92,10 @@ export default function AgentUnhealthy({ item }: AgentUnhealthyProps) { ); + case -5: + return health.info?.version ? ( + + ) : undefined; default: return undefined; } diff --git a/daemon/build.gradle.kts b/daemon/build.gradle.kts index cefbb68c..1aa5931f 100644 --- a/daemon/build.gradle.kts +++ b/daemon/build.gradle.kts @@ -107,6 +107,7 @@ dependencies { implementation("io.github.openfeign:feign-core:12.4") implementation("io.github.openfeign:feign-jackson:12.4") implementation("io.github.openfeign:feign-okhttp:12.4") + implementation("com.vdurmont:semver4j:3.1.0") // Added separately from springdoc for production builds implementation("io.swagger.core.v3:swagger-annotations-jakarta:2.2.15") diff --git a/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthConverter.kt b/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthConverter.kt index 813dd992..81e53c88 100644 --- a/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthConverter.kt +++ b/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthConverter.kt @@ -1,17 +1,29 @@ package dev.krud.boost.daemon.agent import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException +import com.vdurmont.semver4j.Semver import dev.krud.boost.daemon.agent.model.AgentHealthDTO +import dev.krud.boost.daemon.agent.model.AgentInfoDTO import feign.FeignException import feign.RetryableException -import org.springframework.core.convert.converter.Converter import org.springframework.stereotype.Component import java.net.ConnectException import javax.net.ssl.SSLException @Component -class AgentHealthConverter : Converter { - override fun convert(source: Throwable): AgentHealthDTO { +class AgentHealthConverter { + fun convertInfo(source: AgentInfoDTO): AgentHealthDTO { + val agentSemver = source.version.toSemver() + if (agentSemver == null || !agentSemver.satisfies(SUPPORTED_AGENT_VERSION_RANGE)) { + return AgentHealthDTO.notSupported( + source, + SUPPORTED_AGENT_VERSION_RANGE + ) + } + return AgentHealthDTO.ok(source) + } + + fun convertException(source: Throwable): AgentHealthDTO { return when (source) { is RetryableException -> { when (source.cause) { @@ -30,4 +42,11 @@ class AgentHealthConverter : Converter { else -> AgentHealthDTO.error(message = source.message) } } + + companion object { + const val SUPPORTED_AGENT_VERSION_RANGE = ">=0.0.12" + private fun String?.toSemver(): Semver? { + return this?.let { Semver(it, Semver.SemverType.NPM) } + } + } } \ No newline at end of file diff --git a/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthService.kt b/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthService.kt index eddce952..65c1f323 100644 --- a/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthService.kt +++ b/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/AgentHealthService.kt @@ -99,8 +99,8 @@ class AgentHealthService( client.getAgentInfo(agent.apiKey) } .fold( - onSuccess = { AgentHealthDTO.ok(it) }, - onFailure = { agentHealthConverter.convert(it) } + onSuccess = { agentHealthConverter.convertInfo(it) }, + onFailure = { agentHealthConverter.convertException(it) } ) } diff --git a/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/model/AgentHealthDTO.kt b/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/model/AgentHealthDTO.kt index 7cecb751..f59feac1 100644 --- a/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/model/AgentHealthDTO.kt +++ b/daemon/src/main/kotlin/dev/krud/boost/daemon/agent/model/AgentHealthDTO.kt @@ -17,6 +17,7 @@ data class AgentHealthDTO( const val UNREACHABLE = -2 const val NOT_AGENT = -3 const val SSL_ERROR = -4 + const val AGENT_NOT_SUPPORTED = -5 enum class Status { PENDING, UNHEALTHY, HEALTHY @@ -69,5 +70,14 @@ data class AgentHealthDTO( status = Status.UNHEALTHY ) } + + fun notSupported(info: AgentInfoDTO, supportedVersionRange: String): AgentHealthDTO { + return AgentHealthDTO( + statusCode = AGENT_NOT_SUPPORTED, + message = "Agent version ${info.version} is not supported, required version range is $supportedVersionRange", + status = Status.UNHEALTHY, + info = info + ) + } } } \ No newline at end of file diff --git a/daemon/src/test/kotlin/dev/krud/boost/daemon/agent/AgentHealthServiceIntegrationTest.kt b/daemon/src/test/kotlin/dev/krud/boost/daemon/agent/AgentHealthServiceIntegrationTest.kt index cc5bc824..0dc849e2 100644 --- a/daemon/src/test/kotlin/dev/krud/boost/daemon/agent/AgentHealthServiceIntegrationTest.kt +++ b/daemon/src/test/kotlin/dev/krud/boost/daemon/agent/AgentHealthServiceIntegrationTest.kt @@ -34,7 +34,7 @@ import java.util.concurrent.TimeUnit import javax.net.ssl.SSLException @IntegrationTest -@DirtiesContext +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) class AgentHealthServiceIntegrationTest { @Autowired private lateinit var agentHealthService: AgentHealthService @@ -141,6 +141,18 @@ class AgentHealthServiceIntegrationTest { } } + @Test + fun `fetchAgentHealth should return agent not supported if agent version is not supported`() { + val info = AgentInfoDTO("0.0.1", setOf("Internal")) + primeInfoSuccess(info) + val health = agentHealthService.fetchAgentHealth(theAgent.id) + expect { + that(health.info).isEqualTo(info) + that(health.statusCode).isEqualTo(-5) + that(health.status).isEqualTo(AgentHealthDTO.Companion.Status.UNHEALTHY) + } + } + @Test fun `agent health change should fire event`() { val info = AgentInfoDTO("1.2.3", setOf("Internal"))