05_tenant_hierarchy/
05_tenant_hierarchy.rs1use std::sync::Arc;
13use tokio::sync::RwLock;
14use wami::arn::{TenantPath, WamiArn};
15use wami::context::WamiContext;
16use wami::service::TenantService;
17use wami::store::memory::InMemoryWamiStore;
18
19#[tokio::main]
20async fn main() -> Result<(), Box<dyn std::error::Error>> {
21 println!("=== Tenant Hierarchy ===\n");
22
23 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
24
25 let root_context = WamiContext::builder()
27 .instance_id("123456789012")
28 .tenant_path(TenantPath::single(0)) .caller_arn(
30 WamiArn::builder()
31 .service(wami::arn::Service::Iam)
32 .tenant_path(TenantPath::single(0))
33 .wami_instance("123456789012")
34 .resource("user", "admin")
35 .build()?,
36 )
37 .is_root(true)
38 .build()?;
39
40 let tenant_service = TenantService::new(store.clone());
41
42 println!("Step 1: Creating hierarchical tenant structure...\n");
44
45 println!("Creating root tenant: acme-corp");
47 let root_tenant = tenant_service
48 .create_tenant(
49 &root_context,
50 "acme-corp".to_string(),
51 Some("ACME Corporation".to_string()),
52 None,
53 )
54 .await?;
55 let root_id = root_tenant.id.clone();
56 println!("✓ Created: acme-corp (ID: {})", root_id);
57
58 println!("\nCreating department tenants...");
60 let eng_tenant = tenant_service
61 .create_tenant(
62 &root_context,
63 "engineering".to_string(),
64 Some("Engineering Department".to_string()),
65 Some(root_id.clone()),
66 )
67 .await?;
68 let eng_id = eng_tenant.id.clone();
69 println!("✓ Created: acme-corp/engineering (ID: {})", eng_id);
70
71 let sales_tenant = tenant_service
72 .create_tenant(
73 &root_context,
74 "sales".to_string(),
75 Some("Sales Department".to_string()),
76 Some(root_id.clone()),
77 )
78 .await?;
79 let _sales_id = sales_tenant.id.clone();
80 println!("✓ Created: acme-corp/sales (ID: {})", _sales_id);
81
82 println!("\nCreating team tenants under engineering...");
84 let backend_tenant = tenant_service
85 .create_tenant(
86 &root_context,
87 "backend".to_string(),
88 Some("Backend Team".to_string()),
89 Some(eng_id.clone()),
90 )
91 .await?;
92 let backend_id = backend_tenant.id.clone();
93 println!(
94 "✓ Created: acme-corp/engineering/backend (ID: {})",
95 backend_id
96 );
97
98 let frontend_tenant = tenant_service
99 .create_tenant(
100 &root_context,
101 "frontend".to_string(),
102 Some("Frontend Team".to_string()),
103 Some(eng_id.clone()),
104 )
105 .await?;
106 let _frontend_id = frontend_tenant.id.clone();
107 println!(
108 "✓ Created: acme-corp/engineering/frontend (ID: {})",
109 _frontend_id
110 );
111
112 println!("\n\nStep 2: Querying tenant hierarchy...\n");
114
115 let all_tenants = tenant_service.list_tenants().await?;
117 println!("Total tenants created: {}", all_tenants.len());
118 for tenant in &all_tenants {
119 println!(" - {} (ID: {})", tenant.name, tenant.id);
120 }
121
122 println!("\nAncestors of 'backend' team:");
124 let backend_ancestors = tenant_service.get_ancestors(&backend_id).await?;
125 println!(" Found {} ancestors", backend_ancestors.len());
126 for ancestor in &backend_ancestors {
127 println!(" ← {} ({})", ancestor.name, ancestor.id);
128 }
129
130 println!("\nChildren of 'engineering' department:");
132 let eng_children = tenant_service.list_child_tenants(&eng_id).await?;
133 println!(" Found {} children", eng_children.len());
134 for child in &eng_children {
135 println!(" → {}", child.name);
136 }
137
138 println!("\nAll descendants of 'acme-corp' (recursive):");
140 let root_descendants = tenant_service.get_descendants(&root_id).await?;
141 println!(" Found {} descendants", root_descendants.len());
142 for descendant in &root_descendants {
143 println!(" → {}", descendant);
144 }
145
146 println!("\n\nStep 3: Understanding hierarchy benefits...\n");
148
149 println!("Hierarchy visualization:");
150 println!("acme-corp (root)");
151 println!("├── engineering");
152 println!("│ ├── backend");
153 println!("│ └── frontend");
154 println!("└── sales");
155
156 println!("\n✅ Example completed successfully!");
157 println!("Key takeaways:");
158 println!("- TenantId supports hierarchical structures with .child()");
159 println!("- Ancestors represent the path from tenant to root");
160 println!("- Descendants include all child tenants recursively");
161 println!("- Hierarchies enable organizational modeling and quota inheritance");
162
163 Ok(())
164}