aboutsummaryrefslogtreecommitdiffstats
path: root/crates/configuration/src/state/typology/mutate_typology.rs
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-08-16 10:08:51 +0200
committerrtkay123 <dev@kanjala.com>2025-08-16 10:08:51 +0200
commiteb59714648bbba66e77955c8bda1c99caf1cede6 (patch)
tree5c194cd5e132c172e4cb510cc35bb46594f86f02 /crates/configuration/src/state/typology/mutate_typology.rs
parent698633baa2505ffb60cb5bba588f8b360c767edd (diff)
downloadwarden-eb59714648bbba66e77955c8bda1c99caf1cede6.tar.bz2
warden-eb59714648bbba66e77955c8bda1c99caf1cede6.zip
feat(config): typologies
Diffstat (limited to 'crates/configuration/src/state/typology/mutate_typology.rs')
-rw-r--r--crates/configuration/src/state/typology/mutate_typology.rs170
1 files changed, 170 insertions, 0 deletions
diff --git a/crates/configuration/src/state/typology/mutate_typology.rs b/crates/configuration/src/state/typology/mutate_typology.rs
new file mode 100644
index 0000000..f2ab2cc
--- /dev/null
+++ b/crates/configuration/src/state/typology/mutate_typology.rs
@@ -0,0 +1,170 @@
+use opentelemetry_semantic_conventions::attribute;
+use tonic::{Request, Response, Status, async_trait};
+use tracing::{Instrument, error, info_span};
+use tracing_opentelemetry::OpenTelemetrySpanExt;
+use uuid::Uuid;
+use warden_core::configuration::{
+ ConfigKind, ReloadEvent,
+ typology::{
+ DeleteTypologyConfigurationRequest, TypologyConfiguration, UpdateTypologyConfigRequest,
+ mutate_typologies_server::MutateTypologies,
+ },
+};
+
+use crate::state::{
+ AppHandle, cache_key::CacheKey, invalidate_cache, publish_reload, typology::TypologyRow,
+};
+
+#[async_trait]
+impl MutateTypologies for AppHandle {
+ async fn create_typology_configuration(
+ &self,
+ request: Request<TypologyConfiguration>,
+ ) -> Result<Response<TypologyConfiguration>, Status> {
+ let request = request.into_inner();
+ let span = info_span!("create.configuration.typology");
+ span.set_attribute(attribute::DB_SYSTEM_NAME, "postgres");
+ span.set_attribute(attribute::DB_OPERATION_NAME, "insert");
+ span.set_attribute(attribute::DB_COLLECTION_NAME, "typology");
+ span.set_attribute("otel.kind", "client");
+
+ sqlx::query!(
+ "insert into typology (uuid, configuration) values ($1, $2)",
+ Uuid::now_v7(),
+ sqlx::types::Json(&request) as _,
+ )
+ .execute(&self.services.postgres)
+ .instrument(span)
+ .await
+ .map_err(|e| {
+ error!("{e}");
+ tonic::Status::internal(e.to_string())
+ })?;
+
+ Ok(tonic::Response::new(request))
+ }
+
+ async fn update_typology_configuration(
+ &self,
+ request: Request<UpdateTypologyConfigRequest>,
+ ) -> Result<Response<TypologyConfiguration>, Status> {
+ let conf = self
+ .app_config
+ .nats
+ .subject
+ .split(".")
+ .next()
+ .expect("bad config");
+
+ let request = request.into_inner();
+
+ let config = request.configuration.expect("configuration to be provided");
+
+ let span = info_span!("update.configuration.typology");
+ span.set_attribute(attribute::DB_SYSTEM_NAME, "postgres");
+ span.set_attribute(attribute::DB_OPERATION_NAME, "update");
+ span.set_attribute(attribute::DB_COLLECTION_NAME, "typology");
+ span.set_attribute("otel.kind", "client");
+
+ sqlx::query!(
+ r#"
+ update typology
+ set configuration = $1
+ where id = $2 and version = $3
+ "#,
+ sqlx::types::Json(&config) as _,
+ config.id,
+ config.version,
+ )
+ .execute(&self.services.postgres)
+ .instrument(span)
+ .await
+ .map_err(|e| {
+ error!("{e}");
+ tonic::Status::internal(e.to_string())
+ })?;
+
+ let (_del_result, _publish_result) = tokio::try_join!(
+ invalidate_cache(
+ self,
+ CacheKey::Typology {
+ id: &config.id,
+ version: &config.version,
+ }
+ ),
+ publish_reload(
+ self,
+ conf,
+ ReloadEvent {
+ kind: ConfigKind::Typology.into(),
+ id: Some(config.id.to_owned()),
+ version: Some(config.version.to_owned()),
+ }
+ )
+ )?;
+
+ Ok(Response::new(config))
+ }
+
+ async fn delete_typology_configuration(
+ &self,
+ request: Request<DeleteTypologyConfigurationRequest>,
+ ) -> Result<Response<TypologyConfiguration>, Status> {
+ let conf = self
+ .app_config
+ .nats
+ .subject
+ .split(".")
+ .next()
+ .expect("bad config");
+
+ let request = request.into_inner();
+
+ let span = info_span!("delete.configuration.typology");
+ span.set_attribute(attribute::DB_SYSTEM_NAME, "postgres");
+ span.set_attribute(attribute::DB_OPERATION_NAME, "delete");
+ span.set_attribute(attribute::DB_COLLECTION_NAME, "typology");
+ span.set_attribute("otel.kind", "client");
+
+ let updated = sqlx::query_as!(
+ TypologyRow,
+ r#"
+ delete from typology
+ where id = $1 and version = $2
+ returning configuration as "configuration: sqlx::types::Json<TypologyConfiguration>"
+ "#,
+ request.id,
+ request.version,
+ )
+ .fetch_one(&self.services.postgres)
+ .instrument(span)
+ .await
+ .map_err(|e| {
+ error!("{e}");
+ tonic::Status::internal(e.to_string())
+ })?;
+
+ let (_del_result, _publish_result) = tokio::try_join!(
+ invalidate_cache(
+ self,
+ CacheKey::Typology {
+ id: &request.id,
+ version: &request.version,
+ }
+ ),
+ publish_reload(
+ self,
+ conf,
+ ReloadEvent {
+ kind: ConfigKind::Typology.into(),
+ id: Some(request.id.to_owned()),
+ version: Some(request.version.to_owned()),
+ }
+ )
+ )?;
+
+ let res = updated.configuration.0;
+
+ Ok(Response::new(res))
+ }
+}