Commit 9622a83d authored by Dennis Willers's avatar Dennis Willers 🏀

Init

parent ffccf8bb
Pipeline #439 failed with stages
in 25 seconds
DB_HOST=
DB_PORT=
DB_USER=
DB_PASS=
DB_DATABASE=
......@@ -44,3 +44,6 @@ testem.log
# System Files
.DS_Store
Thumbs.db
# Ignore env
.env
......@@ -5,12 +5,17 @@ stages:
- delete
- deploy
before_script:
- chmod +x ./setup_env.sh
- ls
- ./setup_env.sh
docker-build:
stage: build
script:
- docker login hub.willers.digital -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
- docker build -t hub.willers.digital/dennis.willers/tabu-middleware .
- docker push hub.willers.digital/dennis.willers/tabu-middleware:latest
- docker build -t hub.willers.digital/dennis.willers/voting .
- docker push hub.willers.digital/dennis.willers/voting:latest
delete-old-container:
stage: delete
......@@ -22,9 +27,9 @@ delete-old-container:
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
script:
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker stop tabu-middleware"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker rm tabu-middleware"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker rmi -f hub.willers.digital/dennis.willers/tabu-middleware:latest"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker stop voting"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker rm voting"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker rmi -f hub.willers.digital/dennis.willers/voting:latest"
only:
- master
allow_failure: true
......@@ -41,7 +46,7 @@ docker-deploy:
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
script:
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker login hub.willers.digital -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker pull hub.willers.digital/dennis.willers/tabu-middleware:latest"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker run -d -p 3150:8080 -p 3000:3000 --restart=always --mount type=bind,src=/volume1/docker/tmp6,dst=/tmp --name tabu-middleware hub.willers.digital/dennis.willers/tabu-middleware:latest"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker pull hub.willers.digital/dennis.willers/voting:latest"
- ssh root@willers.digital -p 2233 "/usr/local/bin/docker run -d -p 3200:8080 -p 3201:3000 --restart=always --mount type=bind,src=/volume1/docker/tmp6,dst=/tmp --name voting hub.willers.digital/dennis.willers/voting:latest"
only:
- master
const express = require('express');
function createRouter(db) {
const router = express.Router();
function isMapIdAndNameNotNull(req) {
const mapId = req.body.mapId;
const name = req.body.name;
return mapId != null && name != null;
}
function isVoteRequestValid(req) {
const userId = req.body.userId;
const vote = req.body.vote;
return userId != null && vote != null && isMapIdAndNameNotNull(req);
}
function isgetMapInfoValid(req) {
const userId = req.body.userId;
return userId != null && isMapIdAndNameNotNull(req);
}
const hasMap = function hasMap(req, res, next) {
const mapId = req.body.mapId;
if (isMapIdAndNameNotNull(req)) {
const sql = 'SELECT count(*) as Maps From Map WHERE mapId = \"'+mapId+'\";';
console.log('Map Select: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in hasMap'});
} else {
numberResults = results[0].Maps;
if (numberResults === 1) next();
else if (numberResults === 0) addMap(req, res, next);
else res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'There are multiple maps with the same id'});
}
});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'JSON-Parameter are not valid'});
}
};
const addMap = function addMap(req, res, next) {
const mapId = req.body.mapId;
const name = req.body.name;
const sql = 'INSERT INTO Map (mapId, name) VALUES (\"'+mapId+'\", \"'+name+'\");';
console.log('Map Insert: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in addMap'});
} else {
if (results.affectedRows === 1) next();
else res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in insertMap'});
}
});
};
const hasVote = function hasVote(req, res, next) {
if (isVoteRequestValid(req)) {
const userId = req.body.userId;
const mapId = req.body.mapId;
const sql = 'SELECT userId FROM Vote WHERE userId = \"'+ userId + '\" AND mapId = \"' + mapId + '\";';
console.log('Map Insert: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in hasVote'});
} else {
if (results.length === 0) insertVote(req, res, next);
else if (results.length === 1) updateVote(req, res, next);
else res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'too many votes by user'});
}
});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'Vote Request is not valid'});
}
};
const insertVote = function insertVote(req, res, next) {
if (isVoteRequestValid(req)) {
const userId = req.body.userId;
const mapId = req.body.mapId;
const vote = req.body.vote;
const sql = 'INSERT INTO Vote (userId, mapId, vote) VALUES (\"'+ userId + '\", \"'+ mapId + '\", \"' + vote +'\");';
console.log('Insert Vote: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in insertVote'});
} else {
if (results.affectedRows === 1) next();
else res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in insertVote'});
}
});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'Vote Request is not valid'});
}
};
const updateVote = function updateVote(req, res, next) {
if (isVoteRequestValid(req)) {
const userId = req.body.userId;
const mapId = req.body.mapId;
const vote = req.body.vote;
const sql = 'UPDATE Vote SET userId = \"'+ userId + '\", mapId = \"'+ mapId + '\", vote = \"' + vote +'\" WHERE userID = \"'+ userId +'\" AND mapId = \"' + mapId + '\";';
console.log('Update Vote: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in updateVote'});
} else {
if (results.affectedRows === 1) next();
else res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in updateVote'});
}
});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'Vote Request is not valid'});
}
};
const getMapInfo = function getMapInfo(req, res) {
if (isVoteRequestValid(req)) {
const mapId = req.body.mapId;
const vote = req.body.vote;
const sql = 'SELECT count(userId) as votes, round(avg(vote)) as average FROM Vote WHERE mapId LIKE \"'+ mapId + '\";';
console.log('getMapInfo: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in getMapInfo'});
} else {
if (results.length === 1) {
let average = results[0].average;
let votes = results[0].votes;
if (!average) average = 0;
if (!votes) votes = 0;
res.header('Access-Control-Allow-Origin', "*").status(200).json({votes: votes, average: average, vote: vote});
return;
}
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'unexpected result in getMapInfo'});
}
});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'Vote Request is not valid'});
}
};
const getVote = function getVote(req, res) {
if (isgetMapInfoValid(req)) {
const mapId = req.body.mapId;
const userId = req.body.userId;
const sql = 'SELECT vote FROM Vote WHERE mapId LIKE \"'+ mapId + '\" AND userId LIKE \"' + userId + '\";';
console.log('Update Vote: ', sql);
db.query(
sql,
(error, results) => {
if (error) {
console.log(error);
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'error in getVote'});
} else {
if (results.length < 2) {
let vote = -1;
if (results.length === 1) {
vote = results[0].vote;
}
if (!isNaN(vote)) {
req.body.vote = vote;
getMapInfo(req, res);
return;
}
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'unexpected result in getVote'});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'too many results in getVote'});
}
}
});
} else {
res.header('Access-Control-Allow-Origin', "*").status(500).json({status: 'Vote Request is not valid'});
}
};
const test = function test(req, res) {
res.header('Access-Control-Allow-Origin', "*").status(200).json({status: "Test valid!"});
};
// the routes are defined here
router.get('/test', [test]);
router.post('/setVote', [hasMap, hasVote, getMapInfo]);
router.post('/getMapInfo', [hasMap, getVote]);
return router;
}
module.exports = createRouter;
const axios = require('axios');
/**
* @return {boolean}
*/
function isJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function checkIfRequestHasVote(json) {
console.log("Has Vote: " + JSON.parse(json).hasOwnProperty('vote'), json);
return JSON.parse(json).hasOwnProperty('vote');
}
function sendRequest(url, json, callback) {
//make post request
axios
.post(url, JSON.parse(json))
.then(res => {
//echo data
callback(res);
})
.catch(error => {
console.error(error);
callback(null);
});
}
function addMapToClient(clientList, currentClient, mapId, callback) {
clientList.forEach(client => {
if (client.name === currentClient.name) {
client.mapId = mapId;
console.log("Client Map ID found");
}
});
return callback(clientList);
}
module.exports = {
isJsonString,
checkIfRequestHasVote,
sendRequest,
addMapToClient
};
require('./socket');
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const events = require('./events');
const connection = mysql.createConnection({
host : process.env.DB_HOST,
port : process.env.DB_PORT,
user : process.env.DB_USER,
password : process.env.DB_PASS,
database : process.env.DB_DATABASE,
multipleStatements: true,
});
connection.connect();
const port = process.env.PORT || 8080;
const app = express()
.use(cors())
.use(bodyParser.json())
.use(events(connection));
app.listen(port, () => {
console.log(`Express server listening on port ${port}`);
});
This diff is collapsed.
{
"name": "Voting",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js",
"debug": "nodemon --inspect index.js"
},
"keywords": [],
"author": "Dennis Willers",
"license": "ISC",
"dependencies": {
"axios": "^0.21.1",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"mysql": "^2.18.1"
},
"devDependencies": {
"nodemon": "^2.0.7"
}
}
#!/bin/bash
echo DB_HOST=$DB_HOST >> .env
echo DB_PORT=$DB_PORT >> .env
echo DB_USER=$DB_USER >> .env
echo DB_PASS=$DB_PASS >> .env
echo DB_DATABASE=$DB_DATABASE >> .env
var net = require('net');
var hf = require('./helpFunctions');
// creates the server
var server = net.createServer();
var clients = [];
//emitted when server closes ...not emitted until all connections closes.
server.on('close',function(){
console.log('Server closed !');
});
// emitted when new client connects
server.on('connection',function(socket){
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort;
socket.mapId = "null";
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the chat\n", socket);
//this property shows the number of characters currently buffered to be written. (Number of characters is approximately equal to the number of bytes to be written, but the buffer may contain strings, and the strings are lazily encoded, so the exact number of bytes is not known.)
//Users who experience large or growing bufferSize should attempt to "throttle" the data flows in their program with pause() and resume().
console.log('Buffer size : ' + socket.bufferSize);
console.log('---------server details -----------------');
var address = server.address();
var port = address.port;
var family = address.family;
var ipaddr = address.address;
console.log('Server is listening at port' + port);
console.log('Server ip :' + ipaddr);
console.log('Server is IP4/IP6 : ' + family);
var lport = socket.localPort;
var laddr = socket.localAddress;
console.log('Server is listening at LOCAL port' + lport);
console.log('Server LOCAL ip :' + laddr);
console.log('------------remote client info --------------');
var rport = socket.remotePort;
var raddr = socket.remoteAddress;
var rfamily = socket.remoteFamily;
console.log('REMOTE Socket is listening at port' + rport);
console.log('REMOTE Socket ip :' + raddr);
console.log('REMOTE Socket is IP4/IP6 : ' + rfamily);
console.log('--------------------------------------------')
//var no_of_connections = server.getConnections(); // sychronous version
server.getConnections(function(error,count){
console.log('Number of concurrent connections to the server : ' + count);
});
socket.setEncoding('utf8');
socket.setTimeout(800000,function(){
// called after timeout -> same as socket.on('timeout')
// it just tells that soket timed out => its ur job to end or destroy the socket.
// socket.end() vs socket.destroy() => end allows us to send final data and allows some i/o activity to finish before destroying the socket
// whereas destroy kills the socket immediately irrespective of whether any i/o operation is goin on or not...force destry takes place
console.log('Socket timed out');
});
socket.on('data',function(data){
console.log('Data sent to server : ' + data);
if(hf.isJsonString(data)) {
let url;
if (hf.checkIfRequestHasVote(data)) {
url = 'http://localhost:8080/setVote';
} else {
url ='http://localhost:8080/getMapInfo';
}
hf.sendRequest(url, data, res => {
if (res) {
const req = JSON.parse(data);
hf.addMapToClient(clients, socket, req['mapId'], newClientList => {
clients = newClientList.slice();
socket.write(JSON.stringify(res.data) + '\n');
if (hf.checkIfRequestHasVote(data)) {
sendToAllClientsAtSameMap(res, req['mapId'], socket);
}
});
//var is_kernel_buffer_full = socket.write(JSON.stringify(res.data) + '\n');
//if(is_kernel_buffer_full){
// console.log('Data was flushed successfully from kernel buffer i.e written successfully!');
//} else {
// socket.pause();
//}
} else {
console.log("Res was null");
}
});
}
});
socket.on('drain',function(){
console.log('write buffer is empty now .. u can resume the writable stream');
socket.resume();
});
socket.on('error',function(error){
console.log('Error : ' + error);
});
socket.on('timeout',function(){
console.log('Socket timed out !');
socket.end('Timed out!');
// can call socket.destroy() here too.
});
socket.on('end',function(data){
console.log('Socket ended from other end!');
console.log('End data : ' + data);
});
socket.on('close',function(error){
var bread = socket.bytesRead;
var bwrite = socket.bytesWritten;
console.log('Bytes read : ' + bread);
console.log('Bytes written : ' + bwrite);
console.log('Socket closed!');
if(error){
console.log('Socket was closed coz of transmission error');
}
});
setTimeout(function(){
var isdestroyed = socket.destroyed;
console.log('Socket destroyed:' + isdestroyed);
socket.destroy();
},1200000);
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
// Send a message to all clients playing the same map
function sendToAllClientsAtSameMap(res, mapId, currentClient) {
console.log("JSON: ", JSON.stringify(res.data));
clients.forEach(function (client) {
const resJson = res.data;
delete resJson['vote'];
if (client.mapId === mapId && client.name !== currentClient) client.write(JSON.stringify(resJson) + '\n');
});
console.log("Write Message to all at " + mapId +": " + JSON.stringify(res.data));
}
});
// emits when any error occurs -> calls closed event immediately after this.
server.on('error',function(error){
console.log('Error: ' + error);
});
//emits when server is bound with server.listen
server.on('listening',function(){
console.log('Server is listening!');
});
server.maxConnections = 500;
var HOST = '0.0.0.0'; // bind to all interfaces, not just loopback
var PORT = 3000;
//static port allocation
server.listen(PORT, HOST);
// for dyanmic port allocation
/*server.listen(function(){
var address = server.address();
var port = address.port;
var family = address.family;
var ipaddr = address.address;
console.log('Server is listening at port' + port);
console.log('Server ip :' + ipaddr);
console.log('Server is IP4/IP6 : ' + family);
});
var islistening = server.listening;
if(islistening){
console.log('Server is listening');
}else{
console.log('Server is not listening');
}
setTimeout(function(){
server.close();
},5000000);
*/
//---------------------client----------------------
// creating a custom socket client and connecting it....
/*var client = new net.Socket();
client.connect({
host: 'm.willers.digital',
port: 80
});
client.on('connect',function(){
console.log('Client: connection established with server');
console.log('---------client details -----------------');
var address = client.address();
var port = address.port;
var family = address.family;
var ipaddr = address.address;
console.log('Client is listening at port' + port);
console.log('Client ip :' + ipaddr);
console.log('Client is IP4/IP6 : ' + family);
// writing data to server
client.write('hello from client');
});
client.setEncoding('utf8');
client.on('data',function(data){
console.log('Data from server:' + data);
});
/*setTimeout(function(){
client.end('Bye bye server');
},5000);
*/
//NOTE:--> all the events of the socket are applicable here..in client...
// -----------------creating client using net.connect instead of custom socket-------
// server creation using net.connect --->
// u can also => write the below code in seperate js file
// open new node instance => and run it...
// 87.78.129.86 | localhost
const testClient = net.connect({host: 'localhost', port: 3000}, () => {
console.log('connected to server!');
//testClient.write('Hello World Client!\r\n');
testClient.write(JSON.stringify({"mapId":"7fsfRSUCQ7YwfBEdRk_GivW6qzj","userId":"aKBNg9fbReqLedLiz1KFfA","name":"Summer 2021 - 01"}));
//test(testClient);
});
testClient.on('data', (data) => {
console.log(data.toString());
//testClient.end();
});
/*testClient.on('end', () => {
console.log('disconnected from server');
});
//*/
/*async function test(clients) {
let i = 0;
while (true) {
await new Promise(resolve => setTimeout(resolve, 5000));
i = i+1;
clients.write("Test: "+ i);
}
}
// ---------------------------------------------- //
/*var client = new net.Socket();
client.connect(8080, 'm.willers.digital', function() {
console.log('Connected');
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment