Skip to content

Commit

Permalink
Improved folder structure (#63)
Browse files Browse the repository at this point in the history
* feat: improved folder structure

* fix: specs dependence
  • Loading branch information
paulobressan authored Aug 1, 2024
1 parent 755560c commit 3330aac
Show file tree
Hide file tree
Showing 21 changed files with 1,049 additions and 897 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
51 changes: 51 additions & 0 deletions src/domain/event.rs → src/domain/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,54 @@ impl Event {
pub trait EventDrivenBridge: Send + Sync {
async fn dispatch(&self, event: Event) -> Result<()>;
}

#[cfg(test)]
mod tests {
use uuid::Uuid;

use crate::domain::{
project::ProjectStatus,
tests::{PHC, SECRET},
};

use super::*;

impl Default for ProjectCreated {
fn default() -> Self {
Self {
id: Uuid::new_v4().to_string(),
name: "New Project".into(),
namespace: "sonic-vegas".into(),
owner: "user id".into(),
status: ProjectStatus::Active.to_string(),
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
}
impl Default for ProjectSecretCreated {
fn default() -> Self {
Self {
id: Uuid::new_v4().to_string(),
project_id: Uuid::new_v4().to_string(),
name: "Key 1".into(),
phc: PHC.into(),
secret: SECRET.as_bytes().to_vec(),
created_at: Utc::now(),
}
}
}
impl Default for ResourceCreated {
fn default() -> Self {
Self {
id: Uuid::new_v4().to_string(),
project_id: Uuid::new_v4().to_string(),
project_namespace: "prj-test".into(),
kind: "CardanoNode".into(),
data: "{\"spec\":{\"operatorVersion\":\"1\",\"kupoVersion\":\"v1\",\"network\":\"mainnet\",\"pruneUtxo\":false,\"throughputTier\":\"0\"}}".into(),
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
}
}
9 changes: 9 additions & 0 deletions src/domain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ pub mod resource;

pub const PAGE_SIZE_DEFAULT: u32 = 12;
pub const PAGE_SIZE_MAX: u32 = 120;

#[cfg(test)]
mod tests {
pub const KEY: &str = "dmtr_apikey1g9gyswtcf3zxwd26v4x5jj3jw5wx3sn2";
pub const PHC: &str = "$argon2id$v=19$m=19456,t=2,p=1$xVIt6Wr/bm1FewVhTr6zgA$nTO6EgGeOYZe7thACrHmFUWND40U4GEQCXKyvqzvRvs";
pub const SECRET: &str = "fabric@txpipe";
pub const INVALID_KEY: &str = "dmtr_apikey1xe6xzcjxv9nhycnz2ffnq6m02y7nat9e";
pub const INVALID_HRP_KEY: &str = "dmtr_test18pp5vkjzfuuyzwpeg9gk2a2zvsylc5wg";
}
77 changes: 77 additions & 0 deletions src/domain/project/cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::sync::Arc;

use anyhow::Result;

use crate::domain::event::{ProjectCreated, ProjectSecretCreated};

use super::{Project, ProjectSecret, ProjectUser};

#[async_trait::async_trait]
pub trait ProjectDrivenCache: Send + Sync {
async fn find(&self, user_id: &str, page: &u32, page_size: &u32) -> Result<Vec<Project>>;
async fn find_by_namespace(&self, namespace: &str) -> Result<Option<Project>>;
async fn find_by_id(&self, id: &str) -> Result<Option<Project>>;
async fn create(&self, project: &Project) -> Result<()>;
async fn create_secret(&self, secret: &ProjectSecret) -> Result<()>;
async fn find_secret_by_project_id(&self, project_id: &str) -> Result<Vec<ProjectSecret>>;
async fn find_user_permission(
&self,
user_id: &str,
project_id: &str,
) -> Result<Option<ProjectUser>>;
}

pub async fn create(cache: Arc<dyn ProjectDrivenCache>, evt: ProjectCreated) -> Result<()> {
cache.create(&evt.try_into()?).await
}

pub async fn create_secret(
cache: Arc<dyn ProjectDrivenCache>,
evt: ProjectSecretCreated,
) -> Result<()> {
cache.create_secret(&evt.into()).await
}

#[cfg(test)]
mod tests {
use mockall::mock;

use super::*;

mock! {
pub FakeProjectDrivenCache { }

#[async_trait::async_trait]
impl ProjectDrivenCache for FakeProjectDrivenCache {
async fn find(&self, user_id: &str, page: &u32, page_size: &u32) -> Result<Vec<Project>>;
async fn find_by_namespace(&self, namespace: &str) -> Result<Option<Project>>;
async fn find_by_id(&self, id: &str) -> Result<Option<Project>>;
async fn create(&self, project: &Project) -> Result<()>;
async fn create_secret(&self, secret: &ProjectSecret) -> Result<()>;
async fn find_secret_by_project_id(&self, project_id: &str) -> Result<Vec<ProjectSecret>>;
async fn find_user_permission(&self,user_id: &str, project_id: &str) -> Result<Option<ProjectUser>>;
}
}

#[tokio::test]
async fn it_should_create_project_cache() {
let mut cache = MockFakeProjectDrivenCache::new();
cache.expect_create().return_once(|_| Ok(()));

let evt = ProjectCreated::default();

let result = create(Arc::new(cache), evt).await;
assert!(result.is_ok());
}

#[tokio::test]
async fn it_should_create_project_secret_cache() {
let mut cache = MockFakeProjectDrivenCache::new();
cache.expect_create_secret().return_once(|_| Ok(()));

let evt = ProjectSecretCreated::default();

let result = create_secret(Arc::new(cache), evt).await;
assert!(result.is_ok());
}
}
81 changes: 81 additions & 0 deletions src/domain/project/cluster.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use std::sync::Arc;

use anyhow::{bail, Result};
use k8s_openapi::api::core::v1::Namespace;
use kube::{api::ObjectMeta, ResourceExt};
use tracing::info;

use crate::domain::event::ProjectCreated;

#[async_trait::async_trait]
pub trait ProjectDrivenCluster: Send + Sync {
async fn create(&self, namespace: &Namespace) -> Result<()>;
async fn find_by_name(&self, name: &str) -> Result<Option<Namespace>>;
}

pub async fn apply_manifest(
cluster: Arc<dyn ProjectDrivenCluster>,
evt: ProjectCreated,
) -> Result<()> {
if cluster.find_by_name(&evt.namespace).await?.is_some() {
bail!("namespace alread exist")
}

let namespace = Namespace {
metadata: ObjectMeta {
name: Some(evt.namespace),
..Default::default()
},
..Default::default()
};

cluster.create(&namespace).await?;

//TODO: create event to update cache
info!(namespace = namespace.name_any(), "new namespace created");

Ok(())
}

#[cfg(test)]
mod tests {
use k8s_openapi::api::core::v1::Namespace;
use mockall::mock;

use super::*;

mock! {
pub FakeProjectDrivenCluster { }

#[async_trait::async_trait]
impl ProjectDrivenCluster for FakeProjectDrivenCluster {
async fn create(&self, namespace: &Namespace) -> Result<()>;
async fn find_by_name(&self, name: &str) -> Result<Option<Namespace>>;
}
}

#[tokio::test]
async fn it_should_apply_manifest() {
let mut cluster = MockFakeProjectDrivenCluster::new();
cluster.expect_create().return_once(|_| Ok(()));
cluster.expect_find_by_name().return_once(|_| Ok(None));

let project = ProjectCreated::default();

let result = apply_manifest(Arc::new(cluster), project).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn it_should_fail_apply_manifest_when_resource_exists() {
let mut cluster = MockFakeProjectDrivenCluster::new();
cluster.expect_create().return_once(|_| Ok(()));
cluster
.expect_find_by_name()
.return_once(|_| Ok(Some(Namespace::default())));

let project = ProjectCreated::default();

let result = apply_manifest(Arc::new(cluster), project).await;
assert!(result.is_err());
}
}
Loading

0 comments on commit 3330aac

Please sign in to comment.