diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..5171c54083337f0b87926da2e8f52abefe19d70f
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+node_modules
+npm-debug.log
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..57a123473780458b523e29b006d60602a8e201f0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+config.js
+logs/
+*.swp
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..e3b21c3c4534e0dd1f265b7ecc56d1c7f083415a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,12 @@
+FROM node:boron
+
+RUN mkdir -p /usr/src/app
+WORKDIR /usr/src/app
+
+COPY package.json /usr/src/app/
+RUN npm install
+
+COPY . /usr/src/app
+
+EXPOSE 8080
+CMD [ "npm", "start" ]
\ No newline at end of file
diff --git a/config.js.example b/config.js.example
new file mode 100644
index 0000000000000000000000000000000000000000..b2deb06c586c934a283170344e7321bf42f22b2e
--- /dev/null
+++ b/config.js.example
@@ -0,0 +1,40 @@
+var config = module.exports = {};
+
+config.db_config = {
+    user: 'user',
+    password: 'password',
+    database: 'dbname',
+    host: 'localhost',
+    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';
+
+// Uncomment to enable memcached
+//
+// config.memcached = {
+//     server: 'localhost:11211',
+//     options: { retries: 1, timeout: 1000, poolSize: 1 },
+//     lifetime: 3600 // 1 hour in seconds
+// };
diff --git a/lib/agentbuilder.js b/lib/agentbuilder.js
new file mode 100644
index 0000000000000000000000000000000000000000..24cb61e90f345951f3d2b660620fd9034952648a
--- /dev/null
+++ b/lib/agentbuilder.js
@@ -0,0 +1,35 @@
+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/logger.js b/lib/logger.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfd4c5b0405e67c847723329a5be32b0cf421711
--- /dev/null
+++ b/lib/logger.js
@@ -0,0 +1,137 @@
+/*
+ * 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 os = require('os');
+var cluster = require('cluster');
+var bunyan = require('bunyan');
+var cuid = require('cuid');
+var fs    = require('fs');
+
+// Serialize a request (remove unuseful information from requests,
+// log only the necessary).
+function requestSerializer(req) {
+    if ((typeof(req) !== 'object') || (req === null)) {
+        return req;
+    }
+
+    var headers = req.headers || {};
+
+    return {
+        method: req.method,
+        url: req.url,
+        headers: { // selective choice of headers (no cookies)
+            "host": headers["host"],
+            "connection": headers["connection"],
+            "cache-control": headers["cache-control"],
+            "accept": headers["accept"],
+            "user-agent": headers["user-agent"],
+            "referer": headers["referer"],
+            "accept-encoding": headers["accept-encoding"],
+            "accept-language": headers["accept-language"]
+        },
+        remoteAddress: req.ips[0] || req.ip || null
+    };
+}
+
+// Serialize a reponse (remove unuseful information from responses
+// and calculate the reponse time).
+function responseSerializer(res) {
+    if ((typeof(res) !== 'object') || (res === null)) {
+        return res;
+    }
+
+    // Calculate the response time
+    var responseTime;
+    if (res.start) {
+        responseTime = (new Date() - res.start).toString() + " ms";
+    }
+
+    return {
+        statusCode: res.statusCode,
+        responseTime: responseTime
+    }
+}
+
+// Make sure the logs dir exist
+try {
+    fs.mkdirSync('logs');
+}
+catch (e) {
+    if ( e.code != 'EEXIST' )
+        throw e;
+}
+
+// Create the default logger
+var defaultLogger = bunyan.createLogger({
+    name: 'default',
+    streams: [{
+        level: "info",
+        type: 'file',
+        path: 'logs/default.log',
+    },
+    {
+        level: "debug",
+        type: 'file',
+        path: 'logs/debug.log',
+    }],
+    serializers: {
+        req: requestSerializer,
+        res: responseSerializer
+    }
+});
+if (!cluster.isMaster) {
+    defaultLogger = defaultLogger.child({ worker: cluster.worker.id });
+}
+
+// Export the default logger
+exports.default = defaultLogger;
+
+// Export the access logger (log express requests)
+exports.expressAccess = function (req, res, next) {
+    // insert the current time into the response
+    // (for later calculation of reponse time).
+    res.start = new Date();
+
+    // Insert a log object into the request.
+    // The routes can use this object to log messages and all
+    // of them can be traced to the request (by req_id).
+    req.log = defaultLogger.child({ req_id: cuid.slug() });
+
+    // Log the request
+    req.log.debug({req: req}, 'request');
+
+    // Continue to the next handler
+    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) {
+    if (err) {
+        defaultLogger.error({err: err}, 'Error while processing request');
+    }
+
+    next();
+}
diff --git a/lib/mail.js b/lib/mail.js
new file mode 100644
index 0000000000000000000000000000000000000000..602c5cd3513833eba09ec440ec80d4f8bff91d15
--- /dev/null
+++ b/lib/mail.js
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 0000000000000000000000000000000000000000..59659ae08a646bbcee61be69624b68bb635c22d6
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,88 @@
+/*
+ * 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
new file mode 100644
index 0000000000000000000000000000000000000000..e8809908bdef74f85be346443811411dee8ec1d9
--- /dev/null
+++ b/middleware/cache.js
@@ -0,0 +1,37 @@
+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/middleware/db.js b/middleware/db.js
new file mode 100644
index 0000000000000000000000000000000000000000..5f70a2707bd68ba8dc036bc043f5d9c9858d8bd3
--- /dev/null
+++ b/middleware/db.js
@@ -0,0 +1,168 @@
+var pg = require('pg'),
+    copyFrom = require('pg-copy-streams').from,
+    fs = require('fs'),
+    _ = require('lodash');
+
+var tokenPattern = /\$[a-zA-Z]([a-zA-Z0-9_]*)\b/g;
+
+function numericFromNamed(sql, parameters) {
+    var fillableTokens = Object.keys(parameters);
+
+    var matchedTokens = _.uniq(_.map(sql.match(tokenPattern), function (token) {
+        return token.substring(1); // Remove leading dollar sign
+    }));
+
+    var fillTokens = _.intersection(fillableTokens, matchedTokens).sort();
+    var fillValues = _.map(fillTokens, function (token) {
+        return parameters[token];
+    });
+
+    var unmatchedTokens = _.difference(matchedTokens, fillableTokens);
+
+    if (unmatchedTokens.length) {
+        var missing = unmatchedTokens.join(", ");
+        throw new Error("Missing Parameters: " + missing);
+    }
+
+    var interpolatedSql = _.reduce(fillTokens, function (partiallyInterpolated, token, index) {
+        var replaceAllPattern = new RegExp('\\$' + fillTokens[index] + '\\b', "g");
+        return partiallyInterpolated.replace(replaceAllPattern, '$' + (index+1));
+    }, sql);
+
+    var out = {};
+    out.sql = interpolatedSql;
+    out.values = fillValues;
+
+    return out;
+}
+
+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;
+}
+
+exports.pool = function (config) {
+    return function (req, res, next) {
+        req.db = {
+            connect: function (callback) {
+                pg.on('error', function(err) {
+                    return;
+                });
+                pg.connect(config, function (err, client, done) {
+                    if (err) {
+                        setTimeout(req.db.connect, 5000, callback);
+                        return;
+                    }
+
+                    namedPatch(client);
+                    callback(null, new Connection(client), done);
+                });
+            }
+        };
+
+        next();
+    };
+};
+
+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.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) {
+            callback(err);
+        });
+    };
+
+    this.commit = function (callback) {
+        client.query('COMMIT;', function (err) {
+            callback(err);
+        });
+    };
+
+    this.rollback = function (callback) {
+        client.query('ROLLBACK;', 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/package-lock.json b/package-lock.json
new file mode 100644
index 0000000000000000000000000000000000000000..cacdd20788a057d68cb3d94fc52698dae4fe108a
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,480 @@
+{
+  "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
new file mode 100644
index 0000000000000000000000000000000000000000..38d2e9f5cfdfbac4453bf90536576dc1c0cb907c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,20 @@
+{
+  "name": "webservice-pinsis",
+  "version": "0.0.0",
+  "description": "Webservice para receber dados do agente PInSIS",
+  "author": "Davisson Paulino <dhpaulino@gmail.com>",
+  "main": "server.js",
+  "scripts": {
+    "start": "node server.js"
+  },
+  "dependencies": {
+    "express": "^4.13.3",
+    "async": "^2.1.2",
+    "body-parser": "^1.14.1",
+    "pg": "^6.1.0",
+    "pg-copy-streams": "^1.2.0",
+    "minimist": "1.2.0",
+    "cuid": "^1.2.4",
+    "bunyan": "^1.0.1"
+  }
+}
diff --git a/routes/agent.js b/routes/agent.js
new file mode 100644
index 0000000000000000000000000000000000000000..9b2560cf2c5623058403e8b927b64f0287854f82
--- /dev/null
+++ b/routes/agent.js
@@ -0,0 +1,132 @@
+/*
+ * 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/routes/ping.js b/routes/ping.js
new file mode 100644
index 0000000000000000000000000000000000000000..4bbeec42f4d3961d2214d40da10b5f3dfaad60e8
--- /dev/null
+++ b/routes/ping.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+exports.get = function (req, res) {
+    req.db.connect(function (err, conn, done) {
+        done(err);
+        if (err) {
+            res.status(200).json({ message: 'db_connection_failed' });
+            return;
+        }
+        res.status(200).json({ message: 'Pong' });
+        return;
+    });
+};
diff --git a/server.js b/server.js
new file mode 100644
index 0000000000000000000000000000000000000000..a0cb67db8f602d6fd7bd13579779f413422457de
--- /dev/null
+++ b/server.js
@@ -0,0 +1,203 @@
+#!/usr/bin/env node
+/*
+ * 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.
+ */
+
+//
+// Libraries
+//
+var os = require('os');
+var fs = require('fs');
+var cluster = require('cluster');
+var bodyParser = require('body-parser');
+var express = require('express');
+var minimist = require('minimist');
+var path = require('path');
+var exec = require('child_process').execFile;
+
+//
+// Parse command line arguments
+//
+var argv = minimist(process.argv.slice(2));
+if (argv.help || argv.h) {
+    console.log('Usage: server.js [OPTION]...');
+    console.log('');
+    console.log('Where OPTION can be:');
+    console.log('    -c, --config       alternative configuration file (default: config.js)');
+    console.log('    -p, --port         port where the server will listen to');
+    console.log('    --insecure         allows session cookies to be passed around in');
+    console.log('                       in insecure connections');
+    console.log('    --dev              force development mode');
+    console.log('    -n, --num-workers  number of worker processes to spawn');
+    console.log('    -d, --daemon       start the server as a daemon');
+    console.log('    --pid-file         path for the pid file when running as a daemon');
+    console.log('    -h, --help         show this help and exit');
+    return 0;
+}
+
+var configFile = argv.config || argv.c || 'config.js';
+var config;
+try {
+    config = require(path.resolve('.', configFile));
+}
+catch (e) {
+    if (e.code === 'MODULE_NOT_FOUND') {
+        console.error('Missing configuration file ('+configFile+')!');
+        console.error('Perhaps you need to create it using:');
+        console.error(' $ cp config.example.js '+configFile);
+        console.error('');
+        return 1;
+    }
+    else {
+        console.error('Error while parsing configuration file ('+configFile+')!');
+        console.error('');
+        console.error(e.stack);
+        return 2;
+    }
+}
+
+var devMode = argv.dev || (process.env.NODE_ENV && (process.env.NODE_ENV.slice(0,3) === 'dev'));
+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');
+
+if (devMode) {
+    secureCookies = false;
+
+    // Limit to only 1 worker in dev mode because sessions stored
+    // in memory are not shared between processes.
+    // In dev mode memcached is probably not configure therefore
+    // session storage falls back to memory resulting in sessions
+    // not persisting.
+    numWorkers = 1;
+}
+
+//
+// Setup logger
+//
+var logger = require('./lib/logger.js');
+var log = logger.default;
+
+
+//
+// Fork process
+//
+if (cluster.isMaster) {
+    // 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') +
+        ' mode, spawning ' + numWorkers + ' workers');
+
+    for (var i = 0; i < numWorkers; i++) {
+        cluster.fork();
+    }
+
+
+    cluster.on('exit', function(worker, code, signal) {
+        if (code || signal) {
+            log.error('Worker %d has ended (%s,%s).', worker.id, code, signal);
+        } else {
+            log.fatal('Worker %d has died. Restarting it...', worker.id);
+            cluster.fork();
+        }
+    });
+
+    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
+    //
+    if (!module.parent) {
+        // Only enter the listen loop if the script is executed directly
+        // (like: node server.js, not imported by another script). This check
+        // is useful for running automated tests which don't work if this
+        // module is "stuck" on listen loop.
+
+        log.info('Ready');
+        console.log('Worker '+cluster.worker.id+' listening...');
+
+        app.listen(port);
+    }
+}