302 lines
12 KiB
Rust
302 lines
12 KiB
Rust
use heromodels::db::{Collection, Db};
|
|
use heromodels::models::grid4::{Contract, ContractStatus};
|
|
use heromodels::models::grid4::contract::contract_index::customer_id;
|
|
use heromodels_core::Model;
|
|
|
|
// Helper function to print contract details
|
|
fn print_contract_details(contract: &Contract) {
|
|
println!("\n--- Contract Details ---");
|
|
println!("ID: {}", contract.get_id());
|
|
println!("Customer ID: {}", contract.customer_id);
|
|
println!("Compute Slices: {}", contract.compute_slices.len());
|
|
println!("Storage Slices: {}", contract.storage_slices.len());
|
|
println!("Compute Slice Price: ${:.2}", contract.compute_slice_price);
|
|
println!("Storage Slice Price: ${:.2}", contract.storage_slice_price);
|
|
println!("Network Slice Price: ${:.2}", contract.network_slice_price);
|
|
println!("Status: {:?}", contract.status);
|
|
println!("Start Date: {}", contract.start_date);
|
|
println!("End Date: {}", contract.end_date);
|
|
println!("Billing Period: {:?}", contract.billing_period);
|
|
println!("Signature User: {}", contract.signature_user);
|
|
println!("Signature Hoster: {}", contract.signature_hoster);
|
|
println!("Created At: {}", contract.base_data.created_at);
|
|
println!("Modified At: {}", contract.base_data.modified_at);
|
|
|
|
// Print compute slices details
|
|
if !contract.compute_slices.is_empty() {
|
|
println!(" Compute Slices:");
|
|
for (i, slice) in contract.compute_slices.iter().enumerate() {
|
|
println!(" {}. Node: {}, ID: {}, Memory: {:.1}GB, Storage: {:.1}GB, Passmark: {}, vCores: {}",
|
|
i + 1, slice.node_id, slice.id, slice.mem_gb, slice.storage_gb, slice.passmark, slice.vcores);
|
|
}
|
|
}
|
|
|
|
// Print storage slices details
|
|
if !contract.storage_slices.is_empty() {
|
|
println!(" Storage Slices:");
|
|
for (i, slice) in contract.storage_slices.iter().enumerate() {
|
|
println!(" {}. Node: {}, ID: {}, Size: {}GB",
|
|
i + 1, slice.node_id, slice.id, slice.storage_size_gb);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// Create a new DB instance in /tmp/grid4_contracts_db, and reset before every run
|
|
let db = heromodels::db::hero::OurDB::new("/tmp/grid4_contracts_db", true).expect("Can create DB");
|
|
|
|
println!("Grid4 Contract Models - Basic Usage Example");
|
|
println!("==========================================");
|
|
|
|
// Create compute slices for contracts
|
|
let compute_slice1 = ComputeSliceProvisioned::new()
|
|
.node_id(1001)
|
|
.id(1)
|
|
.mem_gb(2.0)
|
|
.storage_gb(20.0)
|
|
.passmark(2500)
|
|
.vcores(2)
|
|
.cpu_oversubscription(150)
|
|
.tags("web-server,production".to_string());
|
|
|
|
let compute_slice2 = ComputeSliceProvisioned::new()
|
|
.node_id(1002)
|
|
.id(2)
|
|
.mem_gb(4.0)
|
|
.storage_gb(40.0)
|
|
.passmark(5000)
|
|
.vcores(4)
|
|
.cpu_oversubscription(120)
|
|
.tags("database,high-performance".to_string());
|
|
|
|
let compute_slice3 = ComputeSliceProvisioned::new()
|
|
.node_id(1003)
|
|
.id(1)
|
|
.mem_gb(8.0)
|
|
.storage_gb(80.0)
|
|
.passmark(10000)
|
|
.vcores(8)
|
|
.cpu_oversubscription(100)
|
|
.tags("ml-training,gpu-enabled".to_string());
|
|
|
|
// Create storage slices for contracts
|
|
let storage_slice1 = StorageSliceProvisioned::new()
|
|
.node_id(2001)
|
|
.id(1)
|
|
.storage_size_gb(100)
|
|
.tags("backup,cold-storage".to_string());
|
|
|
|
let storage_slice2 = StorageSliceProvisioned::new()
|
|
.node_id(2002)
|
|
.id(2)
|
|
.storage_size_gb(500)
|
|
.tags("data-lake,analytics".to_string());
|
|
|
|
let storage_slice3 = StorageSliceProvisioned::new()
|
|
.node_id(2003)
|
|
.id(1)
|
|
.storage_size_gb(1000)
|
|
.tags("archive,long-term".to_string());
|
|
|
|
// Create contracts with different configurations
|
|
|
|
// Contract 1 - Small web hosting contract
|
|
let contract1 = Contract::new()
|
|
.customer_id(201)
|
|
.add_compute_slice(compute_slice1.clone())
|
|
.add_storage_slice(storage_slice1.clone())
|
|
.compute_slice_price(0.05)
|
|
.storage_slice_price(0.02)
|
|
.network_slice_price(0.01)
|
|
.status(ContractStatus::Active)
|
|
.start_date(1640995200) // 2022-01-01
|
|
.end_date(1672531200) // 2023-01-01
|
|
.billing_period(BillingPeriod::Monthly)
|
|
.signature_user("contract_user_201_abc123".to_string())
|
|
.signature_hoster("hoster_node1001_xyz789".to_string());
|
|
|
|
// Contract 2 - Database hosting contract
|
|
let contract2 = Contract::new()
|
|
.customer_id(202)
|
|
.add_compute_slice(compute_slice2.clone())
|
|
.add_storage_slice(storage_slice2.clone())
|
|
.compute_slice_price(0.04)
|
|
.storage_slice_price(0.015)
|
|
.network_slice_price(0.008)
|
|
.status(ContractStatus::Active)
|
|
.start_date(1640995200)
|
|
.end_date(1704067200) // 2024-01-01
|
|
.billing_period(BillingPeriod::Yearly)
|
|
.signature_user("contract_user_202_def456".to_string())
|
|
.signature_hoster("hoster_node1002_uvw123".to_string());
|
|
|
|
// Contract 3 - ML training contract (paused)
|
|
let contract3 = Contract::new()
|
|
.customer_id(203)
|
|
.add_compute_slice(compute_slice3.clone())
|
|
.add_storage_slice(storage_slice3.clone())
|
|
.compute_slice_price(0.08)
|
|
.storage_slice_price(0.01)
|
|
.network_slice_price(0.015)
|
|
.status(ContractStatus::Paused)
|
|
.start_date(1640995200)
|
|
.end_date(1672531200)
|
|
.billing_period(BillingPeriod::Hourly)
|
|
.signature_user("contract_user_203_ghi789".to_string())
|
|
.signature_hoster("hoster_node1003_rst456".to_string());
|
|
|
|
// Contract 4 - Multi-slice enterprise contract
|
|
let contract4 = Contract::new()
|
|
.customer_id(204)
|
|
.add_compute_slice(compute_slice1.clone())
|
|
.add_compute_slice(compute_slice2.clone())
|
|
.add_storage_slice(storage_slice1.clone())
|
|
.add_storage_slice(storage_slice2.clone())
|
|
.compute_slice_price(0.045)
|
|
.storage_slice_price(0.018)
|
|
.network_slice_price(0.012)
|
|
.status(ContractStatus::Active)
|
|
.start_date(1640995200)
|
|
.end_date(1735689600) // 2025-01-01
|
|
.billing_period(BillingPeriod::Monthly)
|
|
.signature_user("contract_user_204_jkl012".to_string())
|
|
.signature_hoster("hoster_enterprise_mno345".to_string());
|
|
|
|
// Save all contracts to database and get their assigned IDs and updated models
|
|
let (contract1_id, db_contract1) = db
|
|
.collection()
|
|
.expect("can open contract collection")
|
|
.set(&contract1)
|
|
.expect("can set contract");
|
|
let (contract2_id, db_contract2) = db
|
|
.collection()
|
|
.expect("can open contract collection")
|
|
.set(&contract2)
|
|
.expect("can set contract");
|
|
let (contract3_id, db_contract3) = db
|
|
.collection()
|
|
.expect("can open contract collection")
|
|
.set(&contract3)
|
|
.expect("can set contract");
|
|
let (contract4_id, db_contract4) = db
|
|
.collection()
|
|
.expect("can open contract collection")
|
|
.set(&contract4)
|
|
.expect("can set contract");
|
|
|
|
println!("Contract 1 assigned ID: {}", contract1_id);
|
|
println!("Contract 2 assigned ID: {}", contract2_id);
|
|
println!("Contract 3 assigned ID: {}", contract3_id);
|
|
println!("Contract 4 assigned ID: {}", contract4_id);
|
|
|
|
// Print all contracts retrieved from database
|
|
println!("\n--- Contracts Retrieved from Database ---");
|
|
println!("\n1. Web hosting contract:");
|
|
print_contract_details(&db_contract1);
|
|
|
|
println!("\n2. Database hosting contract:");
|
|
print_contract_details(&db_contract2);
|
|
|
|
println!("\n3. ML training contract (paused):");
|
|
print_contract_details(&db_contract3);
|
|
|
|
println!("\n4. Enterprise multi-slice contract:");
|
|
print_contract_details(&db_contract4);
|
|
|
|
// Demonstrate different ways to retrieve contracts from the database
|
|
|
|
// 1. Retrieve by customer ID index
|
|
println!("\n--- Retrieving Contracts by Different Methods ---");
|
|
println!("\n1. By Customer ID Index (Customer 202):");
|
|
let customer_contracts = db
|
|
.collection::<Contract>()
|
|
.expect("can open contract collection")
|
|
.get::<customer_id, _>(&202u32)
|
|
.expect("can load contracts by customer");
|
|
|
|
assert_eq!(customer_contracts.len(), 1);
|
|
print_contract_details(&customer_contracts[0]);
|
|
|
|
// 2. Update contract status
|
|
println!("\n2. Resuming Paused Contract:");
|
|
let mut updated_contract = db_contract3.clone();
|
|
updated_contract.status = ContractStatus::Active;
|
|
|
|
let (_, resumed_contract) = db
|
|
.collection::<Contract>()
|
|
.expect("can open contract collection")
|
|
.set(&updated_contract)
|
|
.expect("can update contract");
|
|
|
|
println!("Updated contract status to Active:");
|
|
print_contract_details(&resumed_contract);
|
|
|
|
// 3. Cancel a contract
|
|
println!("\n3. Cancelling a Contract:");
|
|
let mut cancelled_contract = db_contract1.clone();
|
|
cancelled_contract.status = ContractStatus::Cancelled;
|
|
|
|
let (_, final_contract) = db
|
|
.collection::<Contract>()
|
|
.expect("can open contract collection")
|
|
.set(&cancelled_contract)
|
|
.expect("can update contract");
|
|
|
|
println!("Cancelled contract:");
|
|
print_contract_details(&final_contract);
|
|
|
|
// Show remaining active contracts
|
|
let all_contracts = db
|
|
.collection::<Contract>()
|
|
.expect("can open contract collection")
|
|
.get_all()
|
|
.expect("can load all contracts");
|
|
|
|
println!("\n--- Contract Analytics ---");
|
|
let active_contracts: Vec<_> = all_contracts.iter()
|
|
.filter(|c| matches!(c.status, ContractStatus::Active))
|
|
.collect();
|
|
let paused_contracts: Vec<_> = all_contracts.iter()
|
|
.filter(|c| matches!(c.status, ContractStatus::Paused))
|
|
.collect();
|
|
let cancelled_contracts: Vec<_> = all_contracts.iter()
|
|
.filter(|c| matches!(c.status, ContractStatus::Cancelled))
|
|
.collect();
|
|
|
|
println!("Total Contracts: {}", all_contracts.len());
|
|
println!("Active Contracts: {}", active_contracts.len());
|
|
println!("Paused Contracts: {}", paused_contracts.len());
|
|
println!("Cancelled Contracts: {}", cancelled_contracts.len());
|
|
|
|
// Calculate total provisioned resources
|
|
let total_compute_slices: usize = all_contracts.iter().map(|c| c.compute_slices.len()).sum();
|
|
let total_storage_slices: usize = all_contracts.iter().map(|c| c.storage_slices.len()).sum();
|
|
let total_memory_gb: f64 = all_contracts.iter()
|
|
.flat_map(|c| &c.compute_slices)
|
|
.map(|s| s.mem_gb)
|
|
.sum();
|
|
let total_storage_gb: i32 = all_contracts.iter()
|
|
.flat_map(|c| &c.storage_slices)
|
|
.map(|s| s.storage_size_gb)
|
|
.sum();
|
|
|
|
println!("\nProvisioned Resources:");
|
|
println!(" Total Compute Slices: {}", total_compute_slices);
|
|
println!(" Total Storage Slices: {}", total_storage_slices);
|
|
println!(" Total Memory: {:.1} GB", total_memory_gb);
|
|
println!(" Total Storage: {} GB", total_storage_gb);
|
|
|
|
// Calculate average pricing
|
|
let avg_compute_price: f64 = all_contracts.iter().map(|c| c.compute_slice_price).sum::<f64>() / all_contracts.len() as f64;
|
|
let avg_storage_price: f64 = all_contracts.iter().map(|c| c.storage_slice_price).sum::<f64>() / all_contracts.len() as f64;
|
|
let avg_network_price: f64 = all_contracts.iter().map(|c| c.network_slice_price).sum::<f64>() / all_contracts.len() as f64;
|
|
|
|
println!("\nAverage Pricing:");
|
|
println!(" Compute: ${:.3} per slice", avg_compute_price);
|
|
println!(" Storage: ${:.3} per slice", avg_storage_price);
|
|
println!(" Network: ${:.3} per slice", avg_network_price);
|
|
|
|
println!("\n--- Model Information ---");
|
|
println!("Contract DB Prefix: {}", Contract::db_prefix());
|
|
}
|