diff --git a/Dockerfile b/Dockerfile index 6fcc14879f61e607734469eab6bbcedb69b80845..cbcf0373c2251441190111c0696aebb3f7b75644 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,7 @@ RUN npm install # Create public directory RUN mkdir -p /usr/src/app/public +RUN mkdir -p /usr/src/app/nodes # Bundle app source COPY . /usr/src/app diff --git a/config.js b/config.js index 6b232a5a81f513a6d7a9f514d607ede0f89287a4..f623dde05e42af5e0311e132d16c0eb5225c8586 100644 --- a/config.js +++ b/config.js @@ -26,7 +26,7 @@ module.exports = { databaseURL: 'mongodb://localhost:27017/', port: 4000, secret: 'longsecretislong', - logLevel: 'verbose', // possible values: error, warn, info, verbose or debug + logLevel: 'debug', // possible values: error, warn, info, verbose or debug logFile: 'log.txt', admin: { username: 'admin', diff --git a/models/node.js b/models/node.js new file mode 100644 index 0000000000000000000000000000000000000000..340aa107a832e6da41ed6fb55885c7abcd1eadd0 --- /dev/null +++ b/models/node.js @@ -0,0 +1,83 @@ +/** + * File: node.js + * Author: Markus Grigull <mgrigull@eonerc.rwth-aachen.de> + * Date: 21.06.2017 + * + * This file is part of VILLASweb-backend. + * + * VILLASweb-backend 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. + * + * VILLASweb-backend 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 VILLASweb-backend. If not, see <http://www.gnu.org/licenses/>. + ******************************************************************************/ + +// include +var mongoose = require('mongoose'); +var fs = require('fs'); + +var logger = require('../utils/logger'); + +var Schema = mongoose.Schema; + +// node model +var nodeSchema = new Schema({ + name: { type: String, required: true, unique: true, set: function(name) { this._name = this.name; return name; } }, + endpoint: { type: String, required: true, unique: true }, + config: { type: Schema.Types.Mixed, default: {} }, + simulators: [{ type: Schema.Types.Mixed, default: [] }] +}); + +nodeSchema.post('save', function() { + // remove old file + if (this._name != null) { + var oldFile = 'nodes/' + this._name + '.conf'; + + fs.stat(oldFile, function(err, stat) { + if (err) { + logger.info('Old node configuration missing', err); + return; + } + + if (stat.isFile()) { + fs.unlink(oldFile, function(err) { + if (err) { + logger.warn('Unable to delete old node configuration', err); + } + }); + } + }); + } + + // create configuration file + var port = 12000; + + var nodes = this.simulators.map(simulator => { + return "\t" + simulator.name + " = {\n\t\ttype = \"websocket\",\n\t\tvectorize = 1\n\t},\n" + + "\t" + simulator.name + "_RECV = {\n\t\ttype = \"socket\",\n\t\tlayer = \"udp\",\n\t\tlocal = \"*:" + (port++) + "\",\n\t\tremote = \"127.0.0.1:" + (port++) + "\"\n\t}"; + }); + + var paths = this.simulators.map(simulator => { + return "\t{ in = \"" + simulator.name + "_RECV\", out = \"" + simulator.name + "\" }"; + }); + + var content = "nodes = {\n" + nodes.join(",\n") + "\n};\n\npaths = (\n" + paths.join(",\n") + "\n);\n"; + + fs.writeFile('nodes/' + this.name + '.conf', content, function(err) { + if (err) { + logger.error('Unable to write node configuration', err); + return; + } + + logger.log('info', 'Node configuration file written'); + }); +}); + +module.exports = mongoose.model('Node', nodeSchema); diff --git a/models/simulationModel.js b/models/simulationModel.js index 64233df9f2207f4a503d1eb341f8bd3e75d774bd..08af6bdc2997448bb707850fa9ec1feef946ffa7 100644 --- a/models/simulationModel.js +++ b/models/simulationModel.js @@ -27,7 +27,7 @@ var Schema = mongoose.Schema; // simulation model model var simulationModelSchema = new Schema({ name: { type: String, required: true }, - simulator: { type: Schema.Types.ObjectId, ref: 'Simulator', required: true }, + simulator: { type: Schema.Types.Mixed, required: true }, length: { type: Number, default: 1 }, mapping: [{ type: String, default: [] }], simulation: { type: Schema.Types.ObjectId, ref: 'Simulation', required: true } diff --git a/models/simulator.js b/models/simulator.js index 8cc2c92245c10ec0750bfa57930eeab65d5a5ac2..1d561f4a18613ca44d2d7f92988218fd2ed3f4ba 100644 --- a/models/simulator.js +++ b/models/simulator.js @@ -27,8 +27,7 @@ // simulator model var simulatorSchema = new Schema({ name: { type: String, required: true }, - running: { type: Boolean, default: false }, - endpoint: { type: String, required: true } + config: { type: Schema.Types.Mixed, default: {} } }); module.exports = mongoose.model('Simulator', simulatorSchema); diff --git a/routes/nodes.js b/routes/nodes.js new file mode 100644 index 0000000000000000000000000000000000000000..d0ea99194fd3a88ea98c371ec7c560e3e2c7285e --- /dev/null +++ b/routes/nodes.js @@ -0,0 +1,114 @@ +/** + * File: nodes.js + * Author: Markus Grigull <mgrigull@eonerc.rwth-aachen.de> + * Date: 21.06.2017 + * + * This file is part of VILLASweb-backend. + * + * VILLASweb-backend 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. + * + * VILLASweb-backend 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 VILLASweb-backend. If not, see <http://www.gnu.org/licenses/>. + ******************************************************************************/ + +// include +var express = require('express'); + +var logger = require('../utils/logger'); + +// models +var Node = require('../models/node'); + +// create router +var router = express.Router(); + +// routes +router.get('/nodes', function(req, res) { + // get all nodes + Node.find(function(err, nodes) { + if (err) { + logger.error('Unable to receive nodes', err); + return res.status(400).send(err); + } + + res.send({ nodes: nodes }); + }); +}); + +router.post('/nodes', function(req, res) { + // create new node + var node = new Node(req.body.node); + + node.save(function(err) { + if (err) { + logger.error('Unable to create node', err); + return res.status(400).send(err); + } + + res.send({ node: node }); + }); +}); + +router.put('/nodes/:id', function(req, res) { + // get node + Node.findOne({ _id: req.params.id }, function(err, node) { + if (err) { + logger.log('verbose', 'PUT Unknown node for id: ' + req.params.id); + return res.status(400).send(err); + } + + // update all properties + for (property in req.body.node) { + node[property] = req.body.node[property]; + } + + // save the changes + node.save(function(err) { + if (err) { + logger.error('Unable to save node', node); + return res.status(500).send(err); + } + + res.send({ node: node }); + }); + }); +}); + +router.get('/nodes/:id', function(req, res) { + Node.findOne({ _id: req.params.id }, function(err, node) { + if (err) { + logger.log('verbose', 'GET Unknown node for id: ' + req.params.id); + return res.status(400).send(err); + } + + res.send({ node: node }); + }); +}); + +router.delete('/nodes/:id', function(req, res) { + Node.findOne({ _id: req.params.id }, function(err, node) { + if (err) { + logger.log('verbose', 'DELETE Unknown node for id: ' + req.params.id); + return res.status(400).send(err); + } + + node.remove(function(err) { + if (err) { + logger.error('Unable to remove node', node); + return res.status(500).send(err); + } + + res.send({}); + }); + }); +}); + +module.exports = router; diff --git a/server.js b/server.js index b944a7732cb301c0d923419ab29d40fb3edb903b..e2fd149dfad7d512543fdf84e555932492fdfec3 100644 --- a/server.js +++ b/server.js @@ -38,6 +38,7 @@ var simulationModels = require('./routes/simulationModels'); var simulators = require('./routes/simulators'); var upload = require('./routes/upload'); var files = require('./routes/files'); +var nodes = require('./routes/nodes'); var User = require('./models/user'); @@ -93,8 +94,10 @@ app.use('/api/v1', simulationModels); app.use('/api/v1', simulators); app.use('/api/v1', upload); app.use('/api/v1', files); +app.use('/api/v1', nodes); app.use('/public', express.static(__dirname + '/public')); +app.use('/nodes', express.static(__dirname + '/nodes')); // catch 404 and forward to error handler app.use(function(req, res, next) {