aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/bruno/configuration/routing/03-update-routing.bru23
-rw-r--r--contrib/bruno/configuration/routing/04-delete-routing.bru23
-rw-r--r--contrib/bruno/configuration/rule/01-create.bru52
-rw-r--r--contrib/bruno/configuration/rule/folder.bru8
-rw-r--r--crates/configuration/src/server/http_svc/routes.rs2
-rw-r--r--lib/warden-core/build.rs12
-rw-r--r--lib/warden-core/src/configuration.rs2
-rw-r--r--lib/warden-core/src/configuration/conv.rs109
8 files changed, 231 insertions, 0 deletions
diff --git a/contrib/bruno/configuration/routing/03-update-routing.bru b/contrib/bruno/configuration/routing/03-update-routing.bru
new file mode 100644
index 0000000..43d3ea4
--- /dev/null
+++ b/contrib/bruno/configuration/routing/03-update-routing.bru
@@ -0,0 +1,23 @@
+meta {
+ name: 03-update-routing
+ type: http
+ seq: 3
+}
+
+put {
+ url: {{WARDEN_CFG_HOST}}/api/{{WARDEN_CFG_VERSION}}/routing/:id
+ body: none
+ auth: inherit
+}
+
+params:path {
+ id:
+}
+
+assert {
+ res.status: eq 201
+}
+
+settings {
+ encodeUrl: true
+}
diff --git a/contrib/bruno/configuration/routing/04-delete-routing.bru b/contrib/bruno/configuration/routing/04-delete-routing.bru
new file mode 100644
index 0000000..b5abaa8
--- /dev/null
+++ b/contrib/bruno/configuration/routing/04-delete-routing.bru
@@ -0,0 +1,23 @@
+meta {
+ name: 04-delete-routing
+ type: http
+ seq: 4
+}
+
+delete {
+ url: {{WARDEN_CFG_HOST}}/api/{{WARDEN_CFG_VERSION}}/routing/:id
+ body: none
+ auth: inherit
+}
+
+params:path {
+ id:
+}
+
+assert {
+ res.status: eq 200
+}
+
+settings {
+ encodeUrl: true
+}
diff --git a/contrib/bruno/configuration/rule/01-create.bru b/contrib/bruno/configuration/rule/01-create.bru
new file mode 100644
index 0000000..cc98aee
--- /dev/null
+++ b/contrib/bruno/configuration/rule/01-create.bru
@@ -0,0 +1,52 @@
+meta {
+ name: 01-create
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{WARDEN_CFG_HOST}}/api/{{WARDEN_CFG_VERSION}}/rule
+ body: json
+ auth: inherit
+}
+
+body:json {
+ {
+ "id": "901",
+ "version": "1.0.0",
+ "description": "Number of outgoing transactions - debtor",
+ "configuration": {
+ "parameters": {
+ "max_query_range": 86400000
+ },
+ "exit_conditions": [
+ {
+ "sub_rule_ref": ".x00",
+ "reason": "Incoming transaction is unsuccessful"
+ }
+ ],
+ "bands": [
+ {
+ "sub_rule_ref": ".01",
+ "upper_limit": 2,
+ "reason": "The debtor has performed one transaction to date"
+ },
+ {
+ "sub_rule_ref": ".02",
+ "lower_limit": 2,
+ "upper_limit": 3,
+ "reason": "The debtor has performed two transactions to date"
+ },
+ {
+ "sub_rule_ref": ".03",
+ "lower_limit": 3,
+ "reason": "The debtor has performed three or more transactions to date"
+ }
+ ]
+ }
+ }
+}
+
+settings {
+ encodeUrl: true
+}
diff --git a/contrib/bruno/configuration/rule/folder.bru b/contrib/bruno/configuration/rule/folder.bru
new file mode 100644
index 0000000..c486c46
--- /dev/null
+++ b/contrib/bruno/configuration/rule/folder.bru
@@ -0,0 +1,8 @@
+meta {
+ name: rule
+ seq: 2
+}
+
+auth {
+ mode: inherit
+}
diff --git a/crates/configuration/src/server/http_svc/routes.rs b/crates/configuration/src/server/http_svc/routes.rs
index 281b231..7663da2 100644
--- a/crates/configuration/src/server/http_svc/routes.rs
+++ b/crates/configuration/src/server/http_svc/routes.rs
@@ -13,6 +13,8 @@ pub fn router(store: AppHandle) -> OpenApiRouter {
routing::post_routing::post_routing,
routing::delete_routing::delete,
routing::replace_routing::replace,
+ ))
+ .routes(routes!(
/* rule */
rule::create::create_rule,
rule::update::update_rule_config,
diff --git a/lib/warden-core/build.rs b/lib/warden-core/build.rs
index c0496d9..abc6e37 100644
--- a/lib/warden-core/build.rs
+++ b/lib/warden-core/build.rs
@@ -121,6 +121,18 @@ fn add_serde(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder {
"#[serde(try_from = \"crate::google::parser::dt::DateItem\")] #[serde(into = \"String\")]",
).type_attribute(".google.type.Date", "#[serde(try_from = \"crate::google::parser::dt::DateItem\")] #[serde(into = \"String\")]");
+ #[cfg(feature = "configuration")]
+ let config = config
+ .field_attribute(".configuration.rule.Config.cases", "#[serde(default)]")
+ .field_attribute(
+ ".configuration.rule.Config.time_frames",
+ "#[serde(default)]",
+ )
+ .type_attribute(
+ ".google.protobuf.Value",
+ "#[serde(try_from = \"serde_json::Value\")] #[serde(into = \"crate::configuration::conv::GenericParameter\")]",
+ );
+
config
}
diff --git a/lib/warden-core/src/configuration.rs b/lib/warden-core/src/configuration.rs
index 798c079..c6b24ce 100644
--- a/lib/warden-core/src/configuration.rs
+++ b/lib/warden-core/src/configuration.rs
@@ -1,3 +1,5 @@
+pub(crate) mod conv;
+
tonic::include_proto!("configuration");
pub mod routing {
diff --git a/lib/warden-core/src/configuration/conv.rs b/lib/warden-core/src/configuration/conv.rs
new file mode 100644
index 0000000..c5c7768
--- /dev/null
+++ b/lib/warden-core/src/configuration/conv.rs
@@ -0,0 +1,109 @@
+use crate::google::protobuf::{ListValue, NullValue, Struct, Value, value};
+
+#[derive(Debug)]
+/// Generic JSON value
+pub struct GenericParameter(pub(crate) serde_json::Value);
+
+impl From<Value> for GenericParameter {
+ fn from(value: Value) -> Self {
+ Self(value.into())
+ }
+}
+
+impl From<value::Kind> for GenericParameter {
+ fn from(value: value::Kind) -> Self {
+ Self(value.into())
+ }
+}
+
+impl TryFrom<serde_json::Value> for value::Kind {
+ type Error = String;
+
+ fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
+ match value {
+ serde_json::Value::Null => Ok(value::Kind::NullValue(NullValue::NullValue as i32)),
+ serde_json::Value::Bool(b) => Ok(value::Kind::BoolValue(b)),
+ serde_json::Value::Number(n) => n
+ .as_f64()
+ .map(value::Kind::NumberValue)
+ .ok_or_else(|| "Invalid number".to_string()),
+ serde_json::Value::String(s) => Ok(value::Kind::StringValue(s)),
+ serde_json::Value::Array(arr) => {
+ let values = arr
+ .into_iter()
+ .map(Value::try_from)
+ .collect::<Result<Vec<_>, _>>()?;
+ Ok(value::Kind::ListValue(ListValue { values }))
+ }
+ serde_json::Value::Object(map) => {
+ let mut fields = std::collections::HashMap::new();
+ for (k, v) in map {
+ let v = Value::try_from(v)?;
+ fields.insert(k, v);
+ }
+ Ok(value::Kind::StructValue(Struct { fields }))
+ }
+ }
+ }
+}
+
+impl TryFrom<serde_json::Value> for Value {
+ type Error = String;
+
+ fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
+ let kind = Some(value::Kind::try_from(value)?);
+ Ok(Value { kind })
+ }
+}
+
+impl From<value::Kind> for serde_json::Value {
+ fn from(kind: value::Kind) -> Self {
+ match kind {
+ value::Kind::NullValue(_) => serde_json::Value::Null,
+ value::Kind::BoolValue(b) => serde_json::Value::Bool(b),
+ value::Kind::NumberValue(n) => serde_json::Value::Number(
+ serde_json::Number::from_f64(n).unwrap_or_else(|| serde_json::Number::from(0)),
+ ),
+ value::Kind::StringValue(s) => serde_json::Value::String(s),
+ value::Kind::StructValue(s) => serde_json::Value::from(s),
+ value::Kind::ListValue(l) => serde_json::Value::from(l),
+ }
+ }
+}
+
+impl From<Value> for serde_json::Value {
+ fn from(value: Value) -> Self {
+ match value.kind {
+ Some(kind) => kind.into(),
+ None => serde_json::Value::Null,
+ }
+ }
+}
+
+impl From<Struct> for serde_json::Value {
+ fn from(s: Struct) -> Self {
+ let map = s
+ .fields
+ .into_iter()
+ .map(|(k, v)| (k, serde_json::Value::from(v)))
+ .collect();
+ serde_json::Value::Object(map)
+ }
+}
+
+impl From<ListValue> for serde_json::Value {
+ fn from(l: ListValue) -> Self {
+ let list = l.values.into_iter().map(serde_json::Value::from).collect();
+ serde_json::Value::Array(list)
+ }
+}
+
+impl serde::Serialize for GenericParameter {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ let json = serde_json::Value::from(self.0.clone());
+ json.serialize(serializer)
+ }
+}