From e5e3675bebd2a6fbb5b5ffaf4403c4039b25a5ea Mon Sep 17 00:00:00 2001 From: Student User <student@workstation.lab.example.com> Date: Fri, 02 Aug 2019 21:48:17 +0200 Subject: [PATCH] add sample for ch10s03 lab --- todo-backend/controllers/items.js | 131 +++++++++++++++++++++ todo-backend/models/items.js | 127 +++++++++++++++++++++ todo-backend/controllers/serverinfo.js | 29 ++++ todo-backend/package.json | 16 ++ todo-backend/models/db.js | 10 + todo-backend/app.js | 36 ++++++ 6 files changed, 349 insertions(+), 0 deletions(-) diff --git a/todo-backend/app.js b/todo-backend/app.js new file mode 100644 index 0000000..af05312 --- /dev/null +++ b/todo-backend/app.js @@ -0,0 +1,36 @@ +var restify = require('restify'); + +var controller = require('./controllers/items'); +var serverinfo = require('./controllers/serverinfo'); + +var db = require('./models/db'); +var model = require('./models/items'); + +model.connect(db.params, function(err) { + if (err) throw err; +}); + +var server = restify.createServer() + .use(restify.fullResponse()) + .use(restify.queryParser()) + .use(restify.bodyParser()) + .use(restify.CORS());; + +controller.context(server, '/todo/api', model); +serverinfo.context(server, '/todo/api'); + +var port = process.env.PORT || 8080; +server.listen(port, function (err) { + if (err) + console.error(err); + else + console.log('App is ready at : ' + port); +}); + + +/* +process.on('uncaughtException', function (err) { + console.error(JSON.parse(JSON.stringify(err, ['stack', 'message', 'inner'], 2))) +}); +*/ + diff --git a/todo-backend/controllers/items.js b/todo-backend/controllers/items.js new file mode 100644 index 0000000..3a6eeb2 --- /dev/null +++ b/todo-backend/controllers/items.js @@ -0,0 +1,131 @@ + +var model = undefined; + +exports.context = function(server, path, itemsModel) { + if (!server) + done('has to provide a restify server object'); + + var context = "/items"; + if (path) + context = path + context; + + server.get(context + '/', this.list); + server.get(context + '/:id', this.read); + server.get(context + '-count', this.count); + server.post(context + '/', this.save); + server.del(context + '/:id', this.destroy); + + model = itemsModel; +}; + +exports.list = function(req, res, next) { + var page_no = req.query.page || 1; + var sortField = req.query.sortFields || "id"; + var sortDirection = req.query.sortDirections || "asc"; + + model.listAll(page_no, sortField, sortDirection, function(err, items) { + if (err) { + res.send(err); + } + else { + if (items) { + model.countAll(function(err, n) { + if (err) { + res.send(err); + } + else { + if (n) { + var page = { + "currentPage" : page_no, + "list" : items, + "pageSize" : 10, + "sortDirections" : sortDirection, + "sortFields" : sortField, + "totalResults" : n + }; + res.json(page); + next(); + } + } + }); + } + else { + res.send(err); + } + } + }) +}; + +exports.read = function(req, res, next) { + var key = req.params.id; + model.read(key, function(err, item) { + if (err) { + res.send(err); + } + else { + if (item) { + res.json(item); + next(); + } + else { + res.send(err); + } + } + }) +}; + + +exports.count = function(req, res, next) { + model.countAll(function(err, n) { + if (err) { + res.send(err); + } + else { + var page = { + count: n + }; + res.json(page) + next(); + } + }) +}; + + +exports.save = function(req, res, next) { + if (req.params.id) { + model.update(req.params.id, req.params.description, req.params.done, function(err, item) { + if (err) { + res.send(err); + } + else { + res.json(item); + next(); + } + }); + } + else { + model.create(req.params.description, req.params.done, function(err, item) { + if (err) { + res.send(err); + } + else { + res.json(item); + next(); + } + }); + } +}; + + +exports.destroy = function(req, res, next) { + if (req.params.id) { + model.destroy(req.params.id, function(err, item) { + if (err) { + res.send(err); + } + else { + res.json(item); + } + }); + } +} diff --git a/todo-backend/controllers/serverinfo.js b/todo-backend/controllers/serverinfo.js new file mode 100644 index 0000000..00f4b58 --- /dev/null +++ b/todo-backend/controllers/serverinfo.js @@ -0,0 +1,29 @@ +var os = require('os'); + +exports.context = function(server, path) { + if (!server) + done('has to provide a restify server object'); + + server.get(path + '/host', this.serverInfo); +}; + +exports.serverInfo = function(req, res, next) { + var address; + var ifaces = os.networkInterfaces(); + + for (var dev in ifaces) { + var iface = ifaces[dev].filter(function(details) { + return details.family === 'IPv4' && details.internal === false; + }); + if (iface.length > 0) + address = iface[0].address; + } + + var reply = { + ip: address, + hostname: os.hostname() + }; + res.json(reply); + next(); +}; + diff --git a/todo-backend/models/db.js b/todo-backend/models/db.js new file mode 100644 index 0000000..1135d1d --- /dev/null +++ b/todo-backend/models/db.js @@ -0,0 +1,10 @@ + +module.exports.params = { + dbname: process.env.DATABASE_NAME, + username: process.env.DATABASE_USER, + password: process.env.DATABASE_PASSWORD, + params: { + host: process.env.DATABASE_SVC, + dialect: 'mysql', + } +}; diff --git a/todo-backend/models/items.js b/todo-backend/models/items.js new file mode 100644 index 0000000..ef35e81 --- /dev/null +++ b/todo-backend/models/items.js @@ -0,0 +1,127 @@ +var Sequelize = require("sequelize"); + +var Item = undefined; + +module.exports.connect = function(params, callback) { + var sequlz = new Sequelize( + params.dbname, params.username, params.password, + params.params); + Item = sequlz.define('Item', { + id: { type: Sequelize.BIGINT, + primaryKey: true, unique: true, allowNull: false, + autoIncrement: true }, + description: { type: Sequelize.STRING, + allowNull: true }, + done: { type: Sequelize.BOOLEAN, + allowNull: true } + }, { + timestamps: false, + freezeTableName: true + }); + + if (process.env.DATABASE_INIT == 'true') { + Item.sync({ force: true }).then(function() { + callback(); + }).catch(function(err) { + callback(err); + }); + } +} + +exports.disconnect = function(callback) { + //XXX shouln'd to something to close or release the db connection? + callback(); +} + +exports.create = function(description, done, callback) { + Item.create({ + //id: id, + description: description, + done: (done) ? true : false + }).then(function(item) { + callback(null, item); + }).catch(function(err) { + callback(err); + }); +} + +exports.update = function(key, description, done, callback) { + Item.find({ where:{ id: key } }).then(function(item) { + if (!item) { + callback(new Error("Nothing found for key " + key)); + } + else { + item.updateAttributes({ + description: description, + done: (done) ? true : false + }).then(function() { + callback(null, item); + }).error(function(err) { + callback(err); + }); + } + }).catch(function(err) { + callback(err); + }); +} + + +exports.read = function(key, callback) { + Item.find({ where:{ id: key } }).then(function(item) { + if (!item) { + callback(new Error("Nothing found for key " + key)); + } + else { + //XXX why recreating the item object? + callback(null, { + id: item.id, + description: item.description, + done: item.done + }); + } + }).catch(function(err) { + callback(err); + }); +} + +exports.destroy = function(key, callback) { + Item.find({ where:{ id: key } }).then(function(item) { + if (!item) { + callback(new Error("Nothing found for " + key)); + } + else { + item.destroy().then(function() { + callback(null, item); + }).error(function(err) { + callback(err); + }); + } + }).catch(function(err) { + callback(err); + }); +} + +exports.countAll = function(callback) { + Item.findAll({ + attributes: [[Sequelize.fn('COUNT', Sequelize.col('id')), 'no_items']] + }).then(function(n) { + callback(null, n[0].get('no_items')); + }).catch(function(err) { + callback(err); + }); +} + +exports.listAll = function(page, sortField, sortDirection, callback) { + Item.findAll({ offset: 10 * (page - 1), limit: 10, order: [[sortField, sortDirection]] }).then(function(items) { + var theitems = []; + items.forEach(function(item) { + //XXX why recreating the item objects for theitems? + theitems.push({ + id: item.id, description: item.description, done: item.done }); + }); + callback(null, theitems); + }).catch(function(err) { + callback(err); + }); +} + diff --git a/todo-backend/package.json b/todo-backend/package.json new file mode 100644 index 0000000..1d197b2 --- /dev/null +++ b/todo-backend/package.json @@ -0,0 +1,16 @@ +{ + "name": "todo-single", + "description": "single container version of the todoapp", + "version": "0.0.2", + "private": true, + "author": "Red Hat Training", + "license": "ASL", + "scripts": { + "start": "node app.js" + }, + "dependencies": { + "restify": "4.0.3", + "sequelize": "3.14.2", + "mysql": "2.9.0" + } +} -- Gitblit v1.9.3