Skip to content

Commit

Permalink
feat: add agent version not supported error (#680)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
Idane and avivm authored Jul 9, 2023
1 parent 35fb28f commit 42a7880
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 6 deletions.
2 changes: 2 additions & 0 deletions app/src/renderer/lang/locales/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
11 changes: 11 additions & 0 deletions app/src/renderer/layout/agent/components/health/AgentUnhealthy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export default function AgentUnhealthy({ item }: AgentUnhealthyProps) {
{` (${health.message})`}
</>
);
case -5:
return (
<>
<FormattedMessage id={'agentVersionNotSupported'} />
{` (${health.message})`}
</>
);
case -999:
default:
return (
Expand Down Expand Up @@ -85,6 +92,10 @@ export default function AgentUnhealthy({ item }: AgentUnhealthyProps) {
<FormattedMessage id={'checkAgentUrl'} />
</Link>
);
case -5:
return health.info?.version ? (
<FormattedMessage id={'currentAgentVersion'} values={{ version: health.info?.version }} />
) : undefined;
default:
return undefined;
}
Expand Down
1 change: 1 addition & 0 deletions daemon/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Throwable, AgentHealthDTO> {
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) {
Expand All @@ -30,4 +42,11 @@ class AgentHealthConverter : Converter<Throwable, AgentHealthDTO> {
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) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"))
Expand Down

0 comments on commit 42a7880

Please sign in to comment.