summaryrefslogtreecommitdiff
path: root/common/rust/src
diff options
context:
space:
mode:
Diffstat (limited to 'common/rust/src')
-rw-r--r--common/rust/src/config.rs27
-rw-r--r--common/rust/src/error.rs8
-rw-r--r--common/rust/src/lib.rs15
-rw-r--r--common/rust/src/monitoring.rs35
-rw-r--r--common/rust/src/nats.rs35
-rw-r--r--common/rust/src/payloads.rs21
-rw-r--r--common/rust/src/redis.rs15
7 files changed, 105 insertions, 51 deletions
diff --git a/common/rust/src/config.rs b/common/rust/src/config.rs
index c158a21..e4dbade 100644
--- a/common/rust/src/config.rs
+++ b/common/rust/src/config.rs
@@ -1,10 +1,12 @@
use std::env;
-
use config::{Config, ConfigError, Environment, File};
use log::info;
-use serde::{Deserialize};
-
+use serde::Deserialize;
+/// Settings<T> is the base structure for all the nova's component config
+/// you can specify a type T and the name of the component. the "config"
+/// field will be equals to the key named after the given component name
+/// and will be of type T
#[derive(Debug, Deserialize, Clone)]
#[serde(bound(deserialize = "T: Deserialize<'de> + std::default::Default + Clone"))]
pub struct Settings<T> {
@@ -12,10 +14,19 @@ pub struct Settings<T> {
pub config: T,
pub monitoring: crate::monitoring::MonitoringConfiguration,
pub nats: crate::nats::NatsConfiguration,
+ pub redis: crate::redis::RedisConfiguration,
}
-impl<T> Settings<T> where T: Deserialize<'static> + std::default::Default + Clone {
+///
+impl<T> Settings<T>
+where
+ T: Deserialize<'static> + std::default::Default + Clone,
+{
+ /// Initializes a new configuration like the other components of nova
+ /// And starts the prometheus metrics server if needed.
pub fn new(service_name: &str) -> Result<Settings<T>, ConfigError> {
+ pretty_env_logger::init();
+
let mut default = Config::default();
// this file my be shared with all the components
default.merge(File::with_name("config/default"))?;
@@ -25,16 +36,20 @@ impl<T> Settings<T> where T: Deserialize<'static> + std::default::Default + Clon
default.merge(File::with_name(&format!("config/{}", mode)).required(false))?;
default.merge(File::with_name("config/local").required(false))?;
+ let env = Environment::with_prefix("NOVA").separator("__");
// we can configure each component using environment variables
- default.merge(Environment::with_prefix("NOVA").separator("_"))?;
+ default.merge(env)?;
let mut config: Settings<T> = default.clone().try_into().unwrap();
// try to load the config
config.config = default.get::<T>(&service_name).unwrap();
- pretty_env_logger::init();
// start the monitoring system if needed
crate::monitoring::start_monitoring(&config.monitoring);
Ok(config)
}
}
+
+pub fn test_init() {
+ pretty_env_logger::init();
+}
diff --git a/common/rust/src/error.rs b/common/rust/src/error.rs
index b602940..1a24657 100644
--- a/common/rust/src/error.rs
+++ b/common/rust/src/error.rs
@@ -7,6 +7,12 @@ pub struct NovaError {
impl fmt::Display for NovaError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "An error occured wihind the nova system: {}", self.message) // user-facing output
+ write!(f, "An error occurred within the nova system: {}", self.message) // user-facing output
}
}
+
+impl From<&str> for NovaError {
+ fn from(message: &str) -> Self {
+ NovaError { message: message.to_string() }
+ }
+} \ No newline at end of file
diff --git a/common/rust/src/lib.rs b/common/rust/src/lib.rs
index 943d7cc..f4e27fc 100644
--- a/common/rust/src/lib.rs
+++ b/common/rust/src/lib.rs
@@ -1,7 +1,16 @@
-/// This crate contains shared code in all the rust projects
-/// It contains utilities such as monitoring, logging and more.
+/// This crate is all the utilities shared by the nova rust projects
+/// It includes loging, config and protocols.
pub mod config;
pub mod monitoring;
pub mod nats;
pub mod payloads;
-pub mod error; \ No newline at end of file
+pub mod error;
+pub mod redis;
+
+pub use log as log;
+pub use serde as serde;
+pub use ::config as config_crate;
+pub use prometheus as prometheus;
+pub use ::nats as nats_crate;
+pub use testcontainers as testcontainers;
+pub use ::redis as redis_crate; \ No newline at end of file
diff --git a/common/rust/src/monitoring.rs b/common/rust/src/monitoring.rs
index ded1d95..4bff043 100644
--- a/common/rust/src/monitoring.rs
+++ b/common/rust/src/monitoring.rs
@@ -1,19 +1,19 @@
use hyper::{
- Response, Body, Request, Server,
- header::{CONTENT_TYPE},
+ header::CONTENT_TYPE,
service::{make_service_fn, service_fn},
+ Body, Request, Response, Server,
};
-use std::net::ToSocketAddrs;
+use log::{error, info};
use prometheus::{Encoder, TextEncoder};
-use log::{info,error};
use serde::Deserialize;
+use std::net::ToSocketAddrs;
#[derive(Clone, Debug, Deserialize)]
/// Options for the monitoring service
pub struct MonitoringConfiguration {
- enabled: bool,
- address: Option<String>,
- port: Option<i32>,
+ pub enabled: bool,
+ pub address: Option<String>,
+ pub port: Option<i32>,
}
/// Handler for the hyper http server
@@ -37,17 +37,18 @@ pub fn start_monitoring(configuration: &MonitoringConfiguration) {
let config = configuration.clone();
tokio::task::spawn(async move {
if config.enabled {
- let address = format!("{}:{}",
- config.address.expect("a listening address must be specified for the metrics server"),
- config.port.expect("a listening port must be specified for the metrics server")
+ let address = format!(
+ "{}:{}",
+ config
+ .address
+ .expect("a listening address must be specified for the metrics server"),
+ config
+ .port
+ .expect("a listening port must be specified for the metrics server")
);
info!("Starting monitoring server on {}", address);
-
- let listen_address = address
- .to_socket_addrs()
- .unwrap()
- .next()
- .unwrap();
+
+ let listen_address = address.to_socket_addrs().unwrap().next().unwrap();
let server = Server::bind(&listen_address).serve(make_service_fn(|_| async {
Ok::<_, hyper::Error>(service_fn(serve_metrics))
}));
@@ -57,4 +58,4 @@ pub fn start_monitoring(configuration: &MonitoringConfiguration) {
}
}
});
-} \ No newline at end of file
+}
diff --git a/common/rust/src/nats.rs b/common/rust/src/nats.rs
index 59b480c..c61aa4c 100644
--- a/common/rust/src/nats.rs
+++ b/common/rust/src/nats.rs
@@ -1,34 +1,34 @@
-use nats::{Options, Connection};
+use nats::{Connection, Options};
use serde::Deserialize;
#[derive(Clone, Debug, Deserialize)]
-struct NatsConfigurationClientCert {
- cert: String,
- key: String
+pub struct NatsConfigurationClientCert {
+ pub cert: String,
+ pub key: String,
}
#[derive(Clone, Debug, Deserialize)]
-struct NatsConfigurationTls {
- mtu: Option<usize>,
+pub struct NatsConfigurationTls {
+ pub mtu: Option<usize>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct NatsConfiguration {
- client_cert: Option<NatsConfigurationClientCert>,
- root_cert: Option<Vec<String>>,
- jetstream_api_prefix: Option<String>,
- max_reconnects: Option<usize>,
- reconnect_buffer_size: Option<usize>,
- tls: Option<NatsConfigurationTls>,
- client_name: Option<String>,
- tls_required: Option<bool>,
- host: String,
+ pub client_cert: Option<NatsConfigurationClientCert>,
+ pub root_cert: Option<Vec<String>>,
+ pub jetstream_api_prefix: Option<String>,
+ pub max_reconnects: Option<usize>,
+ pub reconnect_buffer_size: Option<usize>,
+ pub tls: Option<NatsConfigurationTls>,
+ pub client_name: Option<String>,
+ pub tls_required: Option<bool>,
+ pub host: String,
}
-///
+// Allows the configuration to directly create a nats connection
impl Into<Connection> for NatsConfiguration {
fn into(self) -> Connection {
let mut options = Options::new();
-
+
if let Some(client_cert) = self.client_cert {
options = options.client_cert(client_cert.cert, client_cert.key);
}
@@ -49,7 +49,6 @@ impl Into<Connection> for NatsConfiguration {
options = options.tls_required(self.tls_required.unwrap_or(false));
options = options.with_name(&self.client_name.unwrap_or("Nova".to_string()));
-
if let Some(tls) = self.tls {
let mut config = nats::rustls::ClientConfig::new();
config.set_mtu(&tls.mtu);
diff --git a/common/rust/src/payloads.rs b/common/rust/src/payloads.rs
index 6eb35c8..c97ac1d 100644
--- a/common/rust/src/payloads.rs
+++ b/common/rust/src/payloads.rs
@@ -1,15 +1,24 @@
use serde::{Deserialize, Serialize};
+use std::fmt::Debug;
-/// Payload send to the nova cache queues
-#[derive(Serialize, Deserialize, Debug, Clone)]
-#[serde(bound(deserialize = "T: Deserialize<'de> + std::default::Default + Clone"))]
+/// Data structure sent to the cache component
+/// by the gateway & webhook.
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(bound(deserialize = "T: Deserialize<'de> + Debug"))]
pub struct CachePayload<T> {
+
+ #[serde(rename = "tr")]
pub tracing: Tracing,
- pub data: T
+
+ #[serde(rename = "d")]
+ pub data: T,
+
+ #[serde(rename = "o")]
+ pub operation: String,
}
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Serialize, Deserialize, Debug)]
pub struct Tracing {
pub node_id: String,
pub span: Option<String>
-} \ No newline at end of file
+}
diff --git a/common/rust/src/redis.rs b/common/rust/src/redis.rs
new file mode 100644
index 0000000..a196f8d
--- /dev/null
+++ b/common/rust/src/redis.rs
@@ -0,0 +1,15 @@
+use redis::Client;
+use serde::Deserialize;
+
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct RedisConfiguration {
+ pub url: String,
+}
+
+// Allows the configuration to directly create a nats connection
+impl Into<Client> for RedisConfiguration {
+ fn into(self) -> Client {
+ redis::Client::open(self.url).unwrap()
+ }
+}