Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Dockerized MongoDb with Seed Data #759

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ app.use(morgan("dev"));
const errorhandler = require('./middleware/errorhandler.middleware');

// ROUTES
const employeesRouter = require('./employees');
const locationsRouter = require('./routers/locations.router');
const healthCheckRouter = require('./routers/healthCheck.router');

app.use('/api/employees', employeesRouter);
app.use('/api/locations', locationsRouter);
app.use('/api/healthcheck', healthCheckRouter);

Expand Down
7 changes: 6 additions & 1 deletion backend/src/config/database.config.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
exports.PORT = process.env.BACKEND_PORT;
exports.DATABASE_URL = process.env.DATABASE_URL;

const DbHost = process.env.DATABASE_HOST;
const DbUrl = DbHost ? `mongodb://${DbHost}:27017`
: process.env.DATABASE_URL;

exports.DATABASE_URL = DbUrl;
12 changes: 12 additions & 0 deletions backend/src/employees/getAll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { EmployeeService } = require("./services/employee.service");

const getAll = async (_, res, next) => {
await EmployeeService
.all()
.then(locations => res.status(200).json(locations))
.catch(next);
}

module.exports = {
getAll
};
9 changes: 9 additions & 0 deletions backend/src/employees/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const express = require("express");
const router = express.Router();

const { getAll } = require("./getAll");

// return all records
router.get('/', getAll);

module.exports = router;
31 changes: 31 additions & 0 deletions backend/src/employees/models/employee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;

/* This is a temp model - used for testing local MongoDB and data generation scripts. */
/* {
"name":"Marcus Hirthe",
"title":"Senior Functionality Designer",
"department":"Operations Management",
"joined":"2020-12-19T14:06:29.007Z"
} */

const employeeSchema = mongoose.Schema({
name: { type: String },
title: { type: String },
department: { type: String },
joined: { type: Date }
});

employeeSchema.methods.serialize = function () {
return {
id: this._id,
name: this.name,
title: this.title,
department: this.department,
joined: this.joined
};
};

const Employee = mongoose.model('Employee', employeeSchema);

module.exports = Employee;
25 changes: 25 additions & 0 deletions backend/src/employees/services/employee.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable func-names */
const Employee = require('../models/employee');
const DatabaseError = require("../../errors/database.error");

const EmployeeService = {};

EmployeeService.all = async function () {
try {
const result = await Employee.find();
return result;
} catch (error) {
throw new DatabaseError(error.message);
}
};

EmployeeService.getByName = async function (name) {
try {
const result = await UserProfile.find({ name });
return result;
} catch (error) {
throw new DatabaseError(error.message);
}
};

module.exports.EmployeeService = EmployeeService;
25 changes: 23 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
version: "3.8"

services:
mongo:
image: "mongo:latest"
expose:
- "27017"
ports:
- "27017:27017"
networks:
- gateway
dbseed:
build:
context: ./mongo
dockerfile: Dockerfile.dev
volumes:
- ./mongo:/srv/mongo
depends_on:
- mongo
networks:
- gateway

backend:
build:
context: ./backend
Expand All @@ -10,12 +29,14 @@ services:
volumes:
- ./backend:/srv/backend
- backend_node_modules:/srv/backend/node_modules
environment:
DATABASE_HOST: mongo
expose:
- "4000"
- "27017"
ports:
- "4000:4000"
- "27017:27017"
depends_on:
- mongo
restart: on-failure
networks:
- gateway
Expand Down
4 changes: 4 additions & 0 deletions mongo/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM mongo:latest
COPY . .
RUN ["chmod", "+x", "init.sh"]
CMD ./init.sh
38 changes: 38 additions & 0 deletions mongo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Summary
This module generates a series of JSON documents that are then treated as seed data for the Mongo database.

It provides an `index.js` script that exposes a command with two parameters:

- **type**: the document type to create
- **amount**: the number of records to create

This command is used to generate test data files that are stored in the `/data` directory.
We generate these files at compile time rather than at runtime to ensure that the same test data is added to all user's environments.

## Workflow for adding a new collection of data

1. Review the [documentation](http://marak.github.io/faker.js/) for the `faker` project.
1. Duplicate the `/scripts/employees.js` file and modify for the new data model.
1. Add the new data model script to the `/scripts/index.js` file.
- Specify the `type` parameter value to associate with the data model.
1. Add a new script to the `package.json` for generating test data for the new model (e.g. `generate:employees`).
1. Run the newly created script to generate the test data file in the `/data` directory.
1. update the `init.sh` file to load the newly created test data file into the relevant database collection.
1. Run the `npm run rebuild` script defined in the `package.json` file to update the docker image.

## Workflow for updating a collection of data
Do this after regenerating test data using the provided script or via manual entry.

1. Run the `npm run rebuild` script defined in the `package.json` file to update the docker image.

# Other Notes
The included `employees` collection is provided as example of how to generate test data.
It is not specified for use in the VRMS project.

## Source Material

- [faker documentation](http://marak.github.io/faker.js/)
- [MongoDB documentation](https://docs.mongodb.com/database-tools/mongoimport/)
- [Running MongoDB in Docker](https://www.bmc.com/blogs/mongodb-docker-container/)

- [Seeding data for MongoDB](https://valenciandigital.com/blog/seeding-data-into-mongodb-using-docker)
12 changes: 12 additions & 0 deletions mongo/data/employees.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7112"},"name":"Austin Wolf","title":"National Implementation Technician","department":"IT","joined":"2020-12-29T16:19:13.798Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7113"},"name":"Mr. Rebecca Prohaska","title":"Legacy Division Representative","department":"Human Resources","joined":"2021-01-28T00:51:24.407Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7114"},"name":"Jerome Yundt","title":"Dynamic Directives Technician","department":"IT","joined":"2021-02-17T10:28:35.191Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7115"},"name":"Billy Rice","title":"Human Response Executive","department":"Marketing","joined":"2020-10-24T01:38:01.527Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7116"},"name":"Billie Dickinson","title":"Corporate Tactics Strategist","department":"IT","joined":"2020-12-11T22:05:23.764Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7117"},"name":"Israel Runolfsdottir","title":"International Program Facilitator","department":"IT","joined":"2021-01-17T17:18:52.826Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7118"},"name":"Beverly Fay","title":"Corporate Security Representative","department":"IT","joined":"2021-04-07T08:25:48.972Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f7119"},"name":"Alexander Lueilwitz PhD","title":"Product Quality Architect","department":"Human Resources","joined":"2020-11-10T07:42:02.373Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f711a"},"name":"Nettie Ankunding","title":"Future Assurance Executive","department":"Human Resources","joined":"2021-02-26T12:43:50.059Z"},
{"_id":{"$oid":"61404aad5dfe7a2d2c8f711b"},"name":"Edmond Ritchie Jr.","title":"International Implementation Orchestrator","department":"IT","joined":"2020-11-26T11:47:20.252Z"}
]
3 changes: 3 additions & 0 deletions mongo/data/locations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
{"_id":{"$oid":"5143afc66d44e1ceb372121e"},"locations":["Los Angeles", "Santa Monica", "Test"]}
]
3 changes: 3 additions & 0 deletions mongo/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
mongoimport --collection employees --file ./data/employees.json --jsonArray --uri "mongodb://mongo:27017"
mongoimport --collection locations --file ./data/locations.json --jsonArray --uri "mongodb://mongo:27017"
17 changes: 17 additions & 0 deletions mongo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "vrms-mongo-setup",
"version": "0.1.0",
"description": "VRMS Database Seed Scripts",
"license": "AGPL-3.0",
"author": "HackForLA",
"main": "./scripts/index.js",
"scripts": {
"rebuild": "cd ../ && docker-compose build dbseed",
"generate:employees": "node ./scripts/index.js --type employee --amount 10"
},
"devDependencies": {
"faker": "^5.5.3",
"mongodb": "^3.x.x",
"yargs": "^17.1.1"
}
}
33 changes: 33 additions & 0 deletions mongo/scripts/employees.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const faker = require("faker");
const { ObjectID } = require("mongodb");

const generateEmployees = (amount) => {
let employees = [];
for (x = 0; x < amount; x++) {
employees.push(createEmployee());
}
return employees;
};
const createEmployee = () => {
const companyDepartments = [
"Marketing",
"Finance",
"Operations Management",
"Human Resources",
"IT",
];
const employeeDepartment = companyDepartments[Math.floor(Math.random() * companyDepartments.length)];
const employee = {
"_id": {"$oid":new ObjectID()},
name: faker.name.findName(),
title: faker.name.jobTitle(),
department: employeeDepartment,
joined: faker.date.past(),
};

return employee;
};

module.exports = {
generateEmployees,
};
36 changes: 36 additions & 0 deletions mongo/scripts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const yargs = require("yargs");
const fs = require("fs");
const { generateEmployees } = require("./employees.js");

// Define Command
const argv = yargs.command("amount", "Decides the number of records to generate", {
type: {
description: "the type of record to generate",
alias: "t",
type: "string"
},
amount: {
description: "The amount to generate",
alias: "a",
type: "number"
},
})
.help()
.alias("help", "h").argv;

if(!argv.hasOwnProperty("type")) throw new Error("Document type not specified.");
if(!argv.hasOwnProperty("amount") || argv.amount < 1) throw new Error("Amount of records to create not specified.");

const type = argv.type.toLowerCase();
const amount = argv.amount;

// Generate Employee data
if (type === "employee") {
const employees = generateEmployees(amount);
const json = JSON.stringify(employees);
fs.writeFileSync("./data/employees.json", json);
return;
}

// Handle non-supported document types
throw new Error(`Document type: '${type}' not supported.`);
Loading