use sodiumoxide;
use std::sync::mpsc::{Receiver, Sender, channel};
use action::Action;
use authority::Authority;
use core::Core;
use data::{Data, DataRequest};
use error::{InterfaceError, RoutingError};
use event::Event;
use messages::{RequestContent, RequestMessage, ResponseContent, ResponseMessage, RoutingMessage};
use sodiumoxide::crypto::hash::sha512;
use xor_name::XorName;
use types::MessageId;
type RoutingResult = Result<(), RoutingError>;
pub struct Node {
interface_result_tx: Sender<Result<(), InterfaceError>>,
interface_result_rx: Receiver<Result<(), InterfaceError>>,
action_sender: ::types::RoutingActionSender,
_raii_joiner: ::maidsafe_utilities::thread::RaiiThreadJoiner,
}
impl Node {
pub fn new(event_sender: Sender<Event>) -> Result<Node, RoutingError> {
sodiumoxide::init();
let (action_sender, raii_joiner) = try!(Core::new(event_sender, false, None));
let (tx, rx) = channel();
Ok(Node {
interface_result_tx: tx,
interface_result_rx: rx,
action_sender: action_sender,
_raii_joiner: raii_joiner,
})
}
pub fn send_get_request(&self,
src: Authority,
dst: Authority,
data_request: DataRequest,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Request(RequestMessage {
src: src,
dst: dst,
content: RequestContent::Get(data_request, id),
});
self.send_action(routing_msg)
}
pub fn send_put_request(&self,
src: Authority,
dst: Authority,
data: Data,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Request(RequestMessage {
src: src,
dst: dst,
content: RequestContent::Put(data, id),
});
self.send_action(routing_msg)
}
pub fn send_post_request(&self,
src: Authority,
dst: Authority,
data: Data,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Request(RequestMessage {
src: src,
dst: dst,
content: RequestContent::Post(data, id),
});
self.send_action(routing_msg)
}
pub fn send_delete_request(&self,
src: Authority,
dst: Authority,
data: Data,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Request(RequestMessage {
src: src,
dst: dst,
content: RequestContent::Delete(data, id),
});
self.send_action(routing_msg)
}
pub fn send_get_success(&self,
src: Authority,
dst: Authority,
data: Data,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::GetSuccess(data, id),
});
self.send_action(routing_msg)
}
pub fn send_get_failure(&self,
src: Authority,
dst: Authority,
request: RequestMessage,
external_error_indicator: Vec<u8>,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::GetFailure {
id: id,
request: request,
external_error_indicator: external_error_indicator,
},
});
self.send_action(routing_msg)
}
pub fn send_put_success(&self,
src: Authority,
dst: Authority,
request_hash: sha512::Digest,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::PutSuccess(request_hash, id),
});
self.send_action(routing_msg)
}
pub fn send_put_failure(&self,
src: Authority,
dst: Authority,
request: RequestMessage,
external_error_indicator: Vec<u8>,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::PutFailure {
id: id,
request: request,
external_error_indicator: external_error_indicator,
},
});
self.send_action(routing_msg)
}
pub fn send_post_success(&self,
src: Authority,
dst: Authority,
request_hash: sha512::Digest,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::PostSuccess(request_hash, id),
});
self.send_action(routing_msg)
}
pub fn send_post_failure(&self,
src: Authority,
dst: Authority,
request: RequestMessage,
external_error_indicator: Vec<u8>,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::PostFailure {
id: id,
request: request,
external_error_indicator: external_error_indicator,
},
});
self.send_action(routing_msg)
}
pub fn send_delete_success(&self,
src: Authority,
dst: Authority,
request_hash: sha512::Digest,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::DeleteSuccess(request_hash, id),
});
self.send_action(routing_msg)
}
pub fn send_delete_failure(&self,
src: Authority,
dst: Authority,
request: RequestMessage,
external_error_indicator: Vec<u8>,
id: MessageId)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Response(ResponseMessage {
src: src,
dst: dst,
content: ResponseContent::DeleteFailure {
id: id,
request: request,
external_error_indicator: external_error_indicator,
},
});
self.send_action(routing_msg)
}
pub fn send_refresh_request(&self,
src: Authority,
content: Vec<u8>)
-> Result<(), InterfaceError> {
let routing_msg = RoutingMessage::Request(RequestMessage {
src: src.clone(),
dst: src,
content: RequestContent::Refresh(content),
});
self.send_action(routing_msg)
}
pub fn close_group(&self) -> Result<Vec<XorName>, InterfaceError> {
let (result_tx, result_rx) = channel();
try!(self.action_sender.send(Action::CloseGroup { result_tx: result_tx }));
Ok(try!(result_rx.recv()))
}
pub fn name(&self) -> Result<XorName, InterfaceError> {
let (result_tx, result_rx) = channel();
try!(self.action_sender.send(Action::Name { result_tx: result_tx }));
Ok(try!(result_rx.recv()))
}
fn send_action(&self, routing_msg: RoutingMessage) -> Result<(), InterfaceError> {
try!(self.action_sender.send(Action::NodeSendMessage {
content: routing_msg,
result_tx: self.interface_result_tx.clone(),
}));
try!(self.interface_result_rx.recv())
}
}
impl Drop for Node {
fn drop(&mut self) {
if let Err(err) = self.action_sender.send(Action::Terminate) {
error!("Error {:?} sending event Core", err);
}
}
}