pub mod context;
mod handler;
mod message;
mod router;
use std::collections::HashMap;
pub use crate::prelude::derives;
use crate::{chaincode::context::Context, fabric::protos::ChaincodeId};
use prost::Message;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Metadata {
pub chaincode_id: String,
pub mspid: String,
pub peer_address: String,
pub client_cert: String,
pub client_key: String,
pub root_cert: String,
}
pub trait Callable {
fn call(&self, ctx: Context, args: Vec<String>) -> tokio::task::JoinHandle<Result<String, String>>;
fn name(&self) -> &str;
}
pub struct Launcher {
metadata: Metadata,
chaincode_id: ChaincodeId,
contracts: HashMap<String, HashMap<String, Box<dyn Callable>>>,
}
impl Launcher {
pub fn register(mut self, contract_name: &str, functions: Vec<Box<dyn Callable>>) -> Self {
if self
.contracts
.insert(contract_name.to_string(), HashMap::new())
.is_some()
{
panic!("Cannot insert same contract twice");
}
let contract = self
.contracts
.get_mut(contract_name)
.expect("Couldn't get contract");
for function in functions {
contract.insert(function.name().to_string(), function);
}
self
}
pub fn launch(self) {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Unable to start tokio runtime")
.block_on(async {
let message_handler =
handler::MessageHandler::new(&self.metadata, self.chaincode_id, self.contracts)
.await;
message_handler.run().await;
println!("Message handler exited");
});
}
}
pub fn initialize() -> Launcher {
let metadata = std::env::var("METADATA").unwrap();
let metadata =
serde_json::from_str::<Metadata>(metadata.as_str()).expect("Invalid metadata json");
let vec = metadata.chaincode_id.clone().encode_to_vec();
let buf = vec.as_slice();
let chaincode_id = ChaincodeId::decode(buf).expect("No valid chaincode id");
Launcher {
metadata,
chaincode_id,
contracts: HashMap::new(),
}
}