Skip to content

Commit

Permalink
Merge pull request #35 from projectNEWM/amw/health_metrics_api
Browse files Browse the repository at this point in the history
Add health metrics API
  • Loading branch information
AndrewWestberg authored May 30, 2024
2 parents e509b16 + a788c90 commit 6224cfb
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 9 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (!project.hasProperty("isGithubActions")) {
}

group = "io.newm"
version = "2.2.1-SNAPSHOT"
version = "2.2.2-SNAPSHOT"

java.sourceCompatibility = JavaVersion.VERSION_21
java.targetCompatibility = JavaVersion.VERSION_21
Expand Down
20 changes: 14 additions & 6 deletions src/main/kotlin/io/newm/kogmios/ClientImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.websocket.*
import io.ktor.client.request.*
import io.ktor.client.statement.bodyAsText
import io.ktor.http.*
import io.ktor.serialization.*
import io.ktor.util.reflect.*
Expand All @@ -14,8 +15,15 @@ import io.newm.kogmios.protocols.messages.*
import io.newm.kogmios.protocols.model.*
import io.newm.kogmios.protocols.model.fault.InternalErrorFault
import io.newm.kogmios.protocols.model.fault.StringFaultData
import io.newm.kogmios.protocols.model.result.HealthResult
import io.newm.kogmios.serializers.BigFractionSerializer
import io.newm.kogmios.serializers.BigIntegerSerializer
import java.io.IOException
import java.math.BigInteger
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.collections.set
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ClosedReceiveChannelException
Expand All @@ -28,12 +36,6 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import org.apache.commons.numbers.fraction.BigFraction
import org.slf4j.LoggerFactory
import java.io.IOException
import java.math.BigInteger
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.collections.set
import kotlin.coroutines.CoroutineContext

internal class ClientImpl(
private val websocketHost: String,
Expand Down Expand Up @@ -509,6 +511,12 @@ internal class ClientImpl(
}
}

override suspend fun health(): HealthResult {
val response = httpClient.get("http://$websocketHost:$websocketPort/health")
val jsonBody = response.bodyAsText()
return json.decodeFromString(jsonBody)
}

override suspend fun acquireMempool(timeoutMs: Long): MsgAcquireMempoolResponse {
assertConnected()
val message = MsgAcquireMempool()
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/io/newm/kogmios/StateQueryClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import io.newm.kogmios.protocols.model.Origin
import io.newm.kogmios.protocols.model.ParamsProjectedRewards
import io.newm.kogmios.protocols.model.ParamsUtxo
import io.newm.kogmios.protocols.model.PointOrOrigin
import io.newm.kogmios.protocols.model.result.HealthResult

/**
* Client interface for querying the state of the node and ledger.
Expand Down Expand Up @@ -128,6 +129,11 @@ interface StateQueryClient : Client {
params: ParamsUtxo,
timeoutMs: Long = DEFAULT_REQUEST_TIMEOUT_MS
): MsgQueryUtxoResponse

/**
* Get the health of the node.
*/
suspend fun health(): HealthResult
}

fun createStateQueryClient(
Expand Down
28 changes: 28 additions & 0 deletions src/main/kotlin/io/newm/kogmios/protocols/model/CardanoEra.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.newm.kogmios.protocols.model

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames

@Serializable
enum class CardanoEra {
@JsonNames("byron")
BYRON,

@JsonNames("shelley")
SHELLEY,

@JsonNames("allegra")
ALLEGRA,

@JsonNames("mary")
MARY,

@JsonNames("alonzo")
ALONZO,

@JsonNames("babbage")
BABBAGE,

@JsonNames("conway")
CONWAY,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.newm.kogmios.protocols.model.result

import io.newm.kogmios.protocols.model.CardanoEra
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class HealthResult(
@SerialName("connectionStatus")
val connectionStatus: String,
@SerialName("currentEpoch")
val currentEpoch: Long,
@SerialName("currentEra")
val currentEra: CardanoEra,
@SerialName("lastKnownTip")
val lastKnownTip: LastKnownTip,
@SerialName("lastTipUpdate")
val lastTipUpdate: String,
@SerialName("metrics")
val metrics: Metrics,
@SerialName("network")
val network: String,
@SerialName("networkSynchronization")
val networkSynchronization: Double,
@SerialName("slotInEpoch")
val slotInEpoch: Long,
@SerialName("startTime")
val startTime: String,
@SerialName("version")
val version: String
)

// {
// "metrics": {
// "totalUnrouted": 1,
// "totalMessages": 30029,
// "runtimeStats": {
// "gcCpuTime": 1233009354,
// "cpuTime": 81064672549,
// "maxHeapSize": 41630,
// "currentHeapSize": 1014
// },
// "totalConnections": 10,
// "sessionDurations": {
// "max": 57385,
// "mean": 7057,
// "min": 0
// },
// "activeConnections": 0
// },
// "startTime": "2021-03-15T16:16:41.470782977Z",
// "lastTipUpdate": "2021-03-15T16:28:36.853115034Z",
// "lastKnownTip": {
// "hash": "c29428f386c701c1d1ba1fd259d4be78921ee9ee6c174eac898245ceb55e8061",
// "blockNo": 5034297,
// "slot": 15520688
// },
// "networkSynchronization": 0.99,
// "currentEra": "mary",
// "connectionStatus": "disconnected",
// "currentEpoch": 164,
// "slotInEpoch": 324543,
// "version": "6.0.0",
// "network": "mainnet"
// }
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.newm.kogmios.protocols.model.result

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class LastKnownTip(
@SerialName("height")
val height: Long,
@SerialName("id")
val id: String,
@SerialName("slot")
val slot: Long,
)
20 changes: 20 additions & 0 deletions src/main/kotlin/io/newm/kogmios/protocols/model/result/Metrics.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.newm.kogmios.protocols.model.result

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class Metrics(
@SerialName("activeConnections")
val activeConnections: Int,
@SerialName("runtimeStats")
val runtimeStats: RuntimeStats,
@SerialName("sessionDurations")
val sessionDurations: SessionDurations,
@SerialName("totalConnections")
val totalConnections: Long,
@SerialName("totalMessages")
val totalMessages: Long,
@SerialName("totalUnrouted")
val totalUnrouted: Long,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.newm.kogmios.protocols.model.result

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RuntimeStats(
@SerialName("cpuTime")
val cpuTime: Long,
@SerialName("currentHeapSize")
val currentHeapSize: Long,
@SerialName("gcCpuTime")
val gcCpuTime: Long,
@SerialName("maxHeapSize")
val maxHeapSize: Long,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.newm.kogmios.protocols.model.result

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class SessionDurations(
@SerialName("max")
val max: Double,
@SerialName("mean")
val mean: Double,
@SerialName("min")
val min: Double,
)
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import io.newm.kogmios.protocols.model.result.ProjectedRewardsResult
import io.newm.kogmios.protocols.model.result.RewardAccountSummariesResult
import io.newm.kogmios.protocols.model.result.StakePoolsResult
import io.newm.kogmios.protocols.model.result.UtxoResult
import java.io.IOException
import java.math.BigInteger
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
Expand All @@ -33,8 +35,6 @@ import kotlinx.coroutines.runBlocking
import kotlinx.datetime.Instant
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import java.io.IOException
import java.math.BigInteger

class StateQueryTest {
companion object {
Expand All @@ -49,6 +49,25 @@ class StateQueryTest {
// private const val TEST_SECURE = true
}

@Test
fun `test health`() =
runBlocking {
createStateQueryClient(
websocketHost = TEST_HOST,
websocketPort = TEST_PORT,
secure = TEST_SECURE,
).use { client ->
val connectResult = client.connect()
assertThat(connectResult).isTrue()
assertThat(client.isConnected).isTrue()

val response = client.health()
assertThat(response).isNotNull()
assertThat(response.connectionStatus).isEqualTo("connected")
println(response)
}
}

@Test
fun `test acquire origin`() =
runBlocking {
Expand Down

0 comments on commit 6224cfb

Please sign in to comment.