mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-14 00:46:44 +00:00
feat: Rest endoint /health for rln (#2011)
* Rest endoint /health added * Remove dev-debug echo * Changed not ready message * Update waku/node/rest/health/handlers.nim Co-authored-by: Ivan Folgueira Bande <128452529+Ivansete-status@users.noreply.github.com> * Various fixes on PR foundings, added comments --------- Co-authored-by: Ivan Folgueira Bande <128452529+Ivansete-status@users.noreply.github.com>
This commit is contained in:
parent
a8095d871e
commit
fc6194bb6b
@ -47,6 +47,7 @@ import
|
||||
../../waku/node/rest/relay/topic_cache,
|
||||
../../waku/node/rest/filter/handlers as rest_filter_api,
|
||||
../../waku/node/rest/store/handlers as rest_store_api,
|
||||
../../waku/node/rest/health/handlers as rest_health_api,
|
||||
../../waku/node/jsonrpc/admin/handlers as rpc_admin_api,
|
||||
../../waku/node/jsonrpc/debug/handlers as rpc_debug_api,
|
||||
../../waku/node/jsonrpc/filter/handlers as rpc_filter_api,
|
||||
@ -569,6 +570,9 @@ proc startRestServer(app: App, address: ValidIpAddress, port: Port, conf: WakuNo
|
||||
## Debug REST API
|
||||
installDebugApiHandlers(server.router, app.node)
|
||||
|
||||
## Health REST API
|
||||
installHealthApiHandler(server.router, app.node)
|
||||
|
||||
## Relay REST API
|
||||
if conf.relay:
|
||||
let relayCache = TopicCache.init(capacity=conf.restRelayCacheCapacity)
|
||||
|
@ -102,4 +102,5 @@ when defined(rln):
|
||||
./waku_rln_relay/test_waku_rln_relay,
|
||||
./waku_rln_relay/test_wakunode_rln_relay,
|
||||
./waku_rln_relay/test_rln_group_manager_onchain,
|
||||
./waku_rln_relay/test_rln_group_manager_static
|
||||
./waku_rln_relay/test_rln_group_manager_static,
|
||||
./wakunode_rest/test_rest_health
|
||||
|
77
tests/wakunode_rest/test_rest_health.nim
Normal file
77
tests/wakunode_rest/test_rest_health.nim
Normal file
@ -0,0 +1,77 @@
|
||||
{.used.}
|
||||
|
||||
import
|
||||
std/tempfiles,
|
||||
stew/shims/net,
|
||||
testutils/unittests,
|
||||
presto,
|
||||
presto/client as presto_client,
|
||||
libp2p/peerinfo,
|
||||
libp2p/multiaddress,
|
||||
libp2p/crypto/crypto
|
||||
import
|
||||
../../waku/waku_node,
|
||||
../../waku/node/waku_node as waku_node2, # TODO: Remove after moving `git_version` to the app code.
|
||||
../../waku/node/rest/server,
|
||||
../../waku/node/rest/client,
|
||||
../../waku/node/rest/responses,
|
||||
../../waku/node/rest/health/handlers as health_api,
|
||||
../../waku/node/rest/health/client as health_api_client,
|
||||
../../waku/waku_rln_relay,
|
||||
../testlib/common,
|
||||
../testlib/wakucore,
|
||||
../testlib/wakunode
|
||||
|
||||
|
||||
proc testWakuNode(): WakuNode =
|
||||
let
|
||||
privkey = crypto.PrivateKey.random(Secp256k1, rng[]).tryGet()
|
||||
bindIp = ValidIpAddress.init("0.0.0.0")
|
||||
extIp = ValidIpAddress.init("127.0.0.1")
|
||||
port = Port(0)
|
||||
|
||||
newTestWakuNode(privkey, bindIp, port, some(extIp), some(port))
|
||||
|
||||
|
||||
suite "Waku v2 REST API - health":
|
||||
asyncTest "Get node health info - GET /health":
|
||||
# Given
|
||||
let node = testWakuNode()
|
||||
await node.start()
|
||||
await node.mountRelay()
|
||||
|
||||
let restPort = Port(58001)
|
||||
let restAddress = ValidIpAddress.init("0.0.0.0")
|
||||
let restServer = RestServerRef.init(restAddress, restPort).tryGet()
|
||||
|
||||
installHealthApiHandler(restServer.router, node)
|
||||
restServer.start()
|
||||
let client = newRestHttpClient(initTAddress(restAddress, restPort))
|
||||
|
||||
# When
|
||||
var response = await client.healthCheck()
|
||||
|
||||
# Then
|
||||
check:
|
||||
response.status == 503
|
||||
$response.contentType == $MIMETYPE_TEXT
|
||||
response.data == "Node is not ready"
|
||||
|
||||
# now kick in rln (currently the only check for health)
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
||||
))
|
||||
|
||||
# When
|
||||
response = await client.healthCheck()
|
||||
|
||||
# Then
|
||||
check:
|
||||
response.status == 200
|
||||
$response.contentType == $MIMETYPE_TEXT
|
||||
response.data == "Node is healthy"
|
||||
|
||||
await restServer.stop()
|
||||
await restServer.closeWait()
|
||||
await node.stop()
|
30
waku/node/rest/health/client.nim
Normal file
30
waku/node/rest/health/client.nim
Normal file
@ -0,0 +1,30 @@
|
||||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
chronicles,
|
||||
json_serialization,
|
||||
json_serialization/std/options,
|
||||
presto/[route, client]
|
||||
import
|
||||
../serdes,
|
||||
../responses
|
||||
|
||||
logScope:
|
||||
topics = "waku node rest health_api"
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
|
||||
proc healthCheck*(): RestResponse[string] {.rest, endpoint: "/health", meth: HttpMethod.MethodGet.}
|
42
waku/node/rest/health/handlers.nim
Normal file
42
waku/node/rest/health/handlers.nim
Normal file
@ -0,0 +1,42 @@
|
||||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
chronicles,
|
||||
json_serialization,
|
||||
presto/route
|
||||
import
|
||||
../../waku_node,
|
||||
../responses,
|
||||
../serdes
|
||||
|
||||
logScope:
|
||||
topics = "waku node rest health_api"
|
||||
|
||||
const ROUTE_HEALTH* = "/health"
|
||||
|
||||
const FutIsReadyTimout = 5.seconds
|
||||
|
||||
proc installHealthApiHandler*(router: var RestRouter, node: WakuNode) =
|
||||
## /health endpoint provides information about node readiness to caller.
|
||||
## Currently it is restricted to checking RLN (if mounted) proper setup
|
||||
## TODO: Leter to extend it to a broader information about each subsystem state
|
||||
## report. Rest response to change to JSON structure that can hold exact detailed
|
||||
## information.
|
||||
|
||||
router.api(MethodGet, ROUTE_HEALTH) do () -> RestApiResponse:
|
||||
|
||||
let isReadyStateFut = node.isReady()
|
||||
if not await isReadyStateFut.withTimeout(FutIsReadyTimout):
|
||||
return RestApiResponse.internalServerError("Health check timed out")
|
||||
|
||||
var msg = "Node is healthy"
|
||||
var status = Http200
|
||||
|
||||
if not isReadyStateFut.read():
|
||||
msg = "Node is not ready"
|
||||
status = Http503
|
||||
|
||||
return RestApiResponse.textResponse(msg, status)
|
41
waku/node/rest/health/openapi.yaml
Normal file
41
waku/node/rest/health/openapi.yaml
Normal file
@ -0,0 +1,41 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Waku V2 node REST API
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: VAC Team
|
||||
url: https://forum.vac.dev/
|
||||
|
||||
tags:
|
||||
- name: health
|
||||
description: Healt check REST API for WakuV2 node
|
||||
|
||||
paths:
|
||||
/health:
|
||||
get:
|
||||
summary: Get node health status
|
||||
description: Retrieve readiness of a Waku v2 node.
|
||||
operationId: healthcheck
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
'200':
|
||||
description: Waku v2 node is up and running.
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: Node is healty
|
||||
'500':
|
||||
description: Internal server error
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
'503':
|
||||
description: Node not initialized or having issues
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: Node is not initialized
|
Loading…
x
Reference in New Issue
Block a user