use acmex::client::CertificateBundle;
use acmex::prelude::*;
use acmex::renewal::RenewalHook;
use acmex::scheduler::AdvancedRenewalScheduler;
use acmex::storage::{CertificateStore, MemoryStorage};
use std::sync::Arc;
use std::time::Duration;
struct MyRenewalHook;
impl RenewalHook for MyRenewalHook {
fn before_renewal(&self, domains: &[String]) {
println!("🚀 Starting renewal process for domains: {:?}", domains);
}
fn after_renewal(&self, domains: &[String], _bundle: &CertificateBundle) {
println!("✅ Successfully renewed domains: {:?}", domains);
}
fn on_error(&self, domains: &[String], error: &AcmeError) {
eprintln!(
"❌ Renewal failed for domains: {:?}. Error: {}",
domains, error
);
}
}
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
let storage = Arc::new(MemoryStorage::new());
let cert_store = CertificateStore::new(storage);
let config = AcmeConfig::lets_encrypt_staging()
.with_contact(Contact::email("ops@example.com"))
.with_tos_agreed(true);
let client = AcmeClient::new(config)?;
let concurrency = 5;
let (scheduler, task_tx) = AdvancedRenewalScheduler::new(client, cert_store, concurrency);
let scheduler = Arc::new(scheduler.with_hook(Arc::new(MyRenewalHook)));
let s_clone = scheduler.clone();
tokio::spawn(async move {
s_clone.run().await;
});
println!("Enqueuing manual renewal task...");
task_tx
.send(acmex::scheduler::renewal_scheduler::RenewalTask {
domains: vec!["example.org".to_string()],
priority: acmex::scheduler::renewal_scheduler::Priority::Urgent,
retry_count: 0,
})
.await
.map_err(|e| format!("Send error: {}", e))?;
tokio::time::sleep(Duration::from_secs(5)).await;
println!("Scheduler example finished (demo mode).");
Ok(())
}