Commit 1a83ca16 authored by Eduardo L. Buratti's avatar Eduardo L. Buratti

Add initial implementation source code

parent 80e47b2c
'use strict';
var gulp = require('gulp');
var gutil = require('gulp-util');
var raml = require('gulp-raml');
var rename = require('gulp-rename');
var jshint = require('gulp-jshint');
var size = require('gulp-size');
var jscs = require('gulp-jscs');
var stylish = require('gulp-jscs-stylish');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var nodemon = require('gulp-nodemon');
var path = require('path');
var raml2html = require('raml2html');
var through = require('through2');
var yaml = require('js-yaml');
var map = require('map-stream');
var srcFiles = [
'src/**/*.js',
'index.js',
'gulpfile.js',
'test/**/*.js'
];
function handleError(err) {
console.error(err.toString());
process.exit(1);
}
function exitOnError(type) {
return map(function(file, callback) {
if (!file[type].success) {
process.exit(1);
}
callback(null, file);
});
}
function generateDoc(options) {
var simplifyMark = function(mark) {
if (mark) {
mark.buffer = mark.buffer
.split('\n', mark.line + 1)[mark.line]
.trim();
}
};
if (!options) {
options = {};
}
switch (options.type) {
case 'json':
options.config = {
template: function(obj) {
return JSON.stringify(obj, null, 2);
}
};
break;
case 'yaml':
options.config = {
template: function(obj) {
return yaml.safeDump(obj, {
skipInvalid: true
});
}
};
break;
default:
options.type = 'html';
if (!options.config) {
options.config = raml2html.getDefaultConfig(
options.https,
options.template,
options.resourceTemplate,
options.itemTemplate
);
}
}
if (!options.extension) {
options.extension = '.' + options.type;
}
var stream = through.obj(function(file, enc, done) {
var fail = function(message) {
done(new gutil.PluginError('raml2html', message));
};
if (file.isBuffer()) {
var cwd = process.cwd();
process.chdir(path.resolve(path.dirname(file.path)));
raml2html
.render(file.contents, options.config)
.then(function(output) {
process.chdir(cwd);
stream.push(new gutil.File({
base: file.base,
cwd: file.cwd,
path: gutil.replaceExtension(
file.path, options.extension),
contents: new Buffer(output)
}));
done();
},
function(error) {
process.chdir(cwd);
simplifyMark(error.context_mark);
simplifyMark(error.problem_mark);
process.nextTick(function() {
fail(JSON.stringify(error, null, 2));
});
}
);
}
else if (file.isStream()) {
fail('Streams are not supported: ' + file.inspect());
}
else if (file.isNull()) {
fail('Input file is null: ' + file.inspect());
}
});
return stream;
}
gulp.task('raml', function() {
gulp.src('specs/*.raml')
.pipe(raml())
.pipe(raml.reporter('default'))
.pipe(exitOnError('raml'));
});
gulp.task('doc', function() {
return gulp.src('specs/*.raml')
.pipe(generateDoc())
.on('error', handleError)
.pipe(rename({ extname: '.html' }))
.pipe(gulp.dest('doc/build'));
});
gulp.task('pre-test', function() {
return gulp.src(['src/**/*.js'])
.pipe(istanbul())
.pipe(istanbul.hookRequire());
});
gulp.task('test', ['pre-test'], function() {
return gulp.src('test/**/*.spec.js', { read: false })
.pipe(mocha({
require: ['./test/common.js'],
reporter: 'spec',
ui: 'bdd',
recursive: true,
colors: true,
timeout: 60000,
slow: 300,
delay: true
}))
.pipe(istanbul.writeReports())
.once('error', function() {
process.exit(1);
})
.once('end', function() {
process.exit();
});
});
gulp.task('lint', function() {
return gulp.src(srcFiles)
.pipe(jshint())
.pipe(jscs())
.pipe(stylish.combineWithHintResults())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(size())
.pipe(exitOnError('jshint'));
});
gulp.task('check', ['raml', 'lint', 'test']);
gulp.task('develop', function() {
return nodemon({
script: 'index.js',
ext: 'js',
tasks: ['lint']
});
});
#!/usr/bin/env node
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
// Add the ./src directory to require's search path to facilitate import
// modules later on (avoiding the require('../../../../module') problem).
require('app-module-path').addPath(__dirname + '/src');
// external libraries
const osprey = require('osprey');
const express = require('express');
const path = require('path');
const ramlParser = require('raml-parser');
// connect to mongodb
const mongo = require('core/mongo');
mongo.connect('mongodb://pyke/blend');
// create a new express app
const app = module.exports = express();
// load router
const router = require('api/router-v1.js');
// parse the RAML spec and load osprey middleware
ramlParser.loadFile(path.join(__dirname, 'specs/blendb-api-v1.raml'))
.then(raml => {
app.use('/v1',
osprey.security(raml),
osprey.server(raml),
router);
if (!module.parent) {
let port = process.env.PORT || 3000;
app.listen(port);
if (app.get('env') === 'development') {
console.log('Server listening on port ' + port + '.');
}
}
else {
// signalize to the test suite that the server is ready to be tested
app.ready = true;
}
},
err => {
console.error('RAML Parsing Error: ' + err.message);
process.exit(1);
});
This diff is collapsed.
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
const mongo = require('core/mongo');
class Collect {
write(req, res, next) {
let collection = mongo.db.collection('raw.' + req.params.class);
if ('_id' in req.body) {
res.status(400)
.json({ message: 'Property named \'_id\' is protected.' });
return;
}
collection.insertOne(req.body, function (err, r) {
if (err) {
res.status(500)
.json({ message: 'Error while writing to the database.' });
return;
}
res.status(200).json({ _id: r.insertedId });
});
}
}
module.exports = new Collect();
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
const aggregator = require('core/aggregator');
class Data {
read(req, res, next) {
let metrics = req.query.metrics.split(',');
let dimensions = req.query.dimensions.split(',');
aggregator.query(metrics, dimensions, (err, data) => {
if (err) {
console.error(err);
res.status(500).json({ message: 'Query execution failed ' +
'because of an unknown error.' });
return;
}
res.json({ data });
});
}
}
module.exports = new Data();
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
const osprey = require('osprey');
// import controllers
const data = require('./controllers/data');
const collect = require('./controllers/collect');
const router = module.exports = osprey.Router();
router.get('/data', data.read);
router.post('/collect/{class}', collect.write);
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
const mongo = require('core/mongo');
class Aggregator {
query(metrics, dimensions, callback) {
this.findClosestAggregate(metrics, dimensions, (err, aggr) => {
if (err) {
callback(err);
return;
}
callback(null, null);
});
}
findClosestAggregate(metrics, dimensions, callback) {
var aggregates = mongo.db.collection('meta.aggregates');
aggregates.find({
metrics: {
$all: metrics
},
dimensions: {
$all: dimensions
}
}).toArray(function(err, result) {
if (err) {
callback(err);
return;
}
if ((!result) || (result.length <= 0)) {
callback('Query could not be aswered, no aggregate available.');
return;
}
// fetch the closest aggregation available
let closestAggr;
for (const aggr of result) {
if ((!closestAggr) ||
(aggr.dimensions.length < closestAggr.dimensions.length)) {
closestAggr = aggr;
}
}
callback(null, closestAggr);
});
}
}
module.exports = new Aggregator();
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
const MongoClient = require('mongodb').MongoClient;
class Mongo {
constructor() {
this.db = undefined;
}
connect(connectionString) {
MongoClient.connect(connectionString, (err, db) => {
if (err) {
console.error(err);
return;
}
this.db = db;
});
}
}
module.exports = new Mongo();
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of blendb.
*
* blendb is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* blendb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with blendb. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
class Serializer {
dump(obj) {
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'function') {
return value.toString();
}
return value;
});
}
load(str) {
return JSON.parse(str, (key, value) => {
if (key === '') {
return value;
}
if (typeof value === 'string') {
let rfunc = /function[^\(]*\(([^\)]*)\)[^\{]*{([^\}]*)\}/;
let match = value.match(rfunc);
if (match) {
let args = match[1].split(',')
.map((arg) => arg.replace(/\s+/, ''));
return new Function(args, match[2]);
}
}
return value;
});
}
}
module.exports = new Serializer();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment