Skip to content
This repository has been archived by the owner on Apr 16, 2021. It is now read-only.

Commit

Permalink
index retailers, inventories, shipments, line items per demoId allowi…
Browse files Browse the repository at this point in the history
…ng data isolation between two demo environments
  • Loading branch information
Frederic Lavigne committed Jun 2, 2016
1 parent 810e88e commit 23019a1
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 95 deletions.
214 changes: 147 additions & 67 deletions common/models/demo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Licensed under the Apache License. See footer for details.
var winston = require('winston');
var helper = require("./helper.js");
var async = require("async");
var bcrypt = require("bcryptjs");
Expand All @@ -12,61 +13,85 @@ function makeUniqueSession(demo) {
}

module.exports = function (Demo) {

//console.log(Demo.definition.modelBuilder.models);
Demo.ISOLATED_MODELS = [ //
Demo.definition.modelBuilder.models.Inventory,
Demo.definition.modelBuilder.models.Retailer,
Demo.definition.modelBuilder.models.Shipment,
Demo.definition.modelBuilder.models.LineItem
];

helper.hideAll(Demo);
helper.hideRelation(Demo, "users");

function seed(model, callback) {
console.log("Seeding", model.definition.name);
model.count(function (err, count) {
function seed(model, demoId, callback) {
winston.info("Seeding " + model.definition.name);

var where = {};
if (demoId) {
where.demoId = demoId;
}

model.count(where, function (err, count) {
if (err) {
console.log(err);
callback(null);
winston.error(err);
callback(err);
} else if (count == 0) {
var objects = JSON.parse(fs.readFileSync("./seed/" + model.definition.name.toLowerCase() + ".json"));
console.log("Injecting", objects.length, model.definition.name);
// inject the demoId if needed
if (demoId) {
objects.forEach(function (object) {
object.demoId = demoId;
if (object.id) {
object.id = object.id + "-" + object.demoId;
}
// if Shipment and toId (RetailerId) then fix the toId too
if (model.modelName == "Shipment") {
object.toId = object.toId + "-" + object.demoId;
}
});
}
winston.info("Injecting", objects.length, model.definition.name);
model.create(objects, function (err, records) {
if (err) {
console.log("Failed to create", model.definition.name, err);
winston.error("Failed to create", model.definition.name, err);
} else {
console.log("Created", records.length, model.definition.name);
winston.info("Created", records.length, model.definition.name);
}
callback(null);
});
} else {
console.log("There are already", count, model.definition.name);
winston.warn("There are already", count, model.definition.name);
callback(null);
}
});
};

Demo.seed = function (cb) {
console.log("Seeding...");
winston.info("Seeding...");
async.waterfall(
[ //
[
Demo.app.models.Supplier,
Demo.app.models.Product,
Demo.app.models.DistributionCenter,
Demo.app.models.Inventory,
Demo.app.models.Retailer,
Demo.app.models.Shipment,
Demo.app.models.LineItem,
Demo.app.models.DistributionCenter
].map(function (model) {
return function (callback) {
seed(model, callback);
seed(model, undefined, callback);
};
}),
function (err, result) {
if (err) {
console.log(err);
winston.error(err);
} else {
console.log("Inject complete");
winston.info("Inject complete");
}
cb(err);
});
};

Demo.remoteMethod('seed', {
description: 'Injects sample data in the service',
description: 'Injects sample shared data in the service',
http: {
path: '/seed',
verb: 'post'
Expand All @@ -84,27 +109,28 @@ module.exports = function (Demo) {
Demo.app.models.Shipment,
Demo.app.models.LineItem,
Demo.app.models.Demo,
Demo.app.models.ERPUser
Demo.app.models.ERPUser,
Demo.app.models.AccessToken
].map(function (model) {
return function (callback) {
console.log("Deleting all", model.definition.name);
winston.info("Deleting all", model.definition.name);
model.destroyAll(function (err, result) {
callback(err);
});
};
}),
function (err, result) {
if (err) {
console.log(err);
winston.error(err);
} else {
console.log("Reset complete");
winston.info("Reset complete");
}
cb(err);
});
};

Demo.remoteMethod('reset', {
description: 'Resets the demo data',
description: 'Deletes all data',
http: {
path: '/reset',
verb: 'post'
Expand All @@ -119,7 +145,7 @@ module.exports = function (Demo) {
async.waterfall([
// create a new demo environment
function (callback) {
console.log("Creating new Demo instance");
winston.info("Creating new Demo instance");
Demo.create({
name: data.name
}, function (err, demo) {
Expand All @@ -128,15 +154,38 @@ module.exports = function (Demo) {
},
// make a unique guid for the demo environment
function (demo, callback) {
console.log("Generating guid for Demo");
winston.info("Generating guid for Demo");
demo.guid = makeUniqueSession(demo);
Demo.upsert(demo, function (err, demo) {
callback(err, demo);
});
},
// insert default data, indexed on the demo.id
function (demo, callback) {
winston.info("Inserting demo data");
async.waterfall(
[ //
Demo.app.models.Inventory,
Demo.app.models.Retailer,
Demo.app.models.Shipment,
Demo.app.models.LineItem
].map(function (model) {
return function (seedCallback) {
seed(model, demo.id, seedCallback);
};
}),
function (err, result) {
if (err) {
winston.error(err);
} else {
winston.info("Inject complete");
}
callback(err, demo);
});
},
// create the supply chain manager
function (demo, callback) {
console.log("Creating Supply Chain Manager user");
winston.info("Creating Supply Chain Manager user");
var random = randomstring.generate(10)
var supplyChainManager = {
email: "chris." + random + "@acme.com",
Expand All @@ -151,7 +200,7 @@ module.exports = function (Demo) {
},
// assign roles to the users
function (demo, user, callback) {
console.log("Assigning role to Supply Chain Manager");
winston.info("Assigning role to Supply Chain Manager");
Demo.app.models.ERPUser.assignRole(user,
Demo.app.models.ERPUser.SUPPLY_CHAIN_MANAGER_ROLE,
function (err, principal) {
Expand All @@ -160,7 +209,7 @@ module.exports = function (Demo) {
},
// returns the demo, its users and the roles
function (demo, callback) {
console.log("Retrieving Demo and its users");
winston.info("Retrieving Demo and its users");
Demo.findById(demo.id, {
include: {
relation: 'users',
Expand All @@ -174,7 +223,6 @@ module.exports = function (Demo) {
function (err, demo) {
callback(err, demo);
});
// insert default shipments and inventories
}
], function (err, result) {
cb(err, result);
Expand Down Expand Up @@ -265,13 +313,17 @@ module.exports = function (Demo) {
notFound.status = 404
callback(notFound);
} else {
callback(err);
callback(err, demo);
}
});
},
// retrieve the user linked to this demo
function (callback) {
Demo.app.models.Retailer.find(function (err, retailers) {
// retrieve the retailers linked to this demo
function (demo, callback) {
Demo.app.models.Retailer.find({
where: {
demoId: demo.id
}
}, function (err, retailers) {
callback(err, retailers);
});
}
Expand Down Expand Up @@ -379,33 +431,64 @@ module.exports = function (Demo) {

// Delete users associated to a demo environment
Demo.observe("after delete", function (context, next) {
console.log("Deleting users linked to demo", context.where.id);
Demo.app.models.ERPUser.find({
where: {
demoId: context.where.id
}
}, function (err, users) {
if (err) {
next(err);
} else if (users.length == 0) {
next();
} else {
async.waterfall(users.map(function (user) {
return function (callback) {
console.log("Deleting user", user.email);
user.destroy(function () {
if (context.where.id) {
// delete all objects linked to the demo
var tasks = [];
[ //
Demo.app.models.Inventory,
Demo.app.models.Retailer,
Demo.app.models.Shipment,
Demo.app.models.LineItem
].forEach(function (model) {
tasks.push(function (callback) {
winston.info("Deleting", model.modelName, "linked to demo", context.where.id);
model.destroyAll({
demoId: context.where.id
}, function (err, info) {
if (err) {
winston.error(err);
}
callback(null);
});
});
});

// and its users
tasks.push(function (callback) {
winston.info("Deleting users linked to demo", context.where.id);
Demo.app.models.ERPUser.find({
where: {
demoId: context.where.id
}
}, function (err, users) {
if (err || users.length == 0) {
callback();
} else {
async.waterfall(users.map(function (user) {
return function (callback) {
winston.info("Deleting user", user.email);
user.destroy(function () {
callback();
});
}
}), function (err, result) {
callback();
});
}
}), function (err, result) {
next();
});
}
});
});

async.waterfall(tasks, function (err, result) {
next();
});

} else {
next();
}
});

Demo.deleteByGuid = function (guid, cb) {
console.log("Deleting demo with guid", guid);
winston.info("Deleting demo with guid", guid);
async.waterfall([
// retrieve the demo
function (callback) {
Expand All @@ -427,7 +510,7 @@ module.exports = function (Demo) {
function (demo, callback) {
Demo.destroyById(demo.id,
function (err, info) {
console.log("Deleted demo", demo.id);
winston.info("Deleted demo", demo.id);
callback(err, demo);
});
}
Expand Down Expand Up @@ -456,7 +539,7 @@ module.exports = function (Demo) {
});

Demo.createUserByGuid = function (guid, retailerId, cb) {
console.log("Adding new Retail Store Manager to demo with guid", guid, retailerId);
winston.info("Adding new Retail Store Manager to demo with guid", guid, retailerId);

var app = Demo.app;

Expand All @@ -479,21 +562,18 @@ module.exports = function (Demo) {
},
// retrieve the store
function (demo, callback) {
app.models.Retailer.findById(retailerId, function (err, retailer) {
app.models.Retailer.findOne({
where: {
id: retailerId,
demoId: demo.id
}
}, function (err, retailer) {
if (!err && !retailer) {
var notFound = new Error("No retailer with this id");
notFound.status = 404
callback(notFound);
} else {
// check that the store demoId is the same as the user demoId
if (retailer.demoId && retailer.demoId != demo.id) {
// can't assign a manager from another demo with this one
var invalidDemoId = new Error("Demo id does not match the one from the retail store");
invalidDemoId.status = 400;
callback(invalidDemoId);
} else {
callback(err, demo, retailer);
}
callback(err, demo, retailer);
}
});
},
Expand Down
Loading

0 comments on commit 23019a1

Please sign in to comment.