Adds endpoint to expose quota information (#652)
This commit is contained in:
parent
e62cb96bde
commit
f1b1fe9152
|
@ -266,7 +266,7 @@ proc new*(
|
||||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
|
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
|
||||||
codexNode = CodexNodeRef.new(switch, store, engine, erasure, discovery)
|
codexNode = CodexNodeRef.new(switch, store, engine, erasure, discovery)
|
||||||
restServer = RestServerRef.new(
|
restServer = RestServerRef.new(
|
||||||
codexNode.initRestApi(config),
|
codexNode.initRestApi(config, repoStore),
|
||||||
initTAddress(config.apiBindAddress , config.apiPort),
|
initTAddress(config.apiBindAddress , config.apiPort),
|
||||||
bufferSize = (1024 * 64),
|
bufferSize = (1024 * 64),
|
||||||
maxRequestBodySize = int.high)
|
maxRequestBodySize = int.high)
|
||||||
|
|
|
@ -34,7 +34,7 @@ import ../conf
|
||||||
import ../contracts
|
import ../contracts
|
||||||
import ../manifest
|
import ../manifest
|
||||||
import ../streams/asyncstreamwrapper
|
import ../streams/asyncstreamwrapper
|
||||||
import ../stores/blockstore
|
import ../stores
|
||||||
|
|
||||||
import ./coders
|
import ./coders
|
||||||
import ./json
|
import ./json
|
||||||
|
@ -106,7 +106,7 @@ proc retrieveCid(
|
||||||
if not stream.isNil:
|
if not stream.isNil:
|
||||||
await stream.close()
|
await stream.close()
|
||||||
|
|
||||||
proc initDataApi(node: CodexNodeRef, router: var RestRouter) =
|
proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRouter) =
|
||||||
router.rawApi(
|
router.rawApi(
|
||||||
MethodPost,
|
MethodPost,
|
||||||
"/api/codex/v1/data") do (
|
"/api/codex/v1/data") do (
|
||||||
|
@ -183,6 +183,17 @@ proc initDataApi(node: CodexNodeRef, router: var RestRouter) =
|
||||||
|
|
||||||
await node.retrieveCid(cid.get(), local = false, resp=resp)
|
await node.retrieveCid(cid.get(), local = false, resp=resp)
|
||||||
|
|
||||||
|
router.api(
|
||||||
|
MethodGet,
|
||||||
|
"/api/codex/v1/space") do () -> RestApiResponse:
|
||||||
|
let json = % RestRepoStore(
|
||||||
|
totalBlocks: repoStore.totalBlocks,
|
||||||
|
quotaMaxBytes: repoStore.quotaMaxBytes,
|
||||||
|
quotaUsedBytes: repoStore.quotaUsedBytes,
|
||||||
|
quotaReservedBytes: repoStore.quotaReservedBytes
|
||||||
|
)
|
||||||
|
return RestApiResponse.response($json, contentType="application/json")
|
||||||
|
|
||||||
proc initSalesApi(node: CodexNodeRef, router: var RestRouter) =
|
proc initSalesApi(node: CodexNodeRef, router: var RestRouter) =
|
||||||
router.api(
|
router.api(
|
||||||
MethodGet,
|
MethodGet,
|
||||||
|
@ -456,10 +467,10 @@ proc initDebugApi(node: CodexNodeRef, conf: CodexConf, router: var RestRouter) =
|
||||||
trace "Excepting processing request", exc = exc.msg
|
trace "Excepting processing request", exc = exc.msg
|
||||||
return RestApiResponse.error(Http500)
|
return RestApiResponse.error(Http500)
|
||||||
|
|
||||||
proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
|
proc initRestApi*(node: CodexNodeRef, conf: CodexConf, repoStore: RepoStore): RestRouter =
|
||||||
var router = RestRouter.init(validate)
|
var router = RestRouter.init(validate)
|
||||||
|
|
||||||
initDataApi(node, router)
|
initDataApi(node, repoStore, router)
|
||||||
initSalesApi(node, router)
|
initSalesApi(node, router)
|
||||||
initPurchasingApi(node, router)
|
initPurchasingApi(node, router)
|
||||||
initDebugApi(node, conf, router)
|
initDebugApi(node, conf, router)
|
||||||
|
|
|
@ -60,6 +60,12 @@ type
|
||||||
RestNodeId* = object
|
RestNodeId* = object
|
||||||
id*: NodeId
|
id*: NodeId
|
||||||
|
|
||||||
|
RestRepoStore* = object
|
||||||
|
totalBlocks* {.serialize.}: uint
|
||||||
|
quotaMaxBytes* {.serialize.}: uint
|
||||||
|
quotaUsedBytes* {.serialize.}: uint
|
||||||
|
quotaReservedBytes* {.serialize.}: uint
|
||||||
|
|
||||||
proc init*(_: type RestContent, cid: Cid, manifest: Manifest): RestContent =
|
proc init*(_: type RestContent, cid: Cid, manifest: Manifest): RestContent =
|
||||||
RestContent(
|
RestContent(
|
||||||
cid: cid,
|
cid: cid,
|
||||||
|
|
35
openapi.yaml
35
openapi.yaml
|
@ -245,6 +245,22 @@ components:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: "Indicates if content is protected by erasure-coding"
|
description: "Indicates if content is protected by erasure-coding"
|
||||||
|
|
||||||
|
Space:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
totalBlocks:
|
||||||
|
type: number
|
||||||
|
description: "Number of blocks stored by the node"
|
||||||
|
quotaMaxBytes:
|
||||||
|
type: number
|
||||||
|
description: "Maximum storage space used by the node"
|
||||||
|
quotaUsedBytes:
|
||||||
|
type: number
|
||||||
|
description: "Amount of storage space currently in use"
|
||||||
|
quotaReservedBytes:
|
||||||
|
type: number
|
||||||
|
description: "Amount of storage space reserved"
|
||||||
|
|
||||||
servers:
|
servers:
|
||||||
- url: "http://localhost:8080/api/codex/v1"
|
- url: "http://localhost:8080/api/codex/v1"
|
||||||
|
|
||||||
|
@ -371,8 +387,7 @@ paths:
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Cid"
|
$ref: "#/components/schemas/Cid"
|
||||||
description: File to be downloaded.
|
description: "File to be downloaded."
|
||||||
|
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Retrieved content specified by CID
|
description: Retrieved content specified by CID
|
||||||
|
@ -388,6 +403,22 @@ paths:
|
||||||
"500":
|
"500":
|
||||||
description: Well it was bad-bad
|
description: Well it was bad-bad
|
||||||
|
|
||||||
|
"/space":
|
||||||
|
get:
|
||||||
|
summary: "Gets a summary of the storage space allocation of the node."
|
||||||
|
tags: [ Data ]
|
||||||
|
operationId: space
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Summary of storage allocation"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Space"
|
||||||
|
|
||||||
|
"500":
|
||||||
|
description: "It's not working as planned"
|
||||||
|
|
||||||
"/sales/slots":
|
"/sales/slots":
|
||||||
get:
|
get:
|
||||||
summary: "Returns active slots"
|
summary: "Returns active slots"
|
||||||
|
|
|
@ -56,6 +56,16 @@ proc list*(client: CodexClient): ?!seq[RestContent] =
|
||||||
let json = ? parseJson(response.body).catch
|
let json = ? parseJson(response.body).catch
|
||||||
seq[RestContent].fromJson(json)
|
seq[RestContent].fromJson(json)
|
||||||
|
|
||||||
|
proc space*(client: CodexClient): ?!RestRepoStore =
|
||||||
|
let url = client.baseurl & "/space"
|
||||||
|
let response = client.http.get(url)
|
||||||
|
|
||||||
|
if response.status != "200 OK":
|
||||||
|
return failure(response.status)
|
||||||
|
|
||||||
|
let json = ? parseJson(response.body).catch
|
||||||
|
RestRepoStore.fromJson(json)
|
||||||
|
|
||||||
proc requestStorageRaw*(
|
proc requestStorageRaw*(
|
||||||
client: CodexClient,
|
client: CodexClient,
|
||||||
cid: Cid,
|
cid: Cid,
|
||||||
|
|
|
@ -44,6 +44,16 @@ twonodessuite "Integration tests", debug1 = false, debug2 = false:
|
||||||
let cid2 = client1.upload("some other contents").get
|
let cid2 = client1.upload("some other contents").get
|
||||||
check cid1 != cid2
|
check cid1 != cid2
|
||||||
|
|
||||||
|
test "node shows used and available space":
|
||||||
|
discard client1.upload("some file contents").get
|
||||||
|
discard client1.postAvailability(size=12.u256, duration=2.u256, minPrice=3.u256, maxCollateral=4.u256).get
|
||||||
|
let space = client1.space().tryGet()
|
||||||
|
check:
|
||||||
|
space.totalBlocks == 2.uint
|
||||||
|
space.quotaMaxBytes == 8589934592.uint
|
||||||
|
space.quotaUsedBytes == 65518.uint
|
||||||
|
space.quotaReservedBytes == 12.uint
|
||||||
|
|
||||||
test "node allows local file downloads":
|
test "node allows local file downloads":
|
||||||
let content1 = "some file contents"
|
let content1 = "some file contents"
|
||||||
let content2 = "some other contents"
|
let content2 = "some other contents"
|
||||||
|
|
Loading…
Reference in New Issue