Skip to content
This repository was archived by the owner on Dec 4, 2021. It is now read-only.

Commit dca8502

Browse files
authored
Add RPC Client API (#44)
1 parent 2d23d2a commit dca8502

16 files changed

Lines changed: 2489 additions & 19 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.vscode/
22
__pycache__/
33
modules/
4-
node_modules/
4+
node_modules
5+
config.js

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ language: node_js
22
node_js:
33
- "stable"
44
install:
5+
- cp client/config/config.example.js client/config/config.js
56
- npm install
67
script:
78
- npm run lint
9+
- npm run test

client/api/2DPrinting.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const express = require('express');
2+
const router = express.Router();
3+
const { healthCheck, updateSignText } = require('../ledsign/led_sign_client');
4+
const { sendPrintRequest } = require('../printing/print_client');
5+
const { send3dPrintRequest } = require('../printing_3d/print_3d_client');
6+
const {
7+
OK, BAD_REQUEST, NOT_FOUND, LED_SIGN_IP
8+
} = require('../config/config');
9+
const { addSignLog } = require('../util/logging-helpers');
10+
11+
router.post('/Printer/sendPrintRequest', (req, res) => {
12+
const { raw, copies, sides, pageRanges, destination } = req.body;
13+
sendPrintRequest(raw, copies, sides, pageRanges, destination)
14+
.then(response => {
15+
return res.status(OK).send({ ...response });
16+
})
17+
.catch(error => {
18+
return res.status(BAD_REQUEST).send({ ...error });
19+
});
20+
});
21+
22+
module.exports = router;

client/api/3DPrinting.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const express = require('express');
2+
const router = express.Router();
3+
const { healthCheck, updateSignText } = require('../ledsign/led_sign_client');
4+
const { sendPrintRequest } = require('../printing/print_client');
5+
const { send3dPrintRequest } = require('../printing_3d/print_3d_client');
6+
const {
7+
OK, BAD_REQUEST, NOT_FOUND, LED_SIGN_IP
8+
} = require('../config/config');
9+
const { addSignLog } = require('../util/logging-helpers');
10+
11+
router.post('/3dPrinter/print3dModel', (req, res) => {
12+
const { raw, memberName, volume, copies } = req.body;
13+
send3dPrintRequest(raw, memberName, volume, copies)
14+
.then(response => {
15+
return res.status(OK).send({ ...response });
16+
})
17+
.catch(error => {
18+
return res.status(BAD_REQUEST).send({ ...error });
19+
});
20+
});
21+
22+
module.exports = router;

client/api/LedSign.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const express = require('express');
2+
const router = express.Router();
3+
const { healthCheck, updateSignText } = require('../ledsign/led_sign_client');
4+
const { sendPrintRequest } = require('../printing/print_client');
5+
const { send3dPrintRequest } = require('../printing_3d/print_3d_client');
6+
const {
7+
OK, BAD_REQUEST, NOT_FOUND, LED_SIGN_IP
8+
} = require('../config/config');
9+
const { addSignLog } = require('../util/logging-helpers');
10+
11+
router.post('/LedSign/healthCheck', (req, res) => {
12+
const { officerName } = req.body;
13+
healthCheck(officerName, LED_SIGN_IP)
14+
.then(response => {
15+
const { message } = response;
16+
return res.status(OK).send({
17+
text: message.getText(),
18+
brightness: message.getBrightness(),
19+
scrollSpeed: message.getScrollSpeed(),
20+
backgroundColor: message.getBackgroundColor(),
21+
textColor: message.getTextColor(),
22+
borderColor: message.getBorderColor()
23+
});
24+
})
25+
.catch(error => {
26+
return res.status(NOT_FOUND).send({ ...error });
27+
});
28+
});
29+
30+
router.post('/LedSign/updateSignText', async (req, res) => {
31+
if (!await addSignLog(req.body)) {
32+
return res.sendStatus(BAD_REQUEST);
33+
}
34+
updateSignText(req.body, LED_SIGN_IP)
35+
.then(response => {
36+
return res.status(OK).send({ ...response });
37+
})
38+
.catch(error => {
39+
return res.status(NOT_FOUND).send({ ...error });
40+
});
41+
});
42+
43+
module.exports = router;

client/api/SceRpcApiServer.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
const express = require('express');
2+
const bodyParser = require('body-parser');
3+
const cors = require('cors');
4+
const http = require('http');
5+
6+
/**
7+
* Class responsible for resolving paths of API endpoints and combining them
8+
* them into an express server.
9+
*/
10+
class SceRpcApiServer {
11+
/**
12+
* Store port information, create express server object and configure
13+
* BodyParser options.
14+
* @param {(String|Array<String>)} pathToEndpoints The path to a single
15+
* server file, directory or array of directories/files;
16+
* @param {Number} port The port for the server to listen on.
17+
* @param {String} prefix The prefix of the api endpoints to send requests
18+
* to, e.g. /api/Event/addEvent, with /api/ being the prefix.
19+
*/
20+
constructor(pathToEndpoints, port, prefix = '/api/') {
21+
this.runningInProduction = process.env.NODE_ENV === 'production';
22+
this.port = port;
23+
this.pathToEndpoints = pathToEndpoints;
24+
this.prefix = prefix;
25+
this.app = express();
26+
27+
this.app.use(cors());
28+
this.app.use(
29+
bodyParser.json({
30+
// support JSON-encoded request bodies
31+
limit: '50mb',
32+
strict: true
33+
})
34+
);
35+
this.app.use(
36+
bodyParser.urlencoded({
37+
// support URL-encoded request bodies
38+
limit: '50mb',
39+
extended: true
40+
})
41+
);
42+
}
43+
44+
/**
45+
* This function is responsible for taking the pathToEndpoints instance
46+
* variable and resolving API endpoints from it.
47+
*/
48+
async initializeEndpoints() {
49+
// Because this.pathToEndpoints can either be an array or
50+
// string, we need to check before initializing the endpoints.
51+
if (Array.isArray(this.pathToEndpoints)) {
52+
this.pathToEndpoints.map((apiPath) => {
53+
this.app.use(this.prefix, require(apiPath));
54+
});
55+
} else {
56+
this.app.use(this.prefix, require(this.pathToEndpoints));
57+
}
58+
}
59+
60+
/**
61+
* Create the http server and start listening on
62+
* the supplied port.
63+
*/
64+
openConnection() {
65+
this.server = http.createServer(this.app);
66+
const { port } = this;
67+
this.server.listen(port, function() {
68+
console.debug(`Now listening on port ${port}`);
69+
});
70+
}
71+
72+
/**
73+
* Return the current instance of the HTTP server. This function is useful
74+
* for making chai HTTP requests in our API testing files.
75+
* @returns {http.Server} The current instance of the HTTP server.
76+
*/
77+
getServerInstance() {
78+
return this.server;
79+
}
80+
81+
/**
82+
* Stop the server.
83+
*/
84+
closeConnection() {
85+
this.server.close();
86+
}
87+
}
88+
89+
// This if statement checks if the module was require()'d or if it was run
90+
// by node server.js. If we are not requiring it and are running it from the
91+
// command line, we create a server instance and start listening for requests.
92+
if (typeof module !== 'undefined' && !module.parent) {
93+
const apiRoutes = [
94+
__dirname + '2DPrinting.js',
95+
__dirname + '3DPrinting.js',
96+
__dirname + 'LedSign.js'
97+
];
98+
const server = new SceRpcApiServer(
99+
apiRoutes, 8083, '/SceRpcApi/');
100+
server.initializeEndpoints().then(() => {
101+
server.openConnection();
102+
});
103+
}
104+
105+
module.exports = { SceRpcApiServer };

client/config/config.example.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
LED_SIGN_IP: 'localhost',
3+
LOGGING_API_URL: 'http://localhost:8081',
4+
OK: 200,
5+
BAD_REQUEST: 400,
6+
NOT_FOUND: 404
7+
};

client/util/logging-helpers.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const { LOGGING_API_URL } = require('../config/config');
2+
const axios = require('axios');
3+
4+
/**
5+
* Add a new error by calling on the ErrorLog API.
6+
* @param {Object} newError - The error that is to be added
7+
* @param {(string|undefined)} errorToAdd.userEmail - The email of the user
8+
* who has sent this error
9+
* @param {(string|undefined)} errorToAdd.errorTime- The time the error occured
10+
* @param {string} errorToAdd.apiEndpoint - The location of the error
11+
* @param {string} errorToAdd.errordescription - The description of the error
12+
*/
13+
async function addErrorLog(errorToAdd) {
14+
let errorSaved = true;
15+
await axios.post(LOGGING_API_URL + '/api/ErrorLog/addErrorLog',
16+
{ ...errorToAdd })
17+
.catch(err => {
18+
errorSaved = false;
19+
});
20+
return errorSaved;
21+
}
22+
23+
/**
24+
* Add a log to the SignLog MongoDB collection
25+
* @param {Object} signRequest An object containing information about the
26+
* request some of the sign.
27+
* @returns {boolean} If the save was successful or not.
28+
*/
29+
async function addSignLog(signRequest) {
30+
let saveSuccessful = true;
31+
await axios.post(LOGGING_API_URL + '/api/SignLog/addSignLog', {
32+
signText: signRequest.text,
33+
firstName: signRequest.firstName,
34+
email: signRequest.email
35+
}).catch(err => {
36+
saveSuccessful = false;
37+
});
38+
return saveSuccessful;
39+
}
40+
41+
module.exports = { addErrorLog, addSignLog };

0 commit comments

Comments
 (0)