Skip to main content

veilid_remote_api/
lib.rs

1//! # veilid-remote-api
2//!
3//! This crate provides the ability to control a Veilid node remotely.
4//!
5//! The [JsonRequestProcessor] is a wrapper around the [VeilidAPI] and provides a way to process requests and send responses.
6
7use veilid_core::tools::*;
8use veilid_core::*;
9
10use parking_lot::Mutex;
11use schemars::{schema_for, JsonSchema};
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14use std::fmt;
15use tracing::*;
16
17mod routing_context;
18pub use routing_context::*;
19
20mod table_db;
21pub use table_db::*;
22
23mod crypto_system;
24pub use crypto_system::*;
25
26mod dht_transaction;
27pub use dht_transaction::*;
28
29mod process;
30pub use process::*;
31
32#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
33pub struct Request {
34    /// Operation Id (pairs with Response, or empty if unidirectional).
35    #[serde(default)]
36    pub id: u32,
37    /// The request operation variant.
38    #[serde(flatten)]
39    pub op: RequestOp,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43#[serde(tag = "type")]
44pub enum RecvMessage {
45    Response(Response),
46    Update(VeilidUpdate),
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
50pub struct Response {
51    /// Operation Id (pairs with Request, or empty if unidirectional).
52    #[serde(default)]
53    pub id: u32,
54    /// The response operation variant.
55    #[serde(flatten)]
56    pub op: ResponseOp,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
60#[serde(tag = "op")]
61pub enum RequestOp {
62    Control {
63        args: Vec<String>,
64    },
65    GetState,
66    IsShutdown,
67    Attach,
68    Detach,
69    GenerateMemberId {
70        #[schemars(with = "String")]
71        writer_key: PublicKey,
72    },
73    GetDhtRecordKey {
74        schema: DHTSchema,
75        #[schemars(with = "String")]
76        owner: PublicKey,
77        #[schemars(with = "Option<String>")]
78        encryption_key: Option<SharedSecret>,
79    },
80    NewPrivateRoute,
81    NewCustomPrivateRoute {
82        #[serde(default)]
83        private_spec: PrivateSpec,
84    },
85    ImportRemotePrivateRoute {
86        #[serde(with = "as_human_base64")]
87        #[schemars(with = "String")]
88        blob: Vec<u8>,
89    },
90    ReleasePrivateRoute {
91        #[schemars(with = "String")]
92        route_id: RouteId,
93    },
94    AppCallReply {
95        #[schemars(with = "String")]
96        call_id: OperationId,
97        #[serde(with = "as_human_base64")]
98        #[schemars(with = "String")]
99        message: Vec<u8>,
100    },
101    // Routing Context
102    NewRoutingContext,
103    RoutingContext(RoutingContextRequest),
104    // DHT Transaction
105    TransactDhtRecords {
106        #[schemars(with = "Vec<String>")]
107        record_keys: Vec<RecordKey>,
108        options: Option<TransactDHTRecordsOptions>,
109    },
110    DhtTransaction(DhtTransactionRequest),
111    // TableDb
112    OpenTableDb {
113        name: String,
114        column_count: u32,
115    },
116    DeleteTableDb {
117        name: String,
118    },
119    TableDb(TableDbRequest),
120    TableDbTransaction(TableDbTransactionRequest),
121    // Crypto
122    GetCryptoSystem {
123        #[schemars(with = "String")]
124        kind: CryptoKind,
125    },
126    CryptoSystem(CryptoSystemRequest),
127    VerifySignatures {
128        #[schemars(with = "Vec<String>")]
129        node_ids: Vec<PublicKey>,
130        #[serde(with = "as_human_base64")]
131        #[schemars(with = "String")]
132        data: Vec<u8>,
133        #[schemars(with = "Vec<String>")]
134        signatures: Vec<Signature>,
135    },
136    GenerateSignatures {
137        #[serde(with = "as_human_base64")]
138        #[schemars(with = "String")]
139        data: Vec<u8>,
140        #[schemars(with = "Vec<String>")]
141        key_pairs: Vec<KeyPair>,
142    },
143    GenerateKeyPair {
144        #[schemars(with = "String")]
145        kind: CryptoKind,
146    },
147    // Misc
148    Now,
149    Debug {
150        command: String,
151    },
152    VeilidVersionString,
153    VeilidVersion,
154    VeilidFeatures,
155    DefaultVeilidConfig,
156    ValidCryptoKinds,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
160#[serde(tag = "op")]
161pub enum ResponseOp {
162    Control {
163        #[serde(flatten)]
164        result: ApiResult<String>,
165    },
166    GetState {
167        #[serde(flatten)]
168        result: ApiResult<Box<VeilidState>>,
169    },
170    IsShutdown {
171        value: bool,
172    },
173    Attach {
174        #[serde(flatten)]
175        result: ApiResult<()>,
176    },
177    Detach {
178        #[serde(flatten)]
179        result: ApiResult<()>,
180    },
181    GenerateMemberId {
182        #[serde(flatten)]
183        #[schemars(with = "ApiResult<String>")]
184        result: ApiResultWithString<MemberId>,
185    },
186    GetDhtRecordKey {
187        #[serde(flatten)]
188        #[schemars(with = "ApiResult<String>")]
189        result: ApiResultWithString<RecordKey>,
190    },
191    NewPrivateRoute {
192        #[serde(flatten)]
193        result: ApiResult<RouteBlob>,
194    },
195    NewCustomPrivateRoute {
196        #[serde(flatten)]
197        result: ApiResult<RouteBlob>,
198    },
199    ImportRemotePrivateRoute {
200        #[serde(flatten)]
201        #[schemars(with = "ApiResult<String>")]
202        result: ApiResultWithString<RouteId>,
203    },
204    ReleasePrivateRoute {
205        #[serde(flatten)]
206        result: ApiResult<()>,
207    },
208    AppCallReply {
209        #[serde(flatten)]
210        result: ApiResult<()>,
211    },
212    // Routing Context
213    NewRoutingContext {
214        #[serde(flatten)]
215        result: ApiResult<u32>,
216    },
217    RoutingContext(Box<RoutingContextResponse>),
218    // DHT Transaction
219    TransactDhtRecords {
220        #[serde(flatten)]
221        result: ApiResult<u32>,
222    },
223    DhtTransaction(Box<DhtTransactionResponse>),
224    // TableDb
225    OpenTableDb {
226        #[serde(flatten)]
227        result: ApiResult<u32>,
228    },
229    DeleteTableDb {
230        #[serde(flatten)]
231        result: ApiResult<bool>,
232    },
233    TableDb(TableDbResponse),
234    TableDbTransaction(TableDbTransactionResponse),
235    // Crypto
236    GetCryptoSystem {
237        #[serde(flatten)]
238        result: ApiResult<u32>,
239    },
240    BestCryptoSystem {
241        #[serde(flatten)]
242        result: ApiResult<u32>,
243    },
244    CryptoSystem(CryptoSystemResponse),
245    VerifySignatures {
246        #[serde(flatten)]
247        #[schemars(with = "ApiResult<Option<Vec<String>>>")]
248        result: ApiResultWithOptVecString<Option<PublicKeyGroup>>,
249    },
250    GenerateSignatures {
251        #[serde(flatten)]
252        #[schemars(with = "ApiResult<Vec<String>>")]
253        result: ApiResultWithVecString<Vec<Signature>>,
254    },
255    GenerateKeyPair {
256        #[serde(flatten)]
257        #[schemars(with = "ApiResult<String>")]
258        result: ApiResultWithString<KeyPair>,
259    },
260    // Misc
261    Now {
262        #[schemars(with = "String")]
263        value: Timestamp,
264    },
265    Debug {
266        #[serde(flatten)]
267        result: ApiResult<String>,
268    },
269    VeilidVersionString {
270        value: String,
271    },
272    VeilidVersion {
273        major: u32,
274        minor: u32,
275        patch: u32,
276    },
277    DefaultVeilidConfig {
278        value: String,
279    },
280    VeilidFeatures {
281        value: Vec<String>,
282    },
283    ValidCryptoKinds {
284        #[schemars(with = "Vec<String>")]
285        value: Vec<CryptoKind>,
286    },
287}
288
289#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
290#[serde(untagged)]
291pub enum ApiResult<T>
292where
293    T: Clone + fmt::Debug + JsonSchema,
294{
295    Ok { value: T },
296    Err { error: VeilidAPIError },
297}
298
299#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
300#[serde(untagged)]
301pub enum ApiResultWithString<T>
302where
303    T: Clone + fmt::Debug,
304{
305    Ok {
306        #[schemars(with = "String")]
307        value: T,
308    },
309    Err {
310        error: VeilidAPIError,
311    },
312}
313
314#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
315#[serde(untagged)]
316pub enum ApiResultWithVecU8 {
317    Ok {
318        #[serde(with = "as_human_base64")]
319        #[schemars(with = "String")]
320        value: Vec<u8>,
321    },
322    Err {
323        error: VeilidAPIError,
324    },
325}
326#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
327#[serde(transparent)]
328pub struct VecU8 {
329    #[serde(with = "as_human_base64")]
330    #[schemars(with = "String")]
331    value: Vec<u8>,
332}
333
334#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
335#[serde(untagged)]
336pub enum ApiResultWithVecVecU8 {
337    Ok {
338        #[schemars(with = "Vec<String>")]
339        value: Vec<VecU8>,
340    },
341    Err {
342        error: VeilidAPIError,
343    },
344}
345
346#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
347#[serde(untagged)]
348pub enum ApiResultWithVecString<T>
349where
350    T: Clone + fmt::Debug,
351{
352    Ok {
353        #[schemars(with = "Vec<String>")]
354        value: T,
355    },
356    Err {
357        error: VeilidAPIError,
358    },
359}
360
361#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
362#[serde(untagged)]
363pub enum ApiResultWithOptVecString<T>
364where
365    T: Clone + fmt::Debug,
366{
367    Ok {
368        #[schemars(with = "Option<Vec<String>>")]
369        value: T,
370    },
371    Err {
372        error: VeilidAPIError,
373    },
374}
375
376pub fn emit_schemas(out: &mut HashMap<String, String>) {
377    let schema_request = schema_for!(Request);
378    let schema_recv_message = schema_for!(RecvMessage);
379
380    out.insert(
381        "Request".to_owned(),
382        serde_json::to_string_pretty(&schema_request).unwrap_or_log(),
383    );
384
385    out.insert(
386        "RecvMessage".to_owned(),
387        serde_json::to_string_pretty(&schema_recv_message).unwrap_or_log(),
388    );
389}