Skip to content

Commit

Permalink
Client side of the registration service. r=arcturus
Browse files Browse the repository at this point in the history
  • Loading branch information
fabricedesre committed Feb 23, 2016
1 parent 562f482 commit 9bb753f
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 4 deletions.
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ docopt = "0.6.78"
docopt_macros = "0.6.80"
env_logger = "0.3.2"
foxbox_users = { git = "https://github.com/fxbox/users.git", rev = "78d3e2f" }
get_if_addrs = "0.3.1"
hyper = "0.7.2"
iron = "0.2.6"
iron-test = "0.2.0"
log = "0.3"
Expand Down
12 changes: 9 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ extern crate staticfile;
extern crate uuid;

mod context;
mod controller;
mod dummy_adapter;
mod events;
mod http_server;
mod service;
mod controller;
mod registration;
mod service_router;

mod stubs {
Expand All @@ -56,24 +57,29 @@ use context::{ ContextTrait, Context };
use controller::Controller;

docopt!(Args derive Debug, "
Usage: foxbox [-v] [-h] [-n <hostname>] [-p <port>] [-w <wsport>]
Usage: foxbox [-v] [-h] [-n <hostname>] [-p <port>] [-w <wsport>] [-r <url>]
Options:
-v, --verbose Toggle verbose output.
-n, --name <hostname> Set local hostname.
-p, --port <port> Set port to listen on for http connections.
-w, --wsport <wsport> Set port to listen on for websocket.
-r, --register <url> Change the url of the registration endpoint.
-h, --help Print this help menu.
",
flag_name: Option<String>,
flag_port: Option<u16>,
flag_wsport: Option<u16>);
flag_wsport: Option<u16>,
flag_register: Option<String>);

fn main() {
env_logger::init().unwrap();

let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());

let registrar = registration::Registrar::new();
registrar.start(args.flag_register);

if let Ok(mut event_loop) = mio::EventLoop::new() {
let sender = event_loop.channel();

Expand Down
111 changes: 111 additions & 0 deletions src/registration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/// This manages registration of the foxbox with the discovery endpoint.
/// For now it simply register itselfs every N minutes with the endpoint,
/// after trying more aggressively at first run.

extern crate get_if_addrs;
extern crate hyper;

use self::hyper::Client;
use self::hyper::header::Connection;
use self::hyper::status::StatusCode;
use self::get_if_addrs::IfAddr;
use std::io::Read;
use std::time::Duration;
use std::thread;

const DEFAULT_ENDPOINT: &'static str = "http://localhost:4242/register";
const REGISTRATION_INTERVAL: u32 = 1; // in minutes.

pub struct Registrar;

impl Registrar {
pub fn new() -> Registrar {
Registrar
}

pub fn start(&self, endpoint: Option<String>) {
let url = match endpoint {
Some(u) => u,
_ => DEFAULT_ENDPOINT.to_owned()
};

info!("Starting registration with {}", url);
let ip_addr = self.get_ip_addr();
if ip_addr == None {
// TODO: retry later, in case we're racing with the network
// configuration.
return;
}

info!("Got ip address: {}", ip_addr.clone().unwrap());
let full_address = format!("{}?ip={}", url, ip_addr.unwrap());

// Spawn a thread to register every REGISTRATION_INTERVAL minutes.
thread::Builder::new().name("Registrar".to_owned())
.spawn(move || {
loop {
let client = Client::new();
let res = client.get(&full_address)
.header(Connection::close())
.send();

// Sanity checks, mostly to debug errors since we don't try
// to recover from failures.
if let Ok(mut response) = res {
if response.status == StatusCode::Ok {
let mut body = String::new();
if let Ok(_) = response.read_to_string(&mut body) {
info!("Server responded with: {}", body);
} else {
info!("Unable to read answer from {}", full_address);
}
}
} else {
info!("Unable to send request to {}", full_address);
}

// Go to sleep.
thread::sleep(Duration::from_secs(REGISTRATION_INTERVAL as u64 * 60))
}
}).unwrap();
}

pub fn get_ip_addr(&self) -> Option<String> {
// Look for an ipv4 interface on eth* or wlan*.
if let Ok(ifaces) = get_if_addrs::get_if_addrs() {
if ifaces.is_empty() {
error!("No IP interfaces found!");
return None;
}

let mut ip_addr: Option<String> = None;

for iface in ifaces {
if ! (iface.name.starts_with("eth") ||
iface.name.starts_with("wlan") ||
iface.name.starts_with("en")) {
continue;
}
if let IfAddr::V4(ref v4) = iface.addr {
ip_addr = Some(format!("{}", v4.ip));
}
}

ip_addr
} else {
error!("No IP interfaces found!");
None
}
}
}

#[test]
fn check_ip_addr() {
let registrar = Registrar::new();
let ip_addr = registrar.get_ip_addr();
assert!(ip_addr != None);
}
4 changes: 3 additions & 1 deletion src/service_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use context::{ ContextTrait, Shared };
use iron::{Request, Response, IronResult};
use iron::headers::ContentType;
use iron::headers::{ ContentType, AccessControlAllowOrigin };
use iron::status::Status;
use router::Router;
use core::marker::Reflect;
Expand All @@ -21,6 +21,7 @@ pub fn create<Ctx: Send + Reflect + ContextTrait + 'static> (context: Shared<Ctx

let mut response = Response::with(serialized);
response.status = Some(Status::Ok);
response.headers.set(AccessControlAllowOrigin::Any);
response.headers.set(ContentType::json());

Ok(response)
Expand All @@ -36,6 +37,7 @@ pub fn create<Ctx: Send + Reflect + ContextTrait + 'static> (context: Shared<Ctx
None => {
let mut response = Response::with(format!("No Such Service: {}", id));
response.status = Some(Status::BadRequest);
response.headers.set(AccessControlAllowOrigin::Any);
response.headers.set(ContentType::plaintext());
Ok(response)
}
Expand Down

0 comments on commit 9bb753f

Please sign in to comment.