diff --git a/.gitignore b/.gitignore index 57a123473780458b523e29b006d60602a8e201f0..40bc57be252f5cfd19a9fad5a7fc841f65f25dc2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ node_modules/ config.js +config_test.js logs/ *.swp +nohup.out +package-lock.json +coverage/ +.nyc_output/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..d50a056e2f15105029c81a3c1b16b437bed9490f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,26 @@ +stages: + - test + +services: + - postgres +variables: + NODE_ENV: 'test' + +before_script: + - npm install --global mocha gulp + - npm install + - apt-get update + - apt-get install postgresql-contrib -y + - /etc/init.d/postgresql start + - su postgres -c "createuser -drS root" #create posgresql user with permission to create databases and roles +run_tests: + stage: test + script: + - mv config_test.js.example config_test.js + - gulp test + tags: + - node + - postgres + cache: + paths: + - node_modules/ diff --git a/config.js.example b/config.js.example index b2deb06c586c934a283170344e7321bf42f22b2e..1846bae3e073ab0b34827a5bcc14a28e7e9aaff5 100644 --- a/config.js.example +++ b/config.js.example @@ -8,33 +8,8 @@ config.db_config = { port: 5432 }; -config.mail = { - port: 25 - , host: 'localhost' - , ignoreTLS: true - , secure: false - , from: 'noreply@simmc.c3sl.ufpr.br' -}; - -config.report_config = { - imagesPath: './reports/reports/images/' - , outputPath: './tmp/reports' -}; - -config.alert_config = { - alertsPath: '/home/simmc/simmc/scripts/alerts/' -}; - -config.fqdn = 'simmc.c3sl.ufpr.br'; - -config.agentVersion = 1.0; - -config.secret = '123mudar'; +config.webservice_config = { + ip: "127.0.0.1" +} -// Uncomment to enable memcached -// -// config.memcached = { -// server: 'localhost:11211', -// options: { retries: 1, timeout: 1000, poolSize: 1 }, -// lifetime: 3600 // 1 hour in seconds -// }; +config.agentVersion = 0.0; diff --git a/config_test.js.example b/config_test.js.example new file mode 100644 index 0000000000000000000000000000000000000000..3a80276e7414581f10a2b34d52403530016b77d5 --- /dev/null +++ b/config_test.js.example @@ -0,0 +1,15 @@ +var config = module.exports = {}; + +config.db_config = { + user: 'test', + password: 'test', + database: 'test', + host: 'localhost', + port: 5432 +}; + +config.webservice_config = { + ip: "127.0.0.1" +} + +config.agentVersion = 0.0; diff --git a/config_test_error.js b/config_test_error.js new file mode 100644 index 0000000000000000000000000000000000000000..7e9c26ef68f9762b47c9a77b652e9fecdb6b2ebd --- /dev/null +++ b/config_test_error.js @@ -0,0 +1,16 @@ +var config = module.exports = {}; + +config.db_config = { + user: 'error', + password: 'error', + database: 'error', + host: 'localhost', + port: 5432 +}; + +config.webservice_config = { + ip: "127.0.0.1" +} + + +config.agentVersion = 0.0; diff --git a/database/create/schema/bd.sql b/database/create/schema/bd.sql new file mode 100755 index 0000000000000000000000000000000000000000..f3cfd94af79fb59ecc390892c4a738b22c26dc6d --- /dev/null +++ b/database/create/schema/bd.sql @@ -0,0 +1,100 @@ +START TRANSACTION; + + +CREATE TABLE session( + sessionSer BIGINT, + SessionNum INT, + Comment VARCHAR(254), + HstryUserName VARCHAR(32), + HstryTimeStamp TIMESTAMP, + HstryDateTime TIMESTAMP, + HstryTaskName VARCHAR(32), + CourseSer BIGINT, + CONSTRAINT pk_session primary key(sessionSer) +); + +CREATE TABLE SessionProcedurePart( + RadiationSer BIGINT, + ImageType VARCHAR(32), + SequenceNumber INT, + SessionProcedurePartSer BIGINT, + AcqAdjustment FLOAT, + AutoSave INT, + DoseAccumulation INT, + Continuous INT, + BeamOff INT, + DeviationImage INT, + DevEnergy INT, + DevDoseRate INT, + DevGeometry INT, + JawState FLOAT, + DevCollX1 FLOAT, + DevCollX2 FLOAT, + DevCollY1 FLOAT, + DevCollY2 FLOAT, + MUSubtraction INT, + AcquisitionMode VARCHAR(64), + HstryUserName VARCHAR(32), + HstryTimeStamp TIMESTAMP, + HstryDateTime TIMESTAMP, + HstryTaskName VARCHAR(32), + SessionProcedureSer BIGINT, + ImageModality VARCHAR(16), + RTPlanSer BIGINT, + CONSTRAINT pk_SessionProcedurePart primary key(SessionProcedurePartSer) +); + +CREATE TABLE Course( + CourseSer BIGINT, + PatientSer BIGINT, + CourseId VARCHAR(16), + StartDateTime TIMESTAMP, + ClinicalStatus VARCHAR(16), + CompletedByUserName VARCHAR(32), + CompletedDateTime TIMESTAMP, + Comment VARCHAR(254), + ClinicalProtocolDir VARCHAR(254), + HstryUserName VARCHAR(32) not null, + HstryTimeStamp TIMESTAMP, + HstryDateTime TIMESTAMP, + HstryTaskName VARCHAR(32), + TransactionId VARCHAR(255), + CONSTRAINT pk_Course primary key(CourseSer) +); + +CREATE TABLE MachineUse( + Pacient_id VARCHAR(254), + Pacient_name VARCHAR(254), + Energy VARCHAR(254), + Use_date TIMESTAMP, + Field_name VARCHAR(254), + Machine_id VARCHAR(254), + Fk_agent int +); + +CREATE TABLE Agent ( + Id BIGSERIAL primary key, + Hospital_name VARCHAR(16), + Geo_long FLOAT, + Geo_lat FLOAT +); + + +CREATE MATERIALIZED VIEW ResumeUsesMonth AS + SELECT date_trunc('month', use_date) AS date, count(*) as uses, fk_agent + FROM machineuse + GROUP BY date, fk_agent; + +CREATE MATERIALIZED VIEW ResumeUsesDay AS + SELECT date_trunc('day', use_date) AS date, count(*) as uses, fk_agent + FROM machineuse + GROUP BY date, fk_agent; + + +ALTER TABLE session ADD CONSTRAINT fk_session_1 FOREIGN KEY(CourseSer) REFERENCES Course(CourseSer); +ALTER TABLE SessionProcedurePart ADD CONSTRAINT fk_SessionProcedurePart_2 FOREIGN KEY(SessionProcedurePartSer) REFERENCES session(sessionSer); +ALTER TABLE SessionProcedurePart ADD CONSTRAINT unique_SessionProcedurePart UNIQUE(SessionProcedurePartSer); + +ALTER TABLE MachineUse ADD CONSTRAINT Fk_Agent FOREIGN KEY(Fk_Agent) REFERENCES Agent(Id); + +COMMIT; diff --git a/database/create_database.sh b/database/create_database.sh new file mode 100755 index 0000000000000000000000000000000000000000..4f48ea1936d6d698b4c1580a141028a89c13fda5 --- /dev/null +++ b/database/create_database.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Copyright (C) 2007-2013 Centro de Computacao Cientifica e Software Livre +# Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR +# +# This file is part of database +# +# database 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 2 +# of the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. + + +#DB_LINK_LOCATION=/usr/share/postgresql/9.1/extension/dblink.sql +#DATABASE_DIR=$(pwd) + +DATABASE_DIR="`dirname \"$0\"`" +DATABASE_DIR="`( cd \"$DATABASE_DIR\" && pwd )`" +SCHEMA_DIR="${DATABASE_DIR}/create/schema/" +DATA_DIR="${DATABASE_DIR}/create/data/" + + + +function print_help() { + echo -e "" + echo -e "usage: $0 database_name" + echo -e "" +} + +if [[ $1 != "-"* && $# != "0" ]]; then + DB_NAME=$1 + shift +else + print_help + exit 1 +fi + +function error_exit() { + dropdb $DB_NAME + exit 1 +} + +# check if db exists3 +if psql -lqt | cut -d \| -f 1 | grep -qw "$DB_NAME"; then + echo "Database with name $DB_NAME already exists."; + read -p "Drop Database and create new one? (Warning, this will delete all existing data) [y/N]:" yn + case $yn in + y | Y | yes | YES ) + echo "Dropping database $DB_NAME" + dropdb $DB_NAME + ;; + * ) + echo "Exiting script." + exit 0 + ;; + esac +fi + +# create db +echo "INFO: Creating database: $DB_NAME"; +createdb $DB_NAME + + +# creating database tables and structure +echo "INFO: Creating database tables and structure"; +for file in $(ls -B "${SCHEMA_DIR}"); do + echo "--- Executing: $file"; + psql -d $DB_NAME -f $SCHEMA_DIR$file || error_exit +done diff --git a/database/create_user.sh b/database/create_user.sh new file mode 100755 index 0000000000000000000000000000000000000000..1ed5f05284c7ece7ad8af11872ba1242c2c534c0 --- /dev/null +++ b/database/create_user.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +USERNAME= +PASSWORD= +SCHEMA_NAME= +PRIVILAGES="SELECT, INSERT, UPDATE, DELETE" + + + +function print_help() { + echo -e "" + echo -e "usage: $0 username password database_name " + echo -e "" +} + + +if [ $# -ne 3 ] + then + print_help + exit 1 +fi + +USERNAME=$1 +PASSWORD=$2 +DATABASE_NAME=$3 +SCHEMA_NAME="public" + +psql -d "$DATABASE_NAME" -tAc "SELECT 1 FROM pg_roles WHERE rolname='test'" | grep -q 1 + +HAS_USER=$? +if [[ "$HAS_USER" -eq 0 ]]; then + echo "User with name $USERNAME already exists."; + if psql -lqt | cut -d \| -f 1 | grep -qw "$DB_NAME"; then + read -p "Revoke all privilages of $USERNAME on $DATABASE_NAME? [y/N]:" yn + case $yn in + y | Y | yes | YES ) + echo "Dropping user $USERNAME" + psql -d "$DATABASE_NAME" -c "REVOKE ALL ON DATABASE \"$DATABASE_NAME\" FROM \"$USERNAME\";" + psql -d "$DATABASE_NAME" -c "REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA \"$SCHEMA_NAME\" FROM \"$USERNAME\";" + ;; + * ) + echo "Exiting script." + exit 0 + ;; + esac + fi + +else + CREATE_QUERY="CREATE USER \"$USERNAME\" WITH PASSWORD '${PASSWORD}';" + psql -d "$DATABASE_NAME" -c "${CREATE_QUERY}" +fi + +GRANT_QUERY="GRANT ${PRIVILAGES} ON ALL TABLES IN SCHEMA \"${SCHEMA_NAME}\" to \"${USERNAME}\";" +psql -d "${DATABASE_NAME}" -c "${GRANT_QUERY}" diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000000000000000000000000000000000000..8ac6a94562c283b0d68cdd9a529f646d0f7b56af --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,90 @@ +/*jshint esversion:6*/ +const gulp = require('gulp'); +const jshint = require('gulp-jshint'); +const shell = require('gulp-shell'); +const mocha = require('gulp-mocha'); +const istanbul = require('gulp-istanbul'); + +var js_files = "**/*.js"; + +const app_state = (process.env.NODE_ENV || 'development').trim().toLowerCase(); + +//dev config +var dev_config_file = './config.js'; + +var test_config_file = './config_test.js'; + +//var config = require(configFile); + +// define the default task and add the watch task to it +gulp.task('default', ['run','watch']); + +// configure the jshint task +gulp.task('jshint', function() { + return gulp.src([js_files, "!node_modules/**/*.js", "!coverage/*"]) + .pipe(jshint({ + "esversion": 6 + })) + .pipe(jshint.reporter('jshint-stylish')); +}); + +// configure which files to watch and what tasks to use on file changes +gulp.task('watch', function() { + gulp.watch(js_files/*, ['jshint']*/); +}); + +gulp.task('run', function(){ + return gulp.src("*") + .pipe(shell('npm start')); +}); + +//Run as a user with CREATE permission and permission to create users on postgresql +gulp.task('create_database_test', function(){ + + var config = require(test_config_file); + + return gulp.src("database") + .pipe(shell("yes | ./database/create_database.sh " + config.db_config.database)) + .pipe(shell("yes | ./database/create_user.sh " + config.db_config.user + " " + config.db_config.password + " " + config.db_config.database )); +}); + + +gulp.task('pre-test', () => { + return gulp.src(['src/**/*.js']) + .pipe(istanbul({includeUntested: true})) + .pipe(istanbul.hookRequire()); +}); + +gulp.task('test',['create_database_test','pre-test'], function(){ + + gulp.src(['test/**/*.js'], {read: false}) + .pipe(mocha({timeout: 60000})) + .pipe(istanbul.writeReports()) + .pipe(istanbul.enforceThresholds({ + thresholds: { + global: { + statements: 80, + branches: 70, + lines: 80, + functions: 80 + } + } + })) + .on('error', () => { + process.exit(1); + }) + .on('end', () => { + process.exit(); + }); + + + // return gulp.src(['test/*.js']) + // .pipe(mocha({ + // reporter : 'spec' + // })); + +}); + + + +module.exports = gulp; diff --git a/lib/agentbuilder.js b/lib/agentbuilder.js deleted file mode 100644 index 24cb61e90f345951f3d2b660620fd9034952648a..0000000000000000000000000000000000000000 --- a/lib/agentbuilder.js +++ /dev/null @@ -1,35 +0,0 @@ -var exec = require('child_process').exec; - -exports.build = function(id_point, os, proxy, callback) { - var buildScript, - proxyParams = ""; - - if (isNaN(id_point)) { - return callback({error: 'invalid_id_point'}); - } - - if (os === 'windows') - buildScript = __dirname + '/../scripts/build-windows-installer.sh'; - else - buildScript = __dirname + '/../scripts/build-linux-installer.sh'; - - if (proxy) { - // the replace method removes whitespaces that are not allowed in this fields - var host = (proxy.host || '').replace(/ /g, ''), - port = (proxy.port || '').replace(/ /g, ''), - user = (proxy.user || '').replace(/ /g, ''), - pass = (proxy.pass || '').replace(/ /g, ''); - - // check if the port number is actually a number or an empty string - if ( (port !== '') && (isNaN(parseInt(port),10)) ) { - return callback({error: 'invalid_proxy_port'}); - } - - proxyParams = '"'+host+'" "'+port+'" "'+user+'" "'+pass+'"'; - } - - var cmdline = buildScript + ' ' + id_point + ' ' + proxyParams; - exec(cmdline, function (err, stdout, stderr) { - callback(err, stdout); - }); -}; \ No newline at end of file diff --git a/lib/mail.js b/lib/mail.js deleted file mode 100644 index 602c5cd3513833eba09ec440ec80d4f8bff91d15..0000000000000000000000000000000000000000 --- a/lib/mail.js +++ /dev/null @@ -1,37 +0,0 @@ -var nodemailer = require('nodemailer'); -var smtpTransport = require('nodemailer-smtp-transport'); -var htmlToText = require('nodemailer-html-to-text').htmlToText; - -module.exports = function(config) { - - var options = smtpTransport({ - port: config.port - , host: config.host - , ignoreTLS: config.ignoreTLS - , secure: config.secure - }); - - // create reusable transporter object using SMTP transport - var transporter = nodemailer.createTransport(options); - - // set transporter to compile html do text automagically - transporter.use('compile', htmlToText()); - - // NB! No need to recreate the transporter object. You can use - // the same transporter object for all e-mails - - // setup e-mail data with unicode symbols - var mail = { - from: config.from // sender address - }; - - return { - send: function(to, subject, html, callback) { - // send mail with defined transport object - mail.to = to; - mail.subject = subject; - mail.html = html; - transporter.sendMail(mail, callback); - } - }; -}; diff --git a/lib/utils.js b/lib/utils.js deleted file mode 100644 index 59659ae08a646bbcee61be69624b68bb635c22d6..0000000000000000000000000000000000000000 --- a/lib/utils.js +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2012 Centro de Computacao Cientifica e Software Livre - * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR - * - * This file is part of simmc - * - * simmc 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 2 - * of the License, or (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -var crypto = require('crypto'); - -// Returns a filename starting with prefix (if not null) plus a md5-hash -// representing the obj given as argument, with "ext" as extension. -exports.hashFilename = function(prefix, obj, ext) { - var txt = ""; - for (i in obj) { - txt += i + obj[i] - } - var hash = crypto.createHash('md5').update(txt).digest('hex'); - return (prefix? prefix + '_' + hash : hash) + '.' + ext; -}; - -// returns a filename in the format: type project_date(day+month+year+'_'+hours+minutes).ext -exports.reportFilename = function(prefix, ext) { - var date = formatDateReport(new Date()); - return prefix+ '_'+ date + '.' + ext; -}; - -// returns the date in the format day+month+year_hours+minutes -function formatDateReport(date) { - var day = date.getUTCDate(), - month = date.getUTCMonth() + 1, //Months are zero based - year = date.getUTCFullYear(), - hours = date.getHours(), - minutes = date.getMinutes(); - - if (day < 10) day = '0' + day; - if (month < 10) month = '0' + month; - if (hours < 10) hours = '0' + hours; - if (minutes < 10) minutes = '0' + minutes; - - return day + month + year + '_' + hours + minutes; -} - - -// returns the sum of every element in a array or object -exports.sum = function(x) { - var total = 0; - if (x.constructor == Array) { - for (var i=0; i<x.length; i++) { - total += x[i]; - } - } else { - for (var i in x) { - total += x[i]; - } - } - return total; -} - -exports.checkEmail = function(email) { - if (email.length < 4) { - return "Email deve conter pelo menos 4 caracteres."; - } - - if (email.length > 255) { - return "Email deve conter no máximo 255 caracteres."; - } - - if (!email.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)) { - return "Email não está em um formato válido."; - } - - return false; -} diff --git a/middleware/cache.js b/middleware/cache.js deleted file mode 100644 index e8809908bdef74f85be346443811411dee8ec1d9..0000000000000000000000000000000000000000 --- a/middleware/cache.js +++ /dev/null @@ -1,37 +0,0 @@ -module.exports = function (config) { - var memcached = null; - if (config) { // require memcached module only if configured - var Memcached = require('memcached'); - memcached = new Memcached(config.server || 'localhost:11211', config.options || {}); - } - - return { - try: function (req, res, next) { - if (!memcached) { // memcached not configured - next(); - return; - } - - memcached.get(req.url, function (err, data) { - if (err) { - console.log('Memcached error:\n'); - console.log(err); - next(); - } - else if (data) { - if (config.debug) console.log('cached response to '+req.url); - res.status(200).send(data); - } - else { - // provide a method for the route to cache its response - res.cache = function (data, cb) { - if (config.debug) console.log('caching '+req.url); - memcached.set(req.url, data, config.lifetime || 3600, cb || function (err) {}); - } - - next(); - } - }); - } - }; -}; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index cacdd20788a057d68cb3d94fc52698dae4fe108a..0000000000000000000000000000000000000000 --- a/package-lock.json +++ /dev/null @@ -1,480 +0,0 @@ -{ - "name": "webservice-pinsis", - "version": "0.0.0", - "lockfileVersion": 1, - "dependencies": { - "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=" - }, - "ap": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ap/-/ap-0.2.0.tgz", - "integrity": "sha1-rglCYAspkS8NKxTsYMRejzMLYRA=" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "optional": true - }, - "body-parser": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", - "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=" - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "optional": true - }, - "browser-fingerprint": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz", - "integrity": "sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo=" - }, - "buffer-writer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz", - "integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg=" - }, - "bunyan": { - "version": "1.8.10", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.10.tgz", - "integrity": "sha1-IB/t0mxwgLYy9BYHL1OpC5pSmBw=" - }, - "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "optional": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" - }, - "content-type": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" - }, - "cuid": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/cuid/-/cuid-1.3.8.tgz", - "integrity": "sha1-S4deCWm612T37AcGz0T1+wgx9rc=" - }, - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=" - }, - "depd": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", - "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "dtrace-provider": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.3.tgz", - "integrity": "sha1-uhv8ZJMoXM/PxqtpzVxh10wqQ78=", - "optional": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", - "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", - "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE=" - }, - "express": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz", - "integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI=" - }, - "finalhandler": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.3.tgz", - "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk=" - }, - "forwarded": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", - "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=" - }, - "fresh": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", - "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=" - }, - "generic-pool": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.4.3.tgz", - "integrity": "sha1-eAw29p360FpaBF3Te+etyhGk9v8=" - }, - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "optional": true - }, - "http-errors": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz", - "integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc=" - }, - "iconv-lite": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "optional": true - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.3.0.tgz", - "integrity": "sha1-HgOlL9rYOou7KyXL9JmLTP/NPew=" - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" - }, - "mime-db": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", - "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=" - }, - "mime-types": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", - "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "optional": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "optional": true, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "optional": true - } - } - }, - "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=", - "optional": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "optional": true - }, - "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", - "optional": true - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "optional": true - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" - }, - "node-fingerprint": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/node-fingerprint/-/node-fingerprint-0.0.2.tgz", - "integrity": "sha1-Mcur63GmeufdWn3AQuUcPHWGhQE=" - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" - }, - "packet-reader": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz", - "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=" - }, - "parseurl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "optional": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pg": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-6.4.0.tgz", - "integrity": "sha1-y3a6Lnwuq4n8ZL96n+ZIztckNtw=" - }, - "pg-connection-string": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", - "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" - }, - "pg-copy-streams": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pg-copy-streams/-/pg-copy-streams-1.2.0.tgz", - "integrity": "sha1-ez+d7gtsX8IGj1nED6IY4MHXQkk=" - }, - "pg-pool": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-1.8.0.tgz", - "integrity": "sha1-9+xzgkw3oD8Hb1G/33DjQBR8Tzc=" - }, - "pg-types": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.12.0.tgz", - "integrity": "sha1-itO3uJfj/UY+Yt4kGtX8ZAtKZvA=" - }, - "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=" - }, - "postgres-array": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz", - "integrity": "sha1-jgsy6wO/d6XAp4UeBEHBaaJWojg=" - }, - "postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" - }, - "postgres-date": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.3.tgz", - "integrity": "sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g=" - }, - "postgres-interval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.0.tgz", - "integrity": "sha1-EDHnusNFZBMoYq3J62xtLzqnW7Q=" - }, - "proxy-addr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz", - "integrity": "sha1-J+VF9pYKRKYn2bREZ+NcG2tM4vM=" - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" - }, - "raw-body": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", - "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=" - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "optional": true - }, - "safe-json-stringify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.4.tgz", - "integrity": "sha1-gaCY9Efku8P/MxKiQ1IbwGDvWRE=", - "optional": true - }, - "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" - }, - "send": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.3.tgz", - "integrity": "sha1-UBP5+ZAj31DRvZiSwZ4979HVMwk=" - }, - "serve-static": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.3.tgz", - "integrity": "sha1-n0uhni8wMMVH+K+ZEHg47DjVseI=" - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - }, - "split": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", - "integrity": "sha1-xDlc5oOrzSVLwo/h2rtuXCfc/64=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" - }, - "vary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", - "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - } - } -} diff --git a/package.json b/package.json index 38d2e9f5cfdfbac4453bf90536576dc1c0cb907c..4821f8d0cdf966a48ab4c661e2c208e553636af8 100644 --- a/package.json +++ b/package.json @@ -3,18 +3,40 @@ "version": "0.0.0", "description": "Webservice para receber dados do agente PInSIS", "author": "Davisson Paulino <dhpaulino@gmail.com>", + "license": "GPL-3.0", "main": "server.js", + "repository": { + "type": "git", + "url": "git@gitlab.c3sl.ufpr.br:PInSIS/webservice-pinsis.git" + }, "scripts": { - "start": "node server.js" + "start": "node src/server.js" }, "dependencies": { - "express": "^4.13.3", "async": "^2.1.2", "body-parser": "^1.14.1", + "bunyan": "^1.0.1", + "collect-webservice": "git+https://gitlab.c3sl.ufpr.br/c3sl/collect-webservice.git", + "cuid": "^1.2.4", + "ejs": "^2.5.7", + "express": "^4.13.3", + "minimist": "1.2.0", "pg": "^6.1.0", "pg-copy-streams": "^1.2.0", - "minimist": "1.2.0", - "cuid": "^1.2.4", - "bunyan": "^1.0.1" + "squel": "^5.10.0", + "xlsx": "^0.12.2" + }, + "devDependencies": { + "chai": "^4.1.0", + "chai-http": "^3.0.0", + "gulp": "^3.9.1", + "gulp-istanbul": "^1.1.2", + "gulp-jshint": "^2.0.4", + "gulp-mocha": "^v3.0.1", + "gulp-shell": "^0.6.3", + "jshint": "latest", + "jshint-stylish": "^2.2.1", + "mocha": "^3.5.0", + "nyc": "^11.1.0" } } diff --git a/routes/agent.js b/routes/agent.js deleted file mode 100644 index 9b2560cf2c5623058403e8b927b64f0287854f82..0000000000000000000000000000000000000000 --- a/routes/agent.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre - * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR - * - * This file is part of simmc - * - * simmc 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 2 - * of the License, or (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -var async = require('async'); - -function isSubSet (array1, array2) { - return array1.every(function(item1) { - return array2.some(function(item2) { - return item1 == item2; - }); - }); -} - -function dateFormat (date) { - - if (!date) { - return null; - } - - return date.getFullYear() + '-' + - ("0" + (date.getMonth() + 1)).slice(-2) + '-' + - ("0" + date.getDate()).slice(-2); -} - -function timeFormat (date) { - - if (!date) { - return null; - } - - return ("0" + date.getHours()).slice(-2) + ':' + - ("0" + date.getMinutes()).slice(-2) + ':' + - ("0" + date.getSeconds()).slice(-2); -} - -var routes = { - /*"net_usage": { - validation: function(body) { - if(!body) { - return false; - } - else { - var keys = [ - 'id_point', - 'mac_address', - 'bytes_recived', - 'bytes_transmited', - 'collect_time', - 'packets_recived', - 'packets_transmited', - ]; - return isSubSet(Object.keys(body), keys); - } - }, - parser: function(body) { - return [ - dateFormat(new Date()), - body.id_point, - body.mac_address, - dateFormat(body.collect_time), - timeFormat(body.collect_time), - body.bytes_recived, - body.packets_recived, - body.bytes_transmited, - body.packets_transmited, - ]; - }, - query: 'collect/net_usage.sql' - }*/ -}; - -module.exports = function(agentVersion) { - return { - collect: function(req, res) { - var route = routes[req.params.type]; - if(!route) { - return res.status(400).json({error: 'invalid_parameter'}); - } - if(route.validation(req.body)) { - var data = route.parser(req.body); - req.db.connect(function(err, conn, done) { - if (err) { - req.log.error(err); - res.status(500).json({error: 'db_connection_failed'}); - return; - } - async.waterfall([ - conn.transaction, - function(callback) { - conn.queryFromFile(route.query, data, callback); - }, - conn.commit - ], function (err, result) { - if(err) { - req.log.error(err); - res.staus(500).json({error: 'db_query_failed'}); - conn.rollback(done); - return; - } - res.status(200).json({}); - done(); - }); - }); - } - else { - return res.status(400).json({error: 'invalid_body'}); - } - }, - version : function (req, res) { - return res.status(200).json({version: agentVersion}); - } - }; -}; diff --git a/Dockerfile b/src/Dockerfile similarity index 100% rename from Dockerfile rename to src/Dockerfile diff --git a/src/db/query_builder.js b/src/db/query_builder.js new file mode 100644 index 0000000000000000000000000000000000000000..57a5697c11e2b6c7edc4922e5d989a21986f9817 --- /dev/null +++ b/src/db/query_builder.js @@ -0,0 +1,25 @@ +squel = require("squel").useFlavour('postgres'); + +module.exports = { + set_from_attr : function (query, obj){ + for (var property in obj) { + if (obj.hasOwnProperty(property)) { + query.set(property, obj[property]); + } + } + return query; + }, + insert: function (table, obj){ + var q = squel.insert().into(table); + this.set_from_attr(q, obj); + return q; + }, + + select: function(table, conditions){ + var q = squel.select().from(table); + for(c in conditions){ + q = q.where(c+" = "+"'"+conditions[c]+"'"); + } + return q; + } +}; diff --git a/lib/logger.js b/src/lib/logger.js similarity index 99% rename from lib/logger.js rename to src/lib/logger.js index cfd4c5b0405e67c847723329a5be32b0cf421711..fc62ffb61a72a7f119fc04be0c81ffa7a85b334d 100644 --- a/lib/logger.js +++ b/src/lib/logger.js @@ -20,6 +20,7 @@ * USA. */ +/*jshint sub:true*/ var os = require('os'); var cluster = require('cluster'); @@ -69,7 +70,7 @@ function responseSerializer(res) { return { statusCode: res.statusCode, responseTime: responseTime - } + }; } // Make sure the logs dir exist @@ -125,7 +126,7 @@ exports.expressAccess = function (req, res, next) { // Log the response req.log.debug({res: res}, 'response'); -} +}; // Export the express error logger (log errors during request processing) exports.expressError = function (err, req, res, next) { @@ -134,4 +135,4 @@ exports.expressError = function (err, req, res, next) { } next(); -} +}; diff --git a/middleware/db.js b/src/middleware/db.js similarity index 64% rename from middleware/db.js rename to src/middleware/db.js index 5f70a2707bd68ba8dc036bc043f5d9c9858d8bd3..c506f7baf06a9f49e71dc35c97e99e695ac27e58 100644 --- a/middleware/db.js +++ b/src/middleware/db.js @@ -66,23 +66,27 @@ function namedPatch(client) { exports.pool = function (config) { return function (req, res, next) { + var pool = new pg.Pool(config); req.db = { connect: function (callback) { - pg.on('error', function(err) { + pool.on('error', function(err) { + pool.end(); return; }); - pg.connect(config, function (err, client, done) { + pool.connect(function (err, client, done) { if (err) { - setTimeout(req.db.connect, 5000, callback); + callback(err, null, done); return; } namedPatch(client); callback(null, new Connection(client), done); }); + + pool.end(); } }; - + next(); }; }; @@ -102,38 +106,38 @@ function Connection(client) { }; }; - this.queryFromFile = function(file, params, callback) { - var queries_dir = __dirname + "/../queries/"; - - fs.readFile(queries_dir + file, 'utf8', function (err, data) { - if (err) { - return callback(err); - } - - if (typeof params === 'undefined') { - params = []; - } - - client.query(data, params, callback); - }); - }; - - this.executeFromFile = function(file, params) { - var $this = this; - - return function (callback) { - $this.queryFromFile(file, params, function (err) { - callback(err); - }); - }; - }; - - this.copyFrom = function (query, callback) { - var stream = client.query(copyFrom(query)); - stream.on('end', callback); - stream.on('error', callback); - return stream; - }; + // this.queryFromFile = function(file, params, callback) { + // var queries_dir = __dirname + "/../queries/"; + // + // fs.readFile(queries_dir + file, 'utf8', function (err, data) { + // if (err) { + // return callback(err); + // } + // + // if (typeof params === 'undefined') { + // params = []; + // } + // + // client.query(data, params, callback); + // }); + // }; + + // this.executeFromFile = function(file, params) { + // var $this = this; + // + // return function (callback) { + // $this.queryFromFile(file, params, function (err) { + // callback(err); + // }); + // }; + // }; + // + // this.copyFrom = function (query, callback) { + // var stream = client.query(copyFrom(query)); + // stream.on('end', callback); + // stream.on('error', callback); + // return stream; + // }; this.transaction = function (callback) { client.query('BEGIN;', function (err) { @@ -153,16 +157,16 @@ function Connection(client) { }); }; - this.auth = function (user, ip, action, comment) { - return function (callback) { - if (!(user && user.id)) - return callback('not_logged_in'); - - client.query('SELECT auth.user_action($1, $2, $3, $4);', - [user.id, ip, action, comment], - function (err) { - callback(err); - }); - }; - }; -}; + // this.auth = function (user, ip, action, comment) { + // return function (callback) { + // if (!(user && user.id)) + // return callback('not_logged_in'); + // + // client.query('SELECT auth.user_action($1, $2, $3, $4);', + // [user.id, ip, action, comment], + // function (err) { + // callback(err); + // }); + // }; + // }; +} diff --git a/src/middleware/populate.js b/src/middleware/populate.js new file mode 100644 index 0000000000000000000000000000000000000000..44f23f62e4e52400a5abca59b52fbbf0cbd856bf --- /dev/null +++ b/src/middleware/populate.js @@ -0,0 +1,232 @@ +var _ = require('lodash'); +var pg = require('pg'), + copyFrom = require('pg-copy-streams').from, + fs = require('fs'); + +var async = require('async'); + +var XLSX = require('xlsx'); + + +function namedPatch(client) { + var originalQuery = client.query; + + if (originalQuery.patched) return client; + + originalQuery = originalQuery.bind(client); + + var patchedQuery = function(config, values, callback) { + if (arguments.length === 1) { + return originalQuery(config); + } + else if (arguments.length === 2 && _.isFunction(values)) { + return originalQuery(config, values); + } + else if (_.isArray(values)) { + return originalQuery(config, values, callback); + } else { + var reparameterized = numericFromNamed(config, values); + return originalQuery(reparameterized.sql, reparameterized.values, callback); + } + }; + + client.query = patchedQuery; + client.query.patched = true; + + return client; +} + + +function Connection(client) { + this.query = function (query, params, callback) { + return client.query(query, params, callback); + }; + + this.execute = function (query, params) { + var $this = this; + + return function (callback) { + $this.query(query, params, function (err) { + callback(err); + }); + }; + }; + + this.transaction = function (callback) { + client.query('BEGIN;', function (err) { + callback(err); + }); + }; + + this.commit = function (callback) { + client.query('COMMIT;', function (err) { + callback(err); + }); + }; + + this.rollback = function (callback) { + client.query('ROLLBACK;', function (err) { + callback(err); + }); + }; + +} + +var sheet2arr = function(sheet){ + var i = 5; + var rows = []; + while(true){ + + if(!sheet["A"+(i+1)] && !sheet["A"+i]){ + return rows; + } + if(sheet["A"+(i+1)] && !sheet["A"+i]){ + i+=1; + } + + if(sheet["A"+i]["v"] == "ID do paciente"){ + + var paciente_id = sheet["D"+i]["w"]; + var paciente_nome = sheet["L"+i]["w"]; + + + if(!sheet["A"+(i+1)]){ + i+=1; + } + + i+=4; + } + + + if(sheet["G"+i]){ + var field_name = sheet["J"+i] ? sheet["J"+i]["w"] : ""; + var use_date = sheet["B"+i]["w"].split(" "); + use_date = new Date( + use_date[0].split("/")[2], + parseInt(use_date[0].split("/")[1])-1, + use_date[0].split("/")[0], + use_date[1].split(":")[0], + use_date[1].split(":")[1] + ); + rows.push({ + Pacient_id: paciente_id, + Pacient_name: paciente_nome, + Energy: sheet["G"+i]["w"], + Use_date: use_date.toISOString(), + Field_name: field_name, + Machine_id: sheet["M"+i]["w"], + Fk_agent: 1, + }); + } + i+=1; + + } + +}; + +function waterfall_queries(queries, config, cb_w){ + var pool = new pg.Pool(config); + var temp_db = { + connect: function (callback) { + pool.on('error', function(err) { + throw(err); + cb_w(); + }); + pool.connect(function (err, client, done) { + if (err) { + setTimeout(temp_db.connect, 5000, callback); + done(); + return; + } + + namedPatch(client); + callback(null, new Connection(client), done); + }); + + pool.end(); + } + }; + + temp_db.connect(function(err, conn, done) { + if (err) { + throw(err); + } + + async.waterfall([ + conn.transaction, + function(callback) { + async.everySeries(queries, function(q, cb){ + conn.query(q.toParam().text, q.toParam().values, cb); + }, function(err, result){ + callback(err); + }); + }, + conn.commit + ], function (err, result) { + if(err) { + throw(err); + conn.rollback(done); + cb_w(); + return; + } + done(); + cb_w(); + }); + }); +} + + +exports.populateAgent = function(file, config, callback = function(){}){ + var workbook = XLSX.readFile(file); + var sheet_name_list = workbook.SheetNames; + var sheetName = Object.keys(workbook.Sheets)[0]; + var s = workbook.Sheets[sheetName]; + + var consultas = sheet2arr(s); + + var queries = []; + + //TODO: Create a config file that will be used to populate this table + var q = qb.insert("agent",{ + Hospital_name: "Erasto Gaertner", + Geo_lat: -25.4696528, + Geo_long: -49.261403 + }); + + queries.push(q); + waterfall_queries(queries, config, callback); + +} + +exports.populeMachineuse = function (file,config, callback = function(){}){ + var workbook = XLSX.readFile(file); + var sheet_name_list = workbook.SheetNames; + var sheetName = Object.keys(workbook.Sheets)[0]; + var s = workbook.Sheets[sheetName]; + + var consultas = sheet2arr(s); + + var queries = []; + + for(var x in consultas){ + var q = qb.insert("machineuse",consultas[x]); + queries.push(q); + } + + var refresh_views_query = { + toParam: function refresh_views(){ + return { + values: [], + text: + "REFRESH materialized view ResumeUsesMonth;"+ + "REFRESH materialized view ResumeUsesDay;" + } + } + } + + queries.push(refresh_views_query); + waterfall_queries(queries, config, callback); + + +} + diff --git a/src/routes/agent.js b/src/routes/agent.js new file mode 100644 index 0000000000000000000000000000000000000000..4359b7f5e234d300a8b60822821e2c2e5bb1e5e6 --- /dev/null +++ b/src/routes/agent.js @@ -0,0 +1,87 @@ +/* +* Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre +* Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR +* +* This file is part of simmc +* +* simmc 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 2 +* of the License, or (at your option) any later version. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +* USA. +*/ + +var async = require('async'); + + + +module.exports = function(agentVersion) { + qb = require("../db/query_builder.js"); + + return { + collect: function(req, res) { + var queries = []; + if(req.body.hasOwnProperty("courses")){ + for(var i=0;i < req.body.courses.length; i++){ + var course = req.body.courses[i]; + var q = qb.insert('Course', course); + queries.push(q); + } + + } + + if(req.body.hasOwnProperty("sessions")){ + req.body.sessions.forEach(function(session){ + queries.push(qb.insert('Session', session)); + }); + + } + + if(req.body.hasOwnProperty("sessionProcedureParts")){ + req.body.sessionProcedureParts.forEach(function(spp){ + queries.push(qb.insert('sessionProcedurePart', spp)); + }); + + } + req.db.connect(function(err, conn, done) { + if (err) { + req.log.error(err); + res.status(500).json({error: 'db_connection_failed'}); + return; + } + async.waterfall([ + conn.transaction, + function(callback) { + async.everySeries(queries, function(q, cb){ + conn.query(q.toParam().text, q.toParam().values, cb); + }, function(err, result){ + callback(err); + }); + }, + conn.commit + ], function (err, result) { + if(err) { + req.log.error(err); + res.status(500).json({error: 'db_query_failed'}); + conn.rollback(done); + return; + } + res.status(200).json({}); + done(); + }); + }); + }, + version : function (req, res) { + return res.status(200).json({version: agentVersion}); + } + }; +}; diff --git a/src/routes/data.js b/src/routes/data.js new file mode 100644 index 0000000000000000000000000000000000000000..f4053339f693137d4cb873ccea54fcb121497d3c --- /dev/null +++ b/src/routes/data.js @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre +* Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR +* +* This file is part of simmc +* +* simmc 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 2 +* of the License, or (at your option) any later version. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +* USA. +*/ + +var async = require('async'); + +module.exports = function(agentVersion) { + qb = require("../db/query_builder.js"); + + return { + listTable : function (req, res, table) { + req.db.connect(function(err, conn, done) { + + if (err) { + req.log.error(err); + res.status(500).json({error: 'db_connection_failed'}); + done(); + return; + } + + var parameters = {}; + + switch(table){ + case 'ResumeUsesMonth': + case 'ResumeUsesDay': + if(req.query['hospital_id']) parameters["fk_agent"] = parseInt(req.query['hospital_id']); + break; + } + + + var q = qb.select(table,parameters); + + conn.query(q.toParam().text,q.toParam().values, function(err,data,fields){ + if (err) req.log.error(err); + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Headers", "X-Requested-With"); + done(); + return res.status(200).json(data.rows); + }); + + }); + + } + }; +}; diff --git a/routes/ping.js b/src/routes/ping.js similarity index 100% rename from routes/ping.js rename to src/routes/ping.js diff --git a/server.js b/src/server.js similarity index 67% rename from server.js rename to src/server.js index a0cb67db8f602d6fd7bd13579779f413422457de..c236018abcccaef6f2cdacc2a24db180a7f65eb7 100644 --- a/server.js +++ b/src/server.js @@ -24,6 +24,8 @@ // // Libraries // +/*jshint esversion: 6*/ + var os = require('os'); var fs = require('fs'); var cluster = require('cluster'); @@ -32,6 +34,7 @@ var express = require('express'); var minimist = require('minimist'); var path = require('path'); var exec = require('child_process').execFile; +var collect = require('collect-webservice'); // // Parse command line arguments @@ -53,7 +56,18 @@ if (argv.help || argv.h) { return 0; } -var configFile = argv.config || argv.c || 'config.js'; +const app_mode = (process.env.NODE_ENV || 'development').trim().toLowerCase(); + + +var configFile; + +//test config +if(app_mode === 'test'){ + configFile = argv.config || argv.c || 'config_test.js'; +}else{ + configFile = argv.config || argv.c || 'config.js'; +} + var config; try { config = require(path.resolve('.', configFile)); @@ -79,9 +93,10 @@ var port = parseInt(argv.port || argv.p || process.env.PORT) || 3000; var secureCookies = !argv.insecure; var numWorkers = parseInt(argv['num-workers'] || argv.n) || (os.cpus().length * 2); var daemon = argv.daemon || argv.d || false; -var pidfile = argv['pid-file'] || config.pid_file || process.env.PID_FILE || path.resolve('.', 'simmc.pid'); +var pidfile = argv['pid-file'] || config.pid_file || process.env.PID_FILE || path.resolve('.', 'pinsis.pid'); + -if (devMode) { +if (app_mode === 'development' || app_mode === 'test') { secureCookies = false; // Limit to only 1 worker in dev mode because sessions stored @@ -99,17 +114,106 @@ var logger = require('./lib/logger.js'); var log = logger.default; +// +// Middlewares +// + +var db = require('./middleware/db.js'); + +// +// Routes +// + +var ping = require('./routes/ping.js'); +var agent = require('./routes/agent.js')(config.agentVersion); +var data = require('./routes/data.js')(config.agentVersion); + +//Data validation +var ct_validator = require('./validation/course_treatment.js'); + +// +// Setup express app +// +var app = express(); +app.use(logger.expressAccess); +app.use(logger.expressError); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended: true})); + + + +app.use(db.pool(config.db_config)); + + + +// acquire user id and ip address +app.use(function (req, res, next) { + req.ip = req.ips[0] || req.ip || null; + next(); +}); + +app.engine('html', require('ejs').renderFile); +app.set('view engine', 'html'); + +var populate = require("./middleware/populate.js"); + + +// +// Setup routes +// + +app.get('/api/ping', ping.get); + + +var collect_mw = collect(ct_validator()); +app.post('/api/agent/collect/:type(course_treatment)', collect_mw, agent.collect); +app.get('/api/agent/version', agent.version); + + + +app.get('/api/data/listAgents', function(req, res) { + data.listTable(req,res,"agent"); +}); + +app.get('/api/data/ResumeUsesDay', function(req, res) { + data.listTable(req,res,"ResumeUsesDay"); +}); + +app.get('/api/data/ResumeUsesMonth', function(req, res) { + data.listTable(req,res,"ResumeUsesMonth"); +}); + + +app.get('/pinsis.js', function(req, res) { + res.render(path.join(__dirname + '/static/pinsis.ejs'),{ip:config.webservice_config.ip}); +}); + +app.get('/exemplo.html', function(req, res) { + res.render(path.join(__dirname + '/static/exemplo.html'),{ip:config.webservice_config.ip}); +}); + + + +var exit = function exit() { + log.info('Server exiting...'); + + process.exit(0); +}; + // // Fork process // if (cluster.isMaster) { + //Here is where should be populated the tables + + // daemonize the process (useful for init.d scripts and similar) if (argv.daemon) { require('daemon')(); fs.writeFileSync(pidfile, process.pid+"\n"); } - log.info('Starting server in '+ (devMode ? 'development' : 'production') + + log.info('Starting server in '+ app_mode + ' mode, spawning ' + numWorkers + ' workers'); for (var i = 0; i < numWorkers; i++) { @@ -126,65 +230,13 @@ if (cluster.isMaster) { } }); - function exit() { - log.info('Server exiting...'); - process.exit(0); - } process.on('SIGTERM', exit); process.on('SIGHUP', exit); process.on('SIGINT', exit); } else { - // - // Middlewares - // - - var db = require('./middleware/db.js'); - var utils = require('./lib/utils.js'); - - // - // Routes - // - - var ping = require('./routes/ping.js'); - var agent = require('./routes/agent.js')(config.agentVersion); - - - // - // Setup express app - // - var app = express(); - app.use(logger.expressAccess); - app.use(logger.expressError); - app.use(bodyParser.json()); - app.use(bodyParser.urlencoded({extended: true})); - - - - app.use(db.pool(config.db_config)); - - - - // acquire user id and ip address - app.use(function (req, res, next) { - req.ip = req.ips[0] || req.ip || null; - next(); - }); - - - - - - // - // Setup routes - // - - app.get('/api/ping', ping.get); - - app.post('/api/agent/collect/:type(inventory|net_usage)', agent.collect); - app.get('/api/agent/version', agent.version); // // Listen for incoming connections @@ -201,3 +253,4 @@ else { app.listen(port); } } +module.exports = app; diff --git a/src/static/exemplo.html b/src/static/exemplo.html new file mode 100644 index 0000000000000000000000000000000000000000..7c78735d1e32aeab82f419fabbd1a192e4442b2a --- /dev/null +++ b/src/static/exemplo.html @@ -0,0 +1,133 @@ +<html> + <header> + <meta charset="utf-8"> + + <style> + .SEPARADOR{ + margin-top:20px; + margin-bottom:20px; + width:100%; + outline-width:1px; + outline-style:solid; + outline-color:rgba(0,0,0,0.3); + text-align:center; + background-color:rgba(0,0,0,0.3); + } + </style> + + + <script src="http://<%= ip %>:3000/pinsis.js"></script> + <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> + <script> + + function get_attribute_list(object_list, key){ + return object_list.map(function(x){return x[key];}); + } + + function plot_uses_by(uses,groupby, divname){ + var plot1_data_x = get_attribute_list(uses,"date"); + var plot2_data_x = plot1_data_x; + + + var plot1_data_y = get_attribute_list(uses,"uses"); + var plot2_data_y = []; + + + for(i in plot1_data_x){ + plot2_data_y[i] = plot1_data_y[i] - parseInt(plot1_data_y[i]*Math.random()); + plot1_data_y[i] -= plot2_data_y[i]; + } + + + var susColor = 'green'; + var othersColor = 'blue'; + + var plot_data = [ + { + x: plot1_data_x, + y: plot1_data_y, + type: 'bar', + name: 'Outros', + marker: {color: othersColor}, + }, + { + x: plot2_data_x, + y: plot2_data_y, + type: 'bar', + name: 'SUS', + marker: {color: susColor}, + } + ]; + + Plotly.newPlot(divname, plot_data, {barmode: 'group'}); + + + var sum = function(x,y){return x+y;} + + var data = [{ + values: [plot2_data_y.reduce(sum),plot1_data_y.reduce(sum)], + labels: ['SUS', 'Outros'], + type: 'pie', + marker:{colors:[susColor, othersColor]}, + }]; + + var layout = { + height: 400, + width: 500 + }; + + Plotly.newPlot(divname+"_pizza", data, layout); + + } + + var hospitals; + + function plot(groupby, hospital){ + switch(groupby){ + case "days": + Pinsis.lastUsesByDay(function(err, data){ + if(err) console.log(err); + plot_uses_by(data,groupby,"myDiv"); + }, hospital.id); + break; + case "months": + Pinsis.lastUsesByMonth(function(err, data){ + if(err) console.log(err); + plot_uses_by(data,groupby,"myDiv"); + },hospital.id); + break; + } + + document.getElementById("hospital_name").innerHTML = hospital.hospital_name; + } + + + Pinsis.hospitals(function(err, data){ + if(err) console.log(err); + hospitals = data; + console.log(data); + plot("days",hospitals[0]); + }); + + + </script> + </header> + <body> + <center> + <button onClick="plot('months', hospitals[0])" > MESES </button> + <button onClick="plot('days', hospitals[0])" > DIAS </button> + </center> + + <center><h1>Monitoramento: <span id="hospital_name"></span></h1> + <div class="SEPARADOR"></div> + <div id="myDiv"></div> + <div id="myDiv_pizza"></div> + <div class="SEPARADOR"></div> + </center> + + <br><br> + + </body> + + +</html> diff --git a/src/static/pinsis.ejs b/src/static/pinsis.ejs new file mode 100644 index 0000000000000000000000000000000000000000..724d23f782cf27bdf5d13517c4808181b2310433 --- /dev/null +++ b/src/static/pinsis.ejs @@ -0,0 +1,47 @@ +var Pinsis = { + + getJson: function(callback, url){ + var xmlhttp = new XMLHttpRequest(); + + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + var myArr = JSON.parse(this.responseText); + callback(null, myArr); + } + + if (this.readyState == 4 && this.status != 200) { + callback({status: this.status}, null) + } + }; + xmlhttp.open("GET", url, true); + xmlhttp.send(); + }, + + lastUsesByDay: function(callback, hospital_id){ + var url = "http://<%= ip %>:3000/api/data/ResumeUsesDay"; + if(hospital_id) url+="?hospital_id="+hospital_id; + this.getJson( + callback, + url + ); + }, + + lastUsesByMonth: function(callback, hospital_id){ + var url = "http://<%= ip %>:3000/api/data/ResumeUsesMonth"; + if(hospital_id) url+="?hospital_id="+hospital_id; + this.getJson( + callback, + url + ); + + }, + + hospitals: function(callback){ + this.getJson( + callback, + "http://<%= ip %>:3000/api/data/listAgents" + ); + }, + + +} diff --git a/src/validation/course_treatment.js b/src/validation/course_treatment.js new file mode 100644 index 0000000000000000000000000000000000000000..72b00c60cd34ff0779242cc8d360a850444ee04c --- /dev/null +++ b/src/validation/course_treatment.js @@ -0,0 +1,307 @@ +/* +* Copyright (C) 2012-2017 Centro de Computacao Cientifica e Software Livre +* Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR +* +* This file is part of simmc +* +* simmc 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 2 +* of the License, or (at your option) any later version. +* +* This program 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 this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +* USA. +*/ + + +var config = { + global: { + fromBody: false, + param: "type" + }, + filters: {}, + collect_types: { + "course_treatment": { + "courses":{ + required: false, + isArray: true, + filters: [], + inner:{ + "CourseSer" : { + required: true, + isArray: false, + filters: [] + }, + "PatientSer" : { + required: true, + isArray: false, + filters: [] + }, + "CourseId" : { + required: true, + isArray: false, + filters: [] + }, + "StartDateTime" : { + required: true, + isArray: false, + filters: [] + }, + "ClinicalStatus" : { + required: true, + isArray: false, + filters: [] + }, + "CompletedByUserName" : { + required: true, + isArray: false, + filters: [] + }, + "CompletedDateTime" : { + required: true, + isArray: false, + filters: [] + }, + "Comment" : { + required: true, + isArray: false, + filters: [] + }, + "ClinicalProtocolDir" : { + required: true, + isArray: false, + filters: [] + }, + "HstryUserName" : { + required: true, + isArray: false, + filters: [] + }, + "HstryTimeStamp" : { + required: true, + isArray: false, + filters: [] + }, + "HstryDateTime" : { + required: true, + isArray: false, + filters: [] + }, + "TransactionId" : { + required: true, + isArray: false, + filters: [] + }, + "HstryTaskName" : { + required: true, + isArray: false, + filters: [] + } + + } + }, + "sessions":{ + required: false, + isArray: true, + filters: [], + inner:{ + "sessionSer": { + required: true, + isArray: false, + filters: [] + }, + "SessionNum": { + required: true, + isArray: false, + filters: [] + }, + "Comment": { + required: true, + isArray: false, + filters: [] + }, + "HstryUserName": { + required: true, + isArray: false, + filters: [] + }, + "HstryTimeStamp": { + required: true, + isArray: false, + filters: [] + }, + "HstryDateTime": { + required: true, + isArray: false, + filters: [] + }, + "HstryTaskName": { + required: true, + isArray: false, + filters: [] + }, + "CourseSer": { + required: true, + isArray: false, + filters: [] + }, + + } + }, + "sessionProcedureParts":{//FIXME: Is it required? + required: false, + isArray: true, + filters: [], + inner:{ + "RadiationSer" : { + required: true, + isArray: false, + filters: [] + }, + "ImageType" : { + required: true, + isArray: false, + filters: [] + }, + "SequenceNumber" : { + required: true, + isArray: false, + filters: [] + }, + "SessionProcedurePartSer" : { + required: true, + isArray: false, + filters: [] + }, + "AcqAdjustment" : { + required: true, + isArray: false, + filters: [] + }, + "AutoSave" : { + required: true, + isArray: false, + filters: [] + }, + "DoseAccumulation" : { + required: true, + isArray: false, + filters: [] + }, + "Continuous" : { + required: true, + isArray: false, + filters: [] + }, + "BeamOff" : { + required: true, + isArray: false, + filters: [] + }, + "DeviationImage" : { + required: true, + isArray: false, + filters: [] + }, + "DevEnergy" : { + required: true, + isArray: false, + filters: [] + }, + "DevDoseRate" : { + required: true, + isArray: false, + filters: [] + }, + "DevGeometry" : { + required: true, + isArray: false, + filters: [] + }, + "JawState" : { + required: true, + isArray: false, + filters: [] + }, + "DevCollX1" : { + required: true, + isArray: false, + filters: [] + }, + "DevCollX2" : { + required: true, + isArray: false, + filters: [] + }, + "DevCollY1" : { + required: true, + isArray: false, + filters: [] + }, + "DevCollY2" : { + required: true, + isArray: false, + filters: [] + }, + "MUSubtraction" : { + required: true, + isArray: false, + filters: [] + }, + "AcquisitionMode" : { + required: true, + isArray: false, + filters: [] + }, + "HstryUserName" : { + required: true, + isArray: false, + filters: [] + }, + "HstryTimeStamp" : { + required: true, + isArray: false, + filters: [] + }, + "HstryDateTime" : { + required: true, + isArray: false, + filters: [] + }, + "HstryTaskName" : { + required: true, + isArray: false, + filters: [] + }, + "SessionProcedureSer" : { + required: true, + isArray: false, + filters: [] + }, + "ImageModality" : { + required: true, + isArray: false, + filters: [] + }, + "RTPlanSer" : { + required: true, + isArray: false, + filters: [] + } + } + } + } + } +}; + +module.exports = function() { + + return config; +}; diff --git a/test/db/query_builder.js b/test/db/query_builder.js new file mode 100644 index 0000000000000000000000000000000000000000..a6e86ec775cbb8485d91145ed0945ff9601d7b7e --- /dev/null +++ b/test/db/query_builder.js @@ -0,0 +1,37 @@ +/*jshint esversion: 6*/ +process.env.NODE_ENV = 'test'; +let chai = require('chai'); +let should = chai.should(); + + + +var toType = function(obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); +}; + +describe('Query builder',() => { + const qb = require('../../src/db/query_builder.js'); + var squel = require("squel").useFlavour('postgres'); + + it('insert return a valid query ', (done) => { + const table = 'tb'; + const obj = { + attr1: "v1", + attr2: 2 + }; + var trueq = squel.insert() + .into(table) + .set('attr1', obj.attr1) + .set('attr2', obj.attr2); + + var resultq = qb.insert(table, obj); + + resultq.should.be.an('object'); + resultq.toString().should.equal(trueq.toString()); + + done(); + }); + + + +}); diff --git a/test/routes/agent.js b/test/routes/agent.js new file mode 100644 index 0000000000000000000000000000000000000000..ae61c9a88eb2e26dc5bcbb69dffb2c7e350042c6 --- /dev/null +++ b/test/routes/agent.js @@ -0,0 +1,113 @@ +/*jshint esversion: 6*/ + +process.env.NODE_ENV = 'test'; +let chai = require('chai'); +let chaiHttp = require('chai-http'); +const src_dir='../../src/'; +const server = require(src_dir + 'server.js'); +let should = chai.should(); + +chai.use(chaiHttp); + + +//console.log("lol"); +//console.log(server); +describe('course_treatment', () => { + + let courses = [{ + "CourseSer" : "1", + "PatientSer" : "1", + "CourseId" : "1", + "StartDateTime" : "11-11-11 11:11:11", + "ClinicalStatus" : "CS1", + "CompletedByUserName" : "CByU1", + "CompletedDateTime" : "11-11-11 11:11:11", + "Comment" : "Comment1", + "ClinicalProtocolDir" : "CPD1", + "HstryUserName" : "HUN1", + "HstryTimeStamp" : "11-11-11 11:11:11", + "HstryDateTime" : "11-11-11 11:11:11", + "TransactionId" : "1", + "HstryTaskName" : "HTN1" + }]; + + let sessions = [{ + "sessionSer": "1", + "SessionNum": "1", + "Comment": "C1", + "HstryUserName": "HUN1", + "HstryTimeStamp": "1111-11-11 11:11:11", + "HstryDateTime": "1111-11-11 11:11:11", + "HstryTaskName": "HTN1", + "CourseSer": "1" + }]; + + let sessionProcedureParts = [{ + "RadiationSer" : "1", + "ImageType" : "IT1", + "SequenceNumber" : "1", + "SessionProcedurePartSer" : "1", + "AcqAdjustment" : "1", + "AutoSave" : "1", + "DoseAccumulation" : "1", + "Continuous" : "1", + "BeamOff" : "1", + "DeviationImage" : "1", + "DevEnergy" : "1", + "DevDoseRate" : "1", + "DevGeometry" : "1", + "JawState" : "1", + "DevCollX1" : "1", + "DevCollX2" : "1", + "DevCollY1" : "1", + "DevCollY2" : "1", + "MUSubtraction" : "1", + "AcquisitionMode" : "AM1", + "HstryUserName" : "HUN1", + "HstryTimeStamp" : "1111-11-11 11:11:11", + "HstryDateTime" : "1111-11-11 11:11:11", + "HstryTaskName" : "1111-11-11 11:11:11", + "SessionProcedureSer" : "1", + "ImageModality" : "IM1", + "RTPlanSer" : "1" + }]; + + + it('it should post courses, sessions and sessionProcedureParts', (done) => { + chai.request(server) + .post('/api/agent/collect/course_treatment') + .send({courses: courses, sessions: sessions, sessionProcedureParts: sessionProcedureParts}) + .end((err, res) => { + res.should.have.status(200); + done(); + }); + + }); + it('it should give a error for save duplicate courses', (done) =>{ + chai.request(server) + .post('/api/agent/collect/course_treatment') + .send({courses: courses}) + .end((err, res) => { + res.should.have.status(500); + res.body.should.be.a('object'); + res.body.should.have.property('error').eql('db_query_failed'); + done(); + }); + }); +}); + +describe('agent version', () => { + + it('it should get version of the agent', (done) => { + + const config = require('../../config_test.js'); + + chai.request(server) + .get('/api/agent/version') + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property('version').eql(config.agentVersion); + done(); + }); + }); +}); diff --git a/test/routes/ping.js b/test/routes/ping.js new file mode 100644 index 0000000000000000000000000000000000000000..4c9cf2cb0b9a668115ad1c2bc95859c3b4285447 --- /dev/null +++ b/test/routes/ping.js @@ -0,0 +1,44 @@ +/*jshint esversion: 6*/ + +process.env.NODE_ENV = 'test'; +let chai = require('chai'); +let chaiHttp = require('chai-http'); +const src_dir='../../src/'; + +let should = chai.should(); + +chai.use(chaiHttp); + + +//console.log("lol"); +//console.log(server); +describe('ping', () => { + + + it('it should pong', (done) => { + const server = require(src_dir + 'server.js'); + chai.request(server) + .get('/api/ping') + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property('message').eql('Pong'); + done(); + }); + + }); + + it('it shouldn\'t pong', (done) =>{ + process.argv.push("--config"); + process.argv.push("config_test_error.js"); + + const server = require(src_dir + 'server.js'); + chai.request(server) + .get('/api/ping') + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property('message').eql('db_connection_failed'); + done(); + }); + + }); +}); diff --git a/test/server.js b/test/server.js new file mode 100644 index 0000000000000000000000000000000000000000..04d18aeb38d520b47c99d0d654702d90be8d4314 --- /dev/null +++ b/test/server.js @@ -0,0 +1,18 @@ +// /*jshint esversion: 6*/ +// +// process.env.NODE_ENV = 'test'; +// let chai = require('chai'); +// let chaiHttp = require('chai-http'); +// const src_dir='../../src/'; +// const server = require(src_dir + 'server.js'); +// let should = chai.should(); +// +// chai.use(chaiHttp); +// +// +// //console.log("lol"); +// //console.log(server); +// describe('Server', () => { +// +// it('it should have') +// });