add sample for ch10s03 lab

This commit is contained in:
Student User 2019-08-02 19:48:17 +00:00
parent c2f929499e
commit e5e3675beb
6 changed files with 349 additions and 0 deletions

36
todo-backend/app.js Normal file
View file

@ -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)))
});
*/

View file

@ -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);
}
});
}
}

View file

@ -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();
};

10
todo-backend/models/db.js Normal file
View file

@ -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',
}
};

View file

@ -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);
});
}

16
todo-backend/package.json Normal file
View file

@ -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"
}
}