Skip to content

Commit b9cdf28

Browse files
committed
Merge branch 'master' of https://github.com/oslabs-beta/Chronos
"example folders and add modal fix"
2 parents c6b0626 + c784f7d commit b9cdf28

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+26186
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
![Chronos logo](https://raw.githubusercontent.com/Chronos2-0/Chronos/master/app/assets/logo2.png)
2+
## Microservices Architecture
3+
Microservices architecture for testing [Chronos](https://github.com/oslabs-beta/Chronos), a microservice communication and health visualizer.
4+
5+
## Purpose and Design - with docker implemented to avoid having to run multiple services in multiple terminals
6+
This sample microservices architecture allows developers to explore the functionality of Chronos but with one docker compose command. This consists of four microservices, which are contained within the directories:
7+
- Reverse Proxy / Frontend
8+
- Books
9+
- Customers
10+
- Orders
11+
12+
Each microservice has its own server, which receives requests from both the client and from other microservices. Books, Customers, and Orders also have their own databases, which they can query to respond to those requests.
13+
The frontend has a reverse proxy set up for proxying requests to the appropriate service in the microservice network. Bear in mind that the use of the word 'services' refers to the individual applications in the microservice network. In development they're all run separately on different ports, with said ports listening out for requests. This is for demonstration and testing purposes. Ideally, in a production environment, all the services will be up and running concurrently from the get go and that's what the docker compose file helps us achieve. It is able to chain all the services and run them together with one command. Docker also ensures that the versions that worked well on dev are bundled up and distributed and used to run the containers for the individual containers.
14+
15+
16+
Run the containerized microservice application with the following command: Because the docker-compose.yml file is located in the main directory of the application, you'll have to be in the main directory folder location for you to properly access the file and run it. That would be Chronos.
17+
18+
`docker-compose -f docker-compose.yml up`
19+
20+
If that doesn't work and you see an error message similar to this: `failed to build: The command '/bin/sh -c npm install' returned a non-zero code: 1` then the error is most likely from the dependency build. You'll have to manually navigate to each service and rum `npm install` for each service dependency to be installed before the image for the container can be created with docker compose.
21+
22+
Next:
23+
24+
**You must replace the placeholder MongoDB Atlas URIs for the databases with your own _actual_ MongoDB Atlas URIs:** Failure to do so means you won't be able to inspect your database.
25+
26+
```
27+
const myURI = 'mongodb+srv://johndoe:[email protected]/';
28+
```
29+
Also, see specific files for specific information on further fuctionality
30+
31+
## Contributing
32+
33+
Chronos hopes to inspire an active community of both users and developers. For questions, comments, or contributions, please submit a pull request.
34+
35+
## People
36+
37+
[Tim Atapagra](https://github.com/timpagra),
38+
[Mohtasim Chowdhury](https://github.com/mohtasim317),
39+
[Ousman Diallo](https://github.com/Dialloousman),
40+
[Michelle Herrera](https://github.com/mesherrera),
41+
[Duane McFarlane](https://github.com/Duane11003),
42+
[Ben Mizel](https://github.com/ben-mizel),
43+
[Jenae Pennie](https://github.com/jenaepen),
44+
[Chris Romano](https://github.com/robicano22),
45+
[Natalie Umanzor](https://github.com/nmczormick)
46+
47+
## License
48+
49+
[MIT](LICENSE)
50+
51+
[npm-image]: https://img.shields.io/npm/v/chronos-microservice-debugger3.svg
52+
[npm-url]: https://www.npmjs.com/package/chronos-microservice-debugger3
53+
[downloads-image]: https://img.shields.io/npm/dm/chronos-microservice-debugger3.svg
54+
[downloads-url]: https://npmjs.org/package/chronos-microservice-debugger3
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
require('dotenv').config();
2+
const fetch = require('node-fetch');
3+
const BookModel = require('./BookModel');
4+
5+
const BookController = {};
6+
7+
// This controller creates a book in the book db
8+
BookController.createBook = (req, res, next) => {
9+
const { title, author, numberOfPages, publisher } = req.body;
10+
BookModel.create(
11+
{
12+
title,
13+
author,
14+
numberOfPages,
15+
publisher,
16+
},
17+
(err, result) => {
18+
if (err) {
19+
console.log(`This is the error I am getting back ${err}`);
20+
return res.send(404).json(err);
21+
}
22+
23+
res.locals.createBook = result;
24+
return next();
25+
}
26+
);
27+
};
28+
29+
// This controller creates a book in the book db
30+
31+
BookController.getBooks = (req, res, next) => {
32+
BookModel.find({}, (err, result) => {
33+
if (err) {
34+
console.log('Book retrieval was not successful', err);
35+
return res.status(404).json(err);
36+
}
37+
res.locals.getBooks = result;
38+
console.log('Book retrieval was successful', res.locals.getBooks);
39+
return next();
40+
});
41+
};
42+
43+
// This controller deletes books
44+
BookController.deleteBook = (req, res, next) => {
45+
const { id } = req.query;
46+
BookModel.findOneAndDelete({ _id: id }, (error, result) => {
47+
if (error) {
48+
console.log(`Deletion was not successful ${error}`);
49+
return res.status(404).json(error);
50+
}
51+
res.locals.deleteBook = result;
52+
return next();
53+
});
54+
};
55+
56+
// This controller gets order info from the order application
57+
BookController.getorderinfo = (req, res, next) => {
58+
console.log('req.headers (in bookController.js):', req.headers);
59+
// const { body } = req;
60+
// since it's a get request, you technically don't need
61+
// all the headers but it's more declarative this way
62+
// fetch(`http://orders:${process.env.ORDERS_PORT}/orders/getorders`, {
63+
fetch(`http://orders:7777/orders/getorders`, {
64+
method: 'GET',
65+
headers: {
66+
'Content-Type': 'Application/JSON',
67+
Accept: 'application/json',
68+
},
69+
})
70+
.then((response) => response.json())
71+
.then((results) => {
72+
// const info = results.forEach((curr) => JSON.stringify((curr)));
73+
res.locals.getorderinfo = results;
74+
return next();
75+
})
76+
.catch((error) => {
77+
console.log(`There was an error in getting orders data ${error}`);
78+
});
79+
};
80+
module.exports = BookController;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const mongoose = require('mongoose');
2+
require('dotenv').config();
3+
4+
// pull schema from the mongoose object
5+
const { Schema } = mongoose;
6+
7+
// DB link for books data.
8+
// Search dotenv documentation for details
9+
const book_db_URI = `${process.env.BOOKS_DB}`;
10+
11+
// const URI = process.env.MONGO_URI || myURI;
12+
13+
// connect the database, if error, log will be sent to the terminal
14+
mongoose
15+
.connect(book_db_URI, { useNewUrlParser: true, useUnifiedTopology: true })
16+
.then(() => console.log('Connected!!!********* Books Database is live!!!'))
17+
.catch((err) => console.log('Connection Error ', err));
18+
19+
// Schema for the database
20+
const BooksSchema = new Schema({
21+
title: {
22+
type: String,
23+
required: true,
24+
},
25+
author: {
26+
type: String,
27+
required: true,
28+
},
29+
numberOfPages: {
30+
type: Number,
31+
required: false,
32+
},
33+
publisher: {
34+
type: String,
35+
required: false,
36+
},
37+
});
38+
39+
// Database Model creation to be exported
40+
const BookModel = mongoose.model('BookModel', BooksSchema);
41+
42+
module.exports = BookModel;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const express = require('express');
2+
const path = require('path');
3+
const cors = require('cors');
4+
const chronos = require('chronos-tracker');
5+
require('./chronos-config');
6+
const controller = require('./BookController.js');
7+
require('dotenv').config();
8+
9+
// Places a unique header on every req in order to trace the path in the req's life cycle.
10+
chronos.propagate();
11+
12+
const app = express();
13+
14+
app.use(express.json());
15+
app.use('/', chronos.track());
16+
17+
app.use(cors());
18+
app.use('/', express.static(path.resolve(__dirname, '../frontend')));
19+
20+
// CHAOS FLOW - SIMPLY A TEST FOR THE EXPESS SERVER
21+
app.use((req, res, next) => {
22+
console.log(
23+
`***************************************************************************************
24+
CHAOS FLOW TEST --- METHOD:${req.method},
25+
PATH: ${req.url},
26+
BODY: ${JSON.stringify(req.body)},
27+
ID: ${req.query.id}
28+
***************************************************************************************`
29+
);
30+
next();
31+
});
32+
33+
// This route will create a new book!
34+
app.post('/books/createbook', controller.createBook, (req, res) => {
35+
res.status(200).json(res.locals.createBook);
36+
});
37+
38+
// This route will delete a book
39+
app.delete('/books/deletebook:id?', controller.deleteBook, (req, res) => {
40+
res.status(200).json(res.locals.deleteBook);
41+
});
42+
43+
// This route will get all the books in the database
44+
app.get('/books/getbooks', controller.getBooks, (req, res) => {
45+
res.status(200).json(res.locals.getBooks);
46+
});
47+
48+
// This route gets orders from the Orders application
49+
app.get('/books/getordersinfo', controller.getorderinfo, (req, res) => {
50+
res.status(200).json(res.locals.getorderinfo);
51+
});
52+
53+
// Global error handler
54+
app.use((error, req, res, next) => {
55+
// console.log(err.stack);
56+
const defaultErr = {
57+
log: 'Express error handler caught unknown middleware error',
58+
status: 400,
59+
message: { err: 'An error occurred' },
60+
};
61+
const errorObj = Object.assign(defaultErr, error);
62+
console.log(`Here is the error object's response: ${errorObj.log}`);
63+
64+
res.status(errorObj.status).json(errorObj.message);
65+
});
66+
67+
// app.listen(process.env.BOOKS_PORT, () => {
68+
// console.log(`Book server running on port ${process.env.BOOKS_PORT} ...`);
69+
// });
70+
71+
app.listen(8888, () => {
72+
console.log(`Book server running on port 8888...`);
73+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM node:10.16
2+
WORKDIR /usr/src/app
3+
COPY package*.json ./
4+
COPY . .
5+
RUN npm install
6+
EXPOSE 8888
7+
ENTRYPOINT ["node", "BookServer.js"]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const chronos = require('chronos-tracker');
2+
3+
chronos.use({
4+
microservice: 'books',
5+
interval: 2000,
6+
dockerized: true,
7+
database: {
8+
type: 'MongoDB',
9+
URI:
10+
' < INSERT MONGODB URL HERE > ',
11+
},
12+
// notifications: [],
13+
});

0 commit comments

Comments
 (0)