Various updates.

This commit is contained in:
Julien Fontanet 2013-07-16 13:51:44 +02:00
parent c611cccc06
commit c650a92a1d
3 changed files with 141 additions and 80 deletions

View File

@ -3,19 +3,6 @@ var Q = require('q');
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// @todo Maybe we should generalize the getter methods (get,
// findWhere, where) to two methods: get([properties]) &
// first([properties]).
//
// Each of these methods accept optionnal properties to filter its
// results.
//
// get() returns any models that match while first() returns only the
// one.
//
// These method should also accept a scalar value as a matching value
// for the “id” property.
// @todo Add events. // @todo Add events.
function Collection(models) function Collection(models)
{ {

View File

@ -79,22 +79,26 @@ function json_api_call(session, message)
// JSON-RPC over WebSocket. // JSON-RPC over WebSocket.
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// @todo Port should be configurable. xo.on('started', function () {
new (require('ws').Server)({'port': 8080}).on('connection', function (socket) { // @todo Port should be configurable.
var session = new Session(xo); var server = new (require('ws').Server)({'port': 8080});
session.once('close', function () {
socket.close();
});
socket.on('message', function (request) { server.on('connection', function (socket) {
json_api_call(session, request).then(function (response) { var session = new Session(xo);
socket.send(response); session.once('close', function () {
}).done(); socket.close();
}); });
// @todo Ugly inter dependency. socket.on('message', function (request) {
socket.once('close', function () { json_api_call(session, request).then(function (response) {
session.close(); socket.send(response);
}).done();
});
// @todo Ugly inter dependency.
socket.once('close', function () {
session.close();
});
}); });
}); });
@ -102,61 +106,67 @@ new (require('ws').Server)({'port': 8080}).on('connection', function (socket) {
// JSON-RPC over TCP. // JSON-RPC over TCP.
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
require('net').createServer(function (socket) { xo.on('started', function () {
var session = new Session(xo); require('net').createServer(function (socket) {
session.on('close', function () { var session = new Session(xo);
socket.end(); // @todo Check it is enough. session.on('close', function () {
}); socket.end(); // @todo Check it is enough.
});
var length = null; // Expected message length. var length = null; // Expected message length.
var buffer = new Buffer(1024); // @todo I hate hardcoded values! var buffer = new Buffer(1024); // @todo I hate hardcoded values!
socket.on('data', function (data) { socket.on('data', function (data) {
data.copy(buffer); data.copy(buffer);
// Read the message length. // Read the message length.
if (!length) if (!length)
{ {
var i = _.indexOf(buffer, 10); var i = _.indexOf(buffer, 10);
if (-1 === i) if (-1 === i)
{
return;
}
length = +(buffer.toString('ascii', 0, i));
// If the length is NaN, we cannot do anything except
// closing the connection.
if (length !== length)
{
session.close();
return;
}
buffer = buffer.slice(i + 1);
}
// We do not have received everything.
if (buffer.length < length)
{ {
return; return;
} }
length = +(buffer.toString('ascii', 0, i)); json_api_call(
session,
buffer.slice(0, length).toString()
).then(function (response) {
// @todo Handle long messages.
socket.write(response.length +'\n'+ response);
}).done();
// If the length is NaN, we cannot do anything except // @todo Check it frees the memory.
// closing the connection. buffer = buffer.slice(length);
if (length !== length)
{
session.close();
return;
}
buffer = buffer.slice(i + 1); length = null;
} });
// We do not have received everything. // @todo Ugly inter dependency.
if (buffer.length < length) socket.once('close', function () {
{ session.close();
return; });
} }).listen(1024); // @todo Should be configurable.
});
json_api_call( //////////////////////////////////////////////////////////////////////
session,
buffer.slice(0, length).toString()
).then(function (response) {
// @todo Handle long messages.
socket.write(response.length +'\n'+ response);
}).done();
// @todo Check it frees the memory. xo.start();
buffer = buffer.slice(length);
length = null;
});
// @todo Ugly inter dependency.
socket.once('close', function () {
session.close();
});
}).listen(1024); // @todo Should be configurable.

View File

@ -33,6 +33,11 @@ var check = function () {
// Models // Models
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
var Server = Model.extend({
'validate': function () {
},
});
// @todo We could also give a permission level to tokens (<= // @todo We could also give a permission level to tokens (<=
// user.permission). // user.permission).
var Token = Model.extend({ var Token = Model.extend({
@ -108,15 +113,26 @@ var User = Model.extend({
}, },
}); });
var Server = Model.extend({ var Pool = Model.extend({});
'validate': function () {
}, var Host = Model.extend({});
});
var VM = Model.extend({});
var Network = Model.extend({});
var SR = Model.extend({});
var VDI = Model.extend({});
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Collections // Collections
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
var Servers = Collection.extend({
'model': Server,
});
var Tokens = Collection.extend({ var Tokens = Collection.extend({
'model': Token, 'model': Token,
@ -148,8 +164,28 @@ var Users = Collection.extend({
} }
}); });
var Servers = Collection.extend({ var Pools = Collection.extend({
'model': Server, 'model': Pool,
});
var Hosts = Collection.extend({
'model': Host,
});
var VMs = Collection.extend({
'model': VM,
});
var Networks = Collection.extend({
'model': Network,
});
var SRs = Collection.extend({
'model': SR,
});
var VDIs = Collection.extend({
'model': VDI,
}); });
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -161,10 +197,15 @@ function Xo()
return new Xo(); return new Xo();
} }
//--------------------------------------
// Main objects (@todo should be persistent).
this.servers = new Servers(); this.servers = new Servers();
this.tokens = new Tokens(); this.tokens = new Tokens();
this.users = new Users(); this.users = new Users();
// Temporary user, used for tests while the collection are not
// persistent.
this.users.add({ this.users.add({
'email': 'bob@gmail.com', 'email': 'bob@gmail.com',
'pw_hash': '$2a$10$PsSOXflmnNMEOd0I5ohJQ.cLty0R29koYydD0FBKO9Rb7.jvCelZq', 'pw_hash': '$2a$10$PsSOXflmnNMEOd0I5ohJQ.cLty0R29koYydD0FBKO9Rb7.jvCelZq',
@ -184,9 +225,32 @@ function Xo()
self.emit('user.revoked:'+ user_id); self.emit('user.revoked:'+ user_id);
}); });
}); });
//--------------------------------------
// Xen objects.
this.pools = new Pools();
this.hosts = new Hosts();
this.vms = new VMs();
this.networks = new Networks();
this.srs = new SRs();
this.vdis = new VDIs();
// Connecting classes: VIF & PIF, VBD & SR.
} }
require('util').inherits(Xo, require('events').EventEmitter); require('util').inherits(Xo, require('events').EventEmitter);
Xo.prototype.start = function () {
// @todo Connect to persistent collection.
// @todo Connect to Xen servers & fetch data.
// -------------------------------------
this.emit('started');
};
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
module.exports = Xo; module.exports = Xo;