This commit is contained in:
raluca-elena 2014-08-14 23:23:31 -07:00
Родитель bb52c7cf85
Коммит e44ca96aa7
4 изменённых файлов: 158 добавлений и 507 удалений

129
directory_server/index.js Normal file → Executable file
Просмотреть файл

@ -1,32 +1,32 @@
const http = require("http")
const fs = require("fs")
const url = require("url")
const utf8 = require("utf8")
var config = JSON.parse(fs.readFileSync(process.argv[2]))
// {ip:{uuid1: {expiryTime:unix, payload:{handlePing payload buffer}}}}
const express = require("express")
var getRawBody = require('raw-body');
var app = express();
var cors = require('cors');
var config = JSON.parse(fs.readFileSync(process.argv[2]));
var things = {}
// make sure errors are not cached
function fail(response, code, message) {
response.writeHead(code, {"Content-Type": "text/plain",
"Content-Length": message.length,
});
response.write(message);
console.log("fail", code, message, things);
response.end();
}
app.use(cors());
function ok(response, message) {
response.writeHead(200, {"Content-Type": "text/plain",
"Content-Length": message.length
});
response.write(message);
response.end();
}
app.use(function (req, res, next) {
getRawBody(req, {
length: req.headers['content-length'],
limit: '1mb',
encoding: 'utf8'
}, function (err, string) {
if (err)
return next(err);
req.text = string;
next()
})
});
/** put json to /thing/stable-uuid
{'uuid':x, 'localurl':y, 'tags':["tag1", ..], 'description':"raspberry pi"}
repeat calls here should just PUT an empty body...Server will 404 if body not already present
*/
function putPing(uuid, remoteAddress, payload) {
var network = things[remoteAddress];
if (!network) {
@ -42,73 +42,36 @@ function putPing(uuid, remoteAddress, payload) {
thing.payload = payload.toString('utf8');
}
/** put json to /thing/stable-uuid
{'uuid':x, 'localurl':y, 'tags':["tag1", ..], 'description':"raspberry pi"}
repeat calls here should just PUT an empty body...Server will 404 if body not already present
*/
function handlePing(uuid, request, response) {
if (!('content-length' in request.headers)) {
return fail(response, 500, "Missing content-length header");
}
var content_length = request.headers['content-length'] * 1
var buf = new Buffer(content_length);
var pos = 0;
request.on('data', function(chunk) {
chunk.copy(buf, pos);
pos += chunk.length;
console.log("got data for uuid ", uuid, "data", chunk.toString('utf8'));
})
request.on('end', function() {
var remoteAddress = request.connection.remoteAddress;
console.log("request.connection.remoteAddress", request.connection.remoteAddress)
putPing(uuid, remoteAddress, buf);
ok(response, "OK");
});
}
function handleGet(request, response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET,POST"); //?put
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
var pathname = url.parse(request.url).pathname;
var remoteAddress = request.connection.remoteAddress;
function getNetwork(req) {
var remoteAddress = req.connection.remoteAddress;
console.log("my remote address is ------", remoteAddress);
var network = things[remoteAddress];
if (!network)
network = {};
if (pathname == "/ls") {
return ok(response, JSON.stringify(network));
} if (pathname.substr(0, 7) == "/thing/") {
var uuid = pathname.substr(7);
var thing = network[uuid];
if (!thing)
return fail(response, 404, "No thing " + uuid + " in " + remoteAddress + " network");
return ok(response, thing.payload);
} else {
return fail(response, 404, pathname + " not found");
}
return network;
}
function handlePut(request, response) {
var pathname = url.parse(request.url).pathname;
if (pathname.substr(0,7) == "/thing/") {
return handlePing(pathname.substr(7), request, response);
}
response.write(pathname);
response.end();
}
app.get('/ls', function(req, res) {
res.json(getNetwork(req));
});
http.createServer(function(request, response) {
var pathname = url.parse(request.url).pathname;
if (request.method == "GET" || request.method == "HEAD") {
return handleGet(request, response);
} else if (request.method == "PUT") {
return handlePut(request, response);
} else {
fail(response, 500, "what is this method:"+request.method);
}
//also handle CONNECT for proxying
}).listen(config.port, config.host);
app.get(/^\/thing\/([A-z:0-9.-]+|\*)$/, function(req, res){
var network = getNetwork(req);
var uuid = req.path.substr("/thing/".length);
var thing = network[uuid];
if (!thing)
return res.send(404, "No thing " + uuid + " in " + req.connection.remoteAddress + " network");
return res.send(thing.payload);
});
app.put(/^\/thing\/([A-z:0-9.-]+|\*)$/, function(req, res){
var uuid = req.path.substr("/thing/".length);
var remoteAddress = req.connection.remoteAddress;
console.log("request.connection.remoteAddress", req.connection.remoteAddress);
putPing(uuid, remoteAddress, req.text);
res.send("OK");
});
app.listen(config.port);
console.log("Server running at\n =>"+config.host+":" + config.port + "/\nCTRL + C to shutdown");

Просмотреть файл

@ -1,77 +0,0 @@
const fs = require("fs")
const url = require("url")
const utf8 = require("utf8")
const express = require("express")
var getRawBody = require('raw-body');
var app = express();
var cors = require('cors');
var config = JSON.parse(fs.readFileSync(process.argv[2]));
var things = {}
app.use(cors());
app.use(function (req, res, next) {
getRawBody(req, {
length: req.headers['content-length'],
limit: '1mb',
encoding: 'utf8'
}, function (err, string) {
if (err)
return next(err);
req.text = string;
next()
})
});
/** put json to /thing/stable-uuid
{'uuid':x, 'localurl':y, 'tags':["tag1", ..], 'description':"raspberry pi"}
repeat calls here should just PUT an empty body...Server will 404 if body not already present
*/
function putPing(uuid, remoteAddress, payload) {
var network = things[remoteAddress];
if (!network) {
things[remoteAddress] = network = {};
}
var thing = network[uuid];
if (!thing) {
console.log("got no thing :(");
network[uuid] = thing = {};
console.log("network is ", network);
}
thing.expiryTime = Date.now();
thing.payload = payload.toString('utf8');
}
function getNetwork(req) {
var remoteAddress = req.connection.remoteAddress;
console.log("my remote address is ------", remoteAddress);
var network = things[remoteAddress];
if (!network)
network = {};
return network;
}
app.get('/ls', function(req, res) {
res.json(getNetwork(req));
});
app.get(/^\/thing\/([A-z:0-9.-]+|\*)$/, function(req, res){
var network = getNetwork(req);
var uuid = req.path.substr("/thing/".length);
var thing = network[uuid];
if (!thing)
return res.send(404, "No thing " + uuid + " in " + req.connection.remoteAddress + " network");
return res.send(thing.payload);
});
app.put(/^\/thing\/([A-z:0-9.-]+|\*)$/, function(req, res){
var uuid = req.path.substr("/thing/".length);
var remoteAddress = req.connection.remoteAddress;
console.log("request.connection.remoteAddress", req.connection.remoteAddress);
putPing(uuid, remoteAddress, req.text);
res.send("OK");
});
app.listen(config.port);
console.log("Server running at\n =>"+config.host+":" + config.port + "/\nCTRL + C to shutdown");

250
frontend/lib/rot.js Normal file → Executable file
Просмотреть файл

@ -1,105 +1,39 @@
(function(global) {
if (typeof superagent === 'undefined') {
superagent = require('superagent');
}
(function(exports){
"use strict";
var ROT = {};
var baseurl = "http://10.0.0.3:8080";
//var baseurl = "http://10.251.38.229:8080";
var allUuids = [];
var allThings = {}; // { 'uuid1dc65c13': { uuid: 'uuid1dc65c13', localURL: 'http://slave:80' }}
var allTags = {};
var allThings = {};
var allFeatures = {}
var allTags = {};
function isValidURL(url){
var RegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if(RegExp.test(url)){
return true;
}else{
return false;
}
}
/*
= get my data => GET /ls on directory => [data]
= for each uuid => GET /thing/uuid/ => info registeded by each device/slave. {"uuid":uuid, "localURL": slave-rest-endpoint}
= for each uuid => GET /tags/. First time, no tags defined (likely): brand new device.
*/
function init(cb) {
superagent.get(baseurl + "/ls", function(err, res) {
ROT.init = function init(cb) {
superagent.get(baseurl + "/ls", function (err, res) {
console.log("--------------------- ROT init ------------------");
if (err) {
cb(err);
return;
}
var uuids = Object.keys(JSON.parse(res.text));
console.log("ROT got uuids: ", uuids);
allUuids = uuids;
getAllThings(uuids, function(err, things) {
allUuids = Object.keys(JSON.parse(res.text));
console.log("ROT got uuids: ", allUuids);
_getAllThings(allUuids, function (err, things) {
allThings = things;
console.log("ROT allThings: ", allThings);
getAllFeatures(things, function(err, features) {
_getAllFeatures(things, function (err, features) {
allFeatures = features;
console.log("ROT allFeatures: ", allFeatures);
getAllTags(things, function(err, tags) {
console.log("ROT allFeatures: ", allFeatures);
_getAllTags(things, function (err, tags) {
allTags = tags;
console.log("ROT allTags: ", allTags);
console.log("ROT allTags: ", allTags);
cb();
});
});
});
});
}
};
function queryTags(tags, cb) {
// ["tag1", "tag2"], cb (resp, err)); where resp: {"tag1": ?, "tag2": ?}
var resp = {};
for (var i = 0; i < tags.length; i++) {
resp[tags[i]] = allTags[tags[i]];
}
cb(resp); // no error
}
function readTag(tag, cb) {
var tagData = allTags[tag];
console.log("ROT READ TAG--", tagData);
if (tagData === undefined) {
cb(undefined, "ROT No such tag: " + tag + " :(");
} else if (tagData === undefined) {
cb(undefined, "ROT No url for tag: " + tag + " :(");
} else if (isValidURL(tagData)) {
superagent
.get(tagData)
.end(function(res){
console.log("res is ", res);
cb(res.text);
});
} else {
return tagData;
}
}
function writeTag(tag, data, cb) {
var tagData = allTags[tag];
console.log("IN WRITE TAG and tagData is ", tagData);
if (tagData === undefined) {
cb(undefined, "No such tag: " + tag + " :(");
} else if (tagData === undefined) {
cb(undefined, "No url for tag: " + tag + " :(");
} else if (isValidURL(tagData)){
console.log("valid tag is:", tagData)
superagent.put(tagData)
.send(data)
.end(function(res){
console.log("callback is ", cb);
cb(res.text, !res.ok);
});
} else {
return tagData;
}
}
function getAllThings(uuids, cb) {
function _getAllThings(uuids, cb) {
var things = {};
var errors = undefined;
var done = 0;
@ -108,13 +42,13 @@ function getAllThings(uuids, cb) {
(function() {
var uuid = uuids[i];
superagent.get(baseurl + "/thing/" + uuid, function(err, res) {
if (err) {
if (errors === undefined)
errors = [];
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
} else {
var thing = JSON.parse(res.text);
things[uuid] = thing;
things[uuid] = thing;//things = {uuid1:{}, uuid2:{}};
}
done ++;
if (done === uuids.length) {
@ -123,10 +57,33 @@ function getAllThings(uuids, cb) {
});
})();
}
}
};
function getAllTags(things, cb) {
console.log("ROT I am in getAllTags having things :--------", things);
function _getAllFeatures(things, cb) {
var features = {};
var errors = undefined;
var done = 0;
for (var uuid in things) {
(function(uuid) {
var thing = things[uuid];
superagent.get(thing['localURL'] + "/features/", function(err, res) {
console.log("--> getAllFeatures: err: ", err, " res.text: ", res.text);
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
} else {
features[uuid] = res.text;
}
done ++;
if (done === Object.keys(things).length)
cb(errors, features);
});
})(uuid);
}
};
function _getAllTags(things, cb) {
var tags = {};
var errors = undefined;
var done = 0;
@ -138,7 +95,7 @@ function getAllTags(things, cb) {
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
errors.push(err);
} else {
var tagsResp = JSON.parse(res.text);
console.log("Got tagsResp: ", tagsResp, " for thing: ", thing);
@ -150,7 +107,7 @@ function getAllTags(things, cb) {
if (JSON.parse(tagsResp[tagName]).val !== undefined) {
tags[tagName] = JSON.parse(tagsResp[tagName]).val;
}
}
}
}
done ++;
if (done === Object.keys(things).length)
@ -158,39 +115,9 @@ function getAllTags(things, cb) {
});
})(uuid);
}
}
};
function getAllFeatures(things, cb) {
var features = {};
var errors = undefined;
var done = 0;
for (var uuid in things) {
(function(uuid) {
var thing = things[uuid];
superagent.get(thing['localURL'] + "/features/", function(err, res) {
console.log("--> getAllFeatures: err: ", err, " res.text: ", res.text);
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
} else {
var featuresResp = JSON.parse(res.text);
features[uuid] = JSON.stringify(featuresResp);
}
done ++;
if (done === Object.keys(things).length)
cb(errors, features);
});
})(uuid);
}
}
function getFeatures(cb) {
cb(allFeatures);
}
//only tags for features
function setTag(uuid, feature, tag, cb) {
ROT.setTag = function setTag(uuid, feature, tag, cb) {
var data = {"url":JSON.parse(allFeatures[uuid])[feature].url, "feature":feature};
if (allFeatures[uuid] === undefined) {
cb("No such uuid: " + uuid + " :( in allFeatures:" + allFeatures);
@ -202,7 +129,7 @@ function setTag(uuid, feature, tag, cb) {
var url = allThings[uuid].localURL + "/tags/" + tag;
superagent.put(url)
.send(data)
.end(function(res){
.end(function(res) {
allTags[tag] = JSON.parse(allFeatures[uuid])[feature].url;
if (res.ok) {
cb();
@ -211,25 +138,72 @@ function setTag(uuid, feature, tag, cb) {
}
});
}
}
};
function deleteTag(tag, cb) {
ROT.writeTag = function writeTag(tag, data, cb) {
var tagData = allTags[tag];
if (tagData === undefined) {
cb(undefined, "No such tag: " + tag + " :(");
} else if (tagData === undefined) {
cb(undefined, "No url for tag: " + tag + " :(");
} else if (_isValidURL(tagData)){
console.log("valid tag is:", tagData)
superagent.put(tagData)
.send(data)
.end(function(res){
console.log("callback is ", cb);
cb(res.text, !res.ok);
});
} else {
return tagData;
}
};
ROT.readTag = function readTag(tag, cb) {
var tagData = allTags[tag];
if (tagData === undefined) {
cb(undefined, "ROT No such tag: " + tag + " :(");
} else if (tagData === undefined) {
cb(undefined, "ROT No url for tag: " + tag + " :(");
} else if (_isValidURL(tagData)) {
superagent
.get(tagData)
.end(function(res){
console.log("res is ", res);
cb(res.text);
});
} else {
return tagData;
}
};
ROT.deleteTag = function deleteTag(tag, cb) {
if (allTags[tag] == undefined) {
cb("No such tag: " + tag + " :(");
} else {
delete allTags[tag];
cb(); // no error
}
};
ROT.queryTags = function queryTags(tags, cb) {
// ["tag1", "tag2"], cb (resp, err)); where resp: {"tag1": ?, "tag2": ?}
var resp = {};
for (var i = 0; i < tags.length; i++) {
resp[tags[i]] = allTags[tags[i]];
}
cb(resp); // no error
};
function _isValidURL(url){
var RegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if(RegExp.test(url)){
return true;
} else {
return false;
}
}
// See https://alicoding.com/write-javascript-modules-that-works-both-in-nodejs-and-browser-with-requirejs/
// make it work in both nodejs/browser.
global.init = init;
global.queryTags = queryTags;
global.readTag = readTag;
global.writeTag = writeTag;
global.getFeatures = getFeatures;
global.setTag = setTag;
global.deleteTag = deleteTag;
}(this));
exports.ROT = ROT;
return exports.ROT;
})(this);

Просмотреть файл

@ -1,209 +0,0 @@
(function(exports){
"use strict";
var ROT = {};
var baseurl = "http://10.0.0.3:8080";
//var baseurl = "http://10.251.38.229:8080";
var allUuids = [];
var allThings = {};
var allFeatures = {}
var allTags = {};
ROT.init = function init(cb) {
superagent.get(baseurl + "/ls", function (err, res) {
console.log("--------------------- ROT init ------------------");
if (err) {
cb(err);
return;
}
allUuids = Object.keys(JSON.parse(res.text));
console.log("ROT got uuids: ", allUuids);
_getAllThings(allUuids, function (err, things) {
allThings = things;
console.log("ROT allThings: ", allThings);
_getAllFeatures(things, function (err, features) {
allFeatures = features;
console.log("ROT allFeatures: ", allFeatures);
_getAllTags(things, function (err, tags) {
allTags = tags;
console.log("ROT allTags: ", allTags);
cb();
});
});
});
});
};
function _getAllThings(uuids, cb) {
var things = {};
var errors = undefined;
var done = 0;
for (var i = 0; i < uuids.length; i++) {
console.log("ROT uuids are ", uuids);
(function() {
var uuid = uuids[i];
superagent.get(baseurl + "/thing/" + uuid, function(err, res) {
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
} else {
var thing = JSON.parse(res.text);
things[uuid] = thing;//things = {uuid1:{}, uuid2:{}};
}
done ++;
if (done === uuids.length) {
cb(errors, things);
}
});
})();
}
};
function _getAllFeatures(things, cb) {
var features = {};
var errors = undefined;
var done = 0;
for (var uuid in things) {
(function(uuid) {
var thing = things[uuid];
superagent.get(thing['localURL'] + "/features/", function(err, res) {
console.log("--> getAllFeatures: err: ", err, " res.text: ", res.text);
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
} else {
features[uuid] = res.text;
}
done ++;
if (done === Object.keys(things).length)
cb(errors, features);
});
})(uuid);
}
};
function _getAllTags(things, cb) {
var tags = {};
var errors = undefined;
var done = 0;
for (var uuid in things) {
(function(uuid) {
var thing = things[uuid];
superagent.get(thing['localURL'] + "/tags/", function(err, res) {
console.log("--> getAllTags: err: ", err);
if (err) {
if (errors === undefined)
errors = [];
errors.push(err);
} else {
var tagsResp = JSON.parse(res.text);
console.log("Got tagsResp: ", tagsResp, " for thing: ", thing);
// merge tag lists
for (var tagName in tagsResp) {
if (JSON.parse(tagsResp[tagName]).url !== undefined) {
tags[tagName] = JSON.parse(tagsResp[tagName]).url;
}
if (JSON.parse(tagsResp[tagName]).val !== undefined) {
tags[tagName] = JSON.parse(tagsResp[tagName]).val;
}
}
}
done ++;
if (done === Object.keys(things).length)
cb(errors, tags);
});
})(uuid);
}
};
ROT.setTag = function setTag(uuid, feature, tag, cb) {
var data = {"url":JSON.parse(allFeatures[uuid])[feature].url, "feature":feature};
if (allFeatures[uuid] === undefined) {
cb("No such uuid: " + uuid + " :( in allFeatures:" + allFeatures);
} else if (JSON.parse(allFeatures[uuid])[feature] === undefined) {
cb("No such feature: " + feature + " for uuid: " + uuid + " :(");
} else if (tag in allTags) {
cb("Tag already used: " + tag + " :(");
} else {
var url = allThings[uuid].localURL + "/tags/" + tag;
superagent.put(url)
.send(data)
.end(function(res) {
allTags[tag] = JSON.parse(allFeatures[uuid])[feature].url;
if (res.ok) {
cb();
} else {
cb(res.text);
}
});
}
};
ROT.writeTag = function writeTag(tag, data, cb) {
var tagData = allTags[tag];
if (tagData === undefined) {
cb(undefined, "No such tag: " + tag + " :(");
} else if (tagData === undefined) {
cb(undefined, "No url for tag: " + tag + " :(");
} else if (_isValidURL(tagData)){
console.log("valid tag is:", tagData)
superagent.put(tagData)
.send(data)
.end(function(res){
console.log("callback is ", cb);
cb(res.text, !res.ok);
});
} else {
return tagData;
}
};
ROT.readTag = function readTag(tag, cb) {
var tagData = allTags[tag];
if (tagData === undefined) {
cb(undefined, "ROT No such tag: " + tag + " :(");
} else if (tagData === undefined) {
cb(undefined, "ROT No url for tag: " + tag + " :(");
} else if (_isValidURL(tagData)) {
superagent
.get(tagData)
.end(function(res){
console.log("res is ", res);
cb(res.text);
});
} else {
return tagData;
}
};
ROT.deleteTag = function deleteTag(tag, cb) {
if (allTags[tag] == undefined) {
cb("No such tag: " + tag + " :(");
} else {
delete allTags[tag];
cb(); // no error
}
};
ROT.queryTags = function queryTags(tags, cb) {
// ["tag1", "tag2"], cb (resp, err)); where resp: {"tag1": ?, "tag2": ?}
var resp = {};
for (var i = 0; i < tags.length; i++) {
resp[tags[i]] = allTags[tags[i]];
}
cb(resp); // no error
};
function _isValidURL(url){
var RegExp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if(RegExp.test(url)){
return true;
} else {
return false;
}
}
exports.ROT = ROT;
return exports.ROT;
})(this);