- Updated RegisterRunnerParams to only require name (queue = name) - Added AddRunnerParams with RunnerConfig for add_runner method - Updated RunnerManagementParams and StopRunnerParams with secrets - Added add_runner method to OpenRPC trait and implementation - Removed duplicate AddRunnerParams definition - Updated client register_runner to send params as JSON object - Added TODO comments for moving secrets to HTTP headers
245 lines
9.7 KiB
Rust
245 lines
9.7 KiB
Rust
///! Comprehensive OSIRIS + OpenRPC Example
|
|
///!
|
|
///! This example demonstrates:
|
|
///! 1. Starting a Hero Supervisor with OpenRPC server
|
|
///! 2. Starting an OSIRIS runner
|
|
///! 3. Registering the runner with the supervisor
|
|
///! 4. Dispatching multiple OSIRIS jobs via OpenRPC
|
|
///! 5. Monitoring job execution
|
|
///! 6. Graceful shutdown
|
|
///!
|
|
///! Usage:
|
|
///! ```bash
|
|
///! cargo run --example osiris_openrpc
|
|
///! ```
|
|
|
|
use hero_supervisor_openrpc_client::{SupervisorClient, RunnerConfig, JobBuilder};
|
|
use std::time::Duration;
|
|
use escargot::CargoBuild;
|
|
use std::process::Stdio;
|
|
use tokio::time::sleep;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("🚀 OSIRIS + OpenRPC Comprehensive Example");
|
|
println!("=========================================\n");
|
|
|
|
// ========================================================================
|
|
// STEP 1: Build and start supervisor with OpenRPC
|
|
// ========================================================================
|
|
println!("Step 1: Building and starting supervisor");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
let supervisor_binary = CargoBuild::new()
|
|
.bin("supervisor")
|
|
.current_release()
|
|
.manifest_path("../supervisor/Cargo.toml")
|
|
.run()?;
|
|
|
|
println!("✅ Supervisor binary built");
|
|
|
|
let mut supervisor = supervisor_binary.command()
|
|
.arg("--redis-url")
|
|
.arg("redis://localhost:6379")
|
|
.arg("--port")
|
|
.arg("3030")
|
|
.arg("--admin-secret")
|
|
.arg("admin_secret")
|
|
.arg("--user-secret")
|
|
.arg("user_secret")
|
|
.stdout(Stdio::inherit())
|
|
.stderr(Stdio::inherit())
|
|
.spawn()?;
|
|
|
|
println!("✅ Supervisor started on port 3030");
|
|
println!("⏳ Waiting for supervisor to initialize...");
|
|
sleep(Duration::from_secs(5)).await;
|
|
|
|
// Check if supervisor is still running
|
|
match supervisor.try_wait()? {
|
|
Some(status) => {
|
|
return Err(format!("Supervisor exited early with status: {}", status).into());
|
|
}
|
|
None => {
|
|
println!("✅ Supervisor is running");
|
|
}
|
|
}
|
|
|
|
// ========================================================================
|
|
// STEP 2: Build OSIRIS runner
|
|
// ========================================================================
|
|
println!("\nStep 2: Building OSIRIS runner");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
let runner_binary = CargoBuild::new()
|
|
.bin("runner_osiris")
|
|
.current_release()
|
|
.manifest_path("../runner_rust/Cargo.toml")
|
|
.run()?;
|
|
|
|
println!("✅ OSIRIS runner binary built");
|
|
|
|
// ========================================================================
|
|
// STEP 3: Connect OpenRPC client
|
|
// ========================================================================
|
|
println!("\nStep 3: Connecting OpenRPC client");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
let client = SupervisorClient::new("http://127.0.0.1:3030")?;
|
|
println!("✅ Connected to supervisor\n");
|
|
|
|
// ========================================================================
|
|
// STEP 4: Register and start OSIRIS runner
|
|
// ========================================================================
|
|
println!("Step 4: Registering OSIRIS runner");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
let runner_path = runner_binary.path().to_string_lossy();
|
|
let db_path = "/tmp/osiris_openrpc.db";
|
|
|
|
// Register the runner with the supervisor
|
|
// Note: The current OpenRPC server uses register_runner, not add_runner
|
|
client.register_runner("admin_secret", "osiris_runner").await?;
|
|
println!("✅ Runner registered: osiris_runner");
|
|
|
|
client.start_runner("admin_secret", "osiris_runner").await?;
|
|
println!("✅ Runner started\n");
|
|
|
|
sleep(Duration::from_secs(2)).await;
|
|
|
|
// ========================================================================
|
|
// STEP 5: Load job scripts
|
|
// ========================================================================
|
|
println!("Step 5: Loading job scripts");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
let note_script = std::fs::read_to_string("examples/osiris_openrpc/note.rhai")?;
|
|
let event_script = std::fs::read_to_string("examples/osiris_openrpc/event.rhai")?;
|
|
let query_script = std::fs::read_to_string("examples/osiris_openrpc/query.rhai")?;
|
|
let access_denied_script = std::fs::read_to_string("examples/osiris_openrpc/access_denied.rhai")?;
|
|
|
|
println!("✅ Loaded 4 job scripts\n");
|
|
|
|
// ========================================================================
|
|
// STEP 6: Dispatch jobs via OpenRPC
|
|
// ========================================================================
|
|
println!("Step 6: Dispatching jobs");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
// Job 1: Create Note
|
|
println!("📝 Job 1: Creating Note...");
|
|
let job1 = JobBuilder::new()
|
|
.caller_id("openrpc_client")
|
|
.context_id("osiris_demo")
|
|
.payload(¬e_script)
|
|
.runner("osiris_runner")
|
|
.executor("rhai")
|
|
.timeout(30)
|
|
.signature("alice", "")
|
|
.signature("bob", "")
|
|
.build()?;
|
|
|
|
let job1_result = client.run_job("user_secret", job1).await;
|
|
|
|
match job1_result {
|
|
Ok(result) => println!("✅ {:?}\n", result),
|
|
Err(e) => println!("❌ Job failed: {}\n", e),
|
|
}
|
|
|
|
sleep(Duration::from_secs(1)).await;
|
|
|
|
// Job 2: Create Event
|
|
println!("📅 Job 2: Creating Event...");
|
|
let job2 = JobBuilder::new()
|
|
.caller_id("openrpc_client")
|
|
.context_id("osiris_demo")
|
|
.payload(&event_script)
|
|
.runner("osiris_runner")
|
|
.executor("rhai")
|
|
.timeout(30)
|
|
.signature("alice", "")
|
|
.signature("bob", "")
|
|
.build()?;
|
|
|
|
let job2_result = client.run_job("user_secret", job2).await;
|
|
|
|
match job2_result {
|
|
Ok(result) => println!("✅ {:?}\n", result),
|
|
Err(e) => println!("❌ Job failed: {}\n", e),
|
|
}
|
|
|
|
sleep(Duration::from_secs(1)).await;
|
|
|
|
// Job 3: Query Data
|
|
println!("🔍 Job 3: Querying Data...");
|
|
let job3 = JobBuilder::new()
|
|
.caller_id("openrpc_client")
|
|
.context_id("osiris_demo")
|
|
.payload(&query_script)
|
|
.runner("osiris_runner")
|
|
.executor("rhai")
|
|
.timeout(30)
|
|
.signature("alice", "")
|
|
.signature("bob", "")
|
|
.signature("charlie", "")
|
|
.build()?;
|
|
|
|
let job3_result = client.run_job("user_secret", job3).await;
|
|
|
|
match job3_result {
|
|
Ok(result) => println!("✅ {:?}\n", result),
|
|
Err(e) => println!("❌ Job failed: {}\n", e),
|
|
}
|
|
|
|
sleep(Duration::from_secs(1)).await;
|
|
|
|
// Job 4: Access Control Test (should fail)
|
|
println!("🔒 Job 4: Testing Access Control (expected to fail)...");
|
|
let job4 = JobBuilder::new()
|
|
.caller_id("openrpc_client")
|
|
.context_id("osiris_demo")
|
|
.payload(&access_denied_script)
|
|
.runner("osiris_runner")
|
|
.executor("rhai")
|
|
.timeout(30)
|
|
.signature("alice", "")
|
|
.signature("bob", "")
|
|
.signature("charlie", "")
|
|
.build()?;
|
|
|
|
let job4_result = client.run_job("user_secret", job4).await;
|
|
|
|
match job4_result {
|
|
Ok(result) => println!("❌ Unexpected success: {:?}\n", result),
|
|
Err(e) => println!("✅ Access denied as expected: {}\n", e),
|
|
}
|
|
|
|
// ========================================================================
|
|
// STEP 7: Check runner status
|
|
// ========================================================================
|
|
println!("\nStep 7: Checking runner status");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
let status = client.get_runner_status("admin_secret", "osiris_runner").await?;
|
|
println!("Runner status: {:?}\n", status);
|
|
|
|
// ========================================================================
|
|
// STEP 8: Cleanup
|
|
// ========================================================================
|
|
println!("Step 8: Cleanup");
|
|
println!("─────────────────────────────────────────────────────────────\n");
|
|
|
|
client.stop_runner("admin_secret", "osiris_runner", false).await?;
|
|
println!("✅ Runner stopped");
|
|
|
|
client.remove_runner("admin_secret", "osiris_runner").await?;
|
|
println!("✅ Runner removed");
|
|
|
|
supervisor.kill()?;
|
|
println!("✅ Supervisor stopped");
|
|
|
|
println!("\n✨ Example completed successfully!");
|
|
|
|
Ok(())
|
|
}
|