diff --git a/chat-service/Dockerfile b/chat-service/Dockerfile index a619b07..03c1939 100644 --- a/chat-service/Dockerfile +++ b/chat-service/Dockerfile @@ -18,8 +18,8 @@ FROM node:18-alpine as main # Bundle the app's source code inside the Docker image. COPY --from=build /app / -# Expose port 8003 so it can be mapped by Docker daemon. -EXPOSE 8003 +# Expose port 5003 so it can be mapped by Docker daemon. +EXPOSE 5003 # Define the command to run your app using CMD which defines your runtime. CMD [ "node", "index.js" ] \ No newline at end of file diff --git a/chat-service/index.js b/chat-service/index.js index a136049..11d548c 100644 --- a/chat-service/index.js +++ b/chat-service/index.js @@ -1,15 +1,19 @@ require('dotenv').config(); const express = require('express'); -const cors = require("cors"); +const cors = require('cors'); const app = express(); const http = require('http'); const allowedOrigins = [ 'http://localhost:3000', - 'http://localhost:8000', - 'http://localhost:8001', - 'http://localhost:8002', - 'http://localhost:8006', + 'http://localhost:5000', + 'http://localhost:5001', + 'http://localhost:5002', + 'http://localhost:5003', + 'http://localhost:5004', + 'http://localhost:5005', + 'http://localhost:5006', + 'http://localhost:5007', // node ip 'http://34.123.40.181:30800', 'http://34.123.40.181:30700', @@ -29,11 +33,12 @@ const corsOptions = { origin: function (origin, callback) { if (!origin) return callback(null, true); if (allowedOrigins.indexOf(origin) === -1) { - const msg = 'The CORS policy for this site does not allow access from the specified Origin.'; + const msg = + 'The CORS policy for this site does not allow access from the specified Origin.'; return callback(new Error(msg), false); } return callback(null, true); - } + }, }; app.use(cors(corsOptions)); @@ -44,8 +49,8 @@ const firebaseConfigRoute = require('./routes/firebaseConfig-route'); app.use('/', firebaseConfigRoute); const server = http.createServer(app); // Create an HTTP server -const port = process.env.PORT || 8003; +const port = process.env.PORT || 5003; server.listen(port, () => { console.log(`web socket server is running on port ${port}`); -}); \ No newline at end of file +}); diff --git a/chat-service/k8/chat-service-values.yaml b/chat-service/k8/chat-service-values.yaml index c53160b..a675578 100644 --- a/chat-service/k8/chat-service-values.yaml +++ b/chat-service/k8/chat-service-values.yaml @@ -11,6 +11,6 @@ secrets: service: type: NodePort - port: 8003 - targetPort: 8003 + port: 5003 + targetPort: 5003 nodePort: 30000 \ No newline at end of file diff --git a/chat-service/k8/templates/deployment.yaml b/chat-service/k8/templates/deployment.yaml index 71f3171..3333868 100644 --- a/chat-service/k8/templates/deployment.yaml +++ b/chat-service/k8/templates/deployment.yaml @@ -17,7 +17,7 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" # image: imrajsingh/chat-service-image ports: - - containerPort: 8003 + - containerPort: 5003 env: - name: FIREBASE_API_KEY value: "{{ .Values.secrets.firebase_keys.firebaseApiKey }}" diff --git a/chat-service/k8/templates/service.yaml b/chat-service/k8/templates/service.yaml index 00ee7a2..ab92ae3 100644 --- a/chat-service/k8/templates/service.yaml +++ b/chat-service/k8/templates/service.yaml @@ -5,8 +5,8 @@ metadata: spec: type: NodePort ports: - - port: 8003 - targetPort: 8003 + - port: 5003 + targetPort: 5003 nodePort: 30000 selector: app: chat-service \ No newline at end of file diff --git a/chat-service/package.json b/chat-service/package.json index 543e271..20ee36f 100644 --- a/chat-service/package.json +++ b/chat-service/package.json @@ -1,7 +1,6 @@ { "name": "chat-service", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -16,5 +15,7 @@ "firebase": "^10.4.0", "jsonwebtoken": "^9.0.2", "nodemon": "^3.0.1" - } + }, + "keywords": [], + "description": "" } diff --git a/collaboration-service/Dockerfile b/collaboration-service/Dockerfile index ea949c5..1ae53b4 100644 --- a/collaboration-service/Dockerfile +++ b/collaboration-service/Dockerfile @@ -18,8 +18,8 @@ FROM node:18-alpine as main # Bundle the app's source code inside the Docker image. COPY --from=build /app / -# Expose port 8004 so it can be mapped by Docker daemon. -EXPOSE 8004 +# Expose port 5004 so it can be mapped by Docker daemon. +EXPOSE 5004 # Define the command to run your app using CMD which defines your runtime. CMD [ "npm", "start" ] \ No newline at end of file diff --git a/collaboration-service/controllers/session-controller.js b/collaboration-service/controllers/session-controller.js index b9bdf83..c3fda45 100644 --- a/collaboration-service/controllers/session-controller.js +++ b/collaboration-service/controllers/session-controller.js @@ -4,248 +4,288 @@ const sessionUsers = {}; const randomQuestions = {}; const axios = require('axios'); -const { difficultyOptions, categoriesOptions } = require( - './data' -); +const { difficultyOptions, categoriesOptions } = require('./data'); const disconnectTime = 15000; const handleConnection = async (ws, req) => { - const sessionId = req.url.substring(1); - - ws.on('message', (message) => { - const { userId } = JSON.parse(message); - ws.userId = userId; - if (sessionUsers[sessionId] && sessionUsers[sessionId].includes(userId)) { - ws.send(JSON.stringify({ allowed: true, usersInfo: sessionUsers[sessionId] })); - if (activeSessions[sessionId].second !== ws.userId && !activeSessions[sessionId].first) { - activeSessions[sessionId].first = ws.userId; - ws.send(JSON.stringify(randomQuestions[sessionId])); - console.log(`User ${ws.userId} assigned as first`); - } else if (activeSessions[sessionId].first !== ws.userId && !activeSessions[sessionId].second) { - activeSessions[sessionId].second = ws.userId; - ws.send(JSON.stringify(randomQuestions[sessionId])); - console.log(`User ${ws.userId} assigned as second`); - } - } else { - ws.send(JSON.stringify({ allowed: false })); - } - - }); - - if (activeSessions[sessionId]) { - if (activeSessions[sessionId].disconnectTimer !== undefined) { - console.log(`Clearing disconnectTimer for sessionId ${sessionId}: ${activeSessions[sessionId].disconnectTimer}`); - clearTimeout(activeSessions[sessionId].disconnectTimer); - delete activeSessions[sessionId].disconnectTimer; - } else { - console.log(`No disconnectTimer to clear`); - } + const sessionId = req.url.substring(1); + + ws.on('message', (message) => { + const { userId } = JSON.parse(message); + ws.userId = userId; + if (sessionUsers[sessionId] && sessionUsers[sessionId].includes(userId)) { + ws.send( + JSON.stringify({ allowed: true, usersInfo: sessionUsers[sessionId] }) + ); + if ( + activeSessions[sessionId].second !== ws.userId && + !activeSessions[sessionId].first + ) { + activeSessions[sessionId].first = ws.userId; + ws.send(JSON.stringify(randomQuestions[sessionId])); + console.log(`User ${ws.userId} assigned as first`); + } else if ( + activeSessions[sessionId].first !== ws.userId && + !activeSessions[sessionId].second + ) { + activeSessions[sessionId].second = ws.userId; + ws.send(JSON.stringify(randomQuestions[sessionId])); + console.log(`User ${ws.userId} assigned as second`); + } + } else { + ws.send(JSON.stringify({ allowed: false })); } - - if (!activeSessions[sessionId]) { - activeSessions[sessionId] = { - first: null, - second: null, - listeners: [], - }; + }); + + if (activeSessions[sessionId]) { + if (activeSessions[sessionId].disconnectTimer !== undefined) { + console.log( + `Clearing disconnectTimer for sessionId ${sessionId}: ${activeSessions[sessionId].disconnectTimer}` + ); + clearTimeout(activeSessions[sessionId].disconnectTimer); + delete activeSessions[sessionId].disconnectTimer; + } else { + console.log(`No disconnectTimer to clear`); } + } - activeSessions[sessionId].listeners.push(ws); + if (!activeSessions[sessionId]) { + activeSessions[sessionId] = { + first: null, + second: null, + listeners: [], + }; + } - activeSessions[sessionId].listeners.forEach(listenerWs => { - if (listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify(randomQuestions[sessionId])); - } - }); + activeSessions[sessionId].listeners.push(ws); + + activeSessions[sessionId].listeners.forEach((listenerWs) => { + if (listenerWs.readyState === WebSocket.OPEN) { + listenerWs.send(JSON.stringify(randomQuestions[sessionId])); + } + }); }; const handleMessage = (message, ws, sessionId) => { - const { type, userId, confirmEnd, language } = JSON.parse(message); - const session = activeSessions[sessionId]; - - if (type === "language") { - const otherUser = userId === session.first ? 'second' : 'first'; - const otherUserId = session[otherUser]; - console.log(language); - session.listeners.forEach(listenerWs => { - if (listenerWs.userId === otherUserId && listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'language', language: language })); - } - }); - } + const { type, userId, confirmEnd, language } = JSON.parse(message); + const session = activeSessions[sessionId]; + + if (type === 'language') { + const otherUser = userId === session.first ? 'second' : 'first'; + const otherUserId = session[otherUser]; + console.log(language); + session.listeners.forEach((listenerWs) => { + if ( + listenerWs.userId === otherUserId && + listenerWs.readyState === WebSocket.OPEN + ) { + listenerWs.send( + JSON.stringify({ type: 'language', language: language }) + ); + } + }); + } - if (type === 'REQUEST_END_SESSION') { - if (confirmEnd) { - // Both users agreed to end the session - session.listeners.forEach(listenerWs => { - if (listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'END_SESSION' })); - } - }); - handleClose(ws, sessionId, confirmEnd); - - } else { - const otherUser = userId === session.first ? 'second' : 'first'; - const otherUserId = session[otherUser]; - session.listeners.forEach(listenerWs => { - if (listenerWs.userId === otherUserId && listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'requestEndSession' })); - } - }); - console.log(`userId: ${userId}, otherUser: ${otherUser}, otherUserId: ${otherUserId}`); + if (type === 'REQUEST_END_SESSION') { + if (confirmEnd) { + // Both users agreed to end the session + session.listeners.forEach((listenerWs) => { + if (listenerWs.readyState === WebSocket.OPEN) { + listenerWs.send(JSON.stringify({ type: 'END_SESSION' })); } - + }); + handleClose(ws, sessionId, confirmEnd); + } else { + const otherUser = userId === session.first ? 'second' : 'first'; + const otherUserId = session[otherUser]; + session.listeners.forEach((listenerWs) => { + if ( + listenerWs.userId === otherUserId && + listenerWs.readyState === WebSocket.OPEN + ) { + listenerWs.send(JSON.stringify({ type: 'requestEndSession' })); + } + }); + console.log( + `userId: ${userId}, otherUser: ${otherUser}, otherUserId: ${otherUserId}` + ); } - if (type === 'cancelEndRequest') { - const otherUser = userId === session.first ? 'second' : 'first'; - const otherUserId = session[otherUser]; - session.listeners.forEach(listenerWs => { - if (listenerWs.userId === otherUserId && listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'cancelled' })); - } - }); - }; - - - if (type === 'REQUEST_REDIRECT') { - if (confirmEnd) { - // Both users agreed to end the session - session.listeners.forEach(listenerWs => { - if (listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'REDIRECTED' })); - } - }); + } + if (type === 'cancelEndRequest') { + const otherUser = userId === session.first ? 'second' : 'first'; + const otherUserId = session[otherUser]; + session.listeners.forEach((listenerWs) => { + if ( + listenerWs.userId === otherUserId && + listenerWs.readyState === WebSocket.OPEN + ) { + listenerWs.send(JSON.stringify({ type: 'cancelled' })); + } + }); + } - } else { - const otherUser = userId === session.first ? 'second' : 'first'; - const otherUserId = session[otherUser]; - session.listeners.forEach(listenerWs => { - if (listenerWs.userId === otherUserId && listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'requestRedirect' })); - } - }); - console.log(`userId: ${userId}, otherUser: ${otherUser}, otherUserId: ${otherUserId}`); + if (type === 'REQUEST_REDIRECT') { + if (confirmEnd) { + // Both users agreed to end the session + session.listeners.forEach((listenerWs) => { + if (listenerWs.readyState === WebSocket.OPEN) { + listenerWs.send(JSON.stringify({ type: 'REDIRECTED' })); } - + }); + } else { + const otherUser = userId === session.first ? 'second' : 'first'; + const otherUserId = session[otherUser]; + session.listeners.forEach((listenerWs) => { + if ( + listenerWs.userId === otherUserId && + listenerWs.readyState === WebSocket.OPEN + ) { + listenerWs.send(JSON.stringify({ type: 'requestRedirect' })); + } + }); + console.log( + `userId: ${userId}, otherUser: ${otherUser}, otherUserId: ${otherUserId}` + ); } - - if (type === 'cancelRedirect') { - const otherUser = userId === session.first ? 'second' : 'first'; - const otherUserId = session[otherUser]; - session.listeners.forEach(listenerWs => { - if (listenerWs.userId === otherUserId && listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'cancelledRedirect' })); - } - }); - }; -} - + } + + if (type === 'cancelRedirect') { + const otherUser = userId === session.first ? 'second' : 'first'; + const otherUserId = session[otherUser]; + session.listeners.forEach((listenerWs) => { + if ( + listenerWs.userId === otherUserId && + listenerWs.readyState === WebSocket.OPEN + ) { + listenerWs.send(JSON.stringify({ type: 'cancelledRedirect' })); + } + }); + } +}; const handleClose = (ws, sessionId, confirmEnd) => { - - let index; + let index; + if (activeSessions[sessionId]) { + index = activeSessions[sessionId].listeners.indexOf(ws); + } + if (index > -1) { + activeSessions[sessionId].listeners.splice(index, 1); + } + + if (!confirmEnd) { if (activeSessions[sessionId]) { - index = activeSessions[sessionId].listeners.indexOf(ws); - } - if (index > -1) { - activeSessions[sessionId].listeners.splice(index, 1); - } - - if (!confirmEnd) { - if (activeSessions[sessionId]) { - if (activeSessions[sessionId].disconnectTimer === undefined) { - activeSessions[sessionId].disconnectTimer = setTimeout(() => { - if (activeSessions[sessionId] && Array.isArray(activeSessions[sessionId].listeners)) { - activeSessions[sessionId].listeners.forEach(listenerWs => { - if (listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'requestEndSession', reason: 'disconnect' })); - } - }); - } - }, disconnectTime); - } - console.log(`Set disconnectTimer for sessionId ${sessionId}: ${activeSessions[sessionId].disconnectTimer}`); - - } - } - - if (confirmEnd) { - activeSessions[sessionId].listeners.forEach(listenerWs => { - if (listenerWs.readyState === WebSocket.OPEN) { - listenerWs.send(JSON.stringify({ type: 'END_SESSION' })); - } - }); - activeSessions[sessionId].first = null; - activeSessions[sessionId].second = null; - delete sessionUsers[sessionId]; - delete activeSessions[sessionId]; + if (activeSessions[sessionId].disconnectTimer === undefined) { + activeSessions[sessionId].disconnectTimer = setTimeout(() => { + if ( + activeSessions[sessionId] && + Array.isArray(activeSessions[sessionId].listeners) + ) { + activeSessions[sessionId].listeners.forEach((listenerWs) => { + if (listenerWs.readyState === WebSocket.OPEN) { + listenerWs.send( + JSON.stringify({ + type: 'requestEndSession', + reason: 'disconnect', + }) + ); + } + }); + } + }, disconnectTime); + } + console.log( + `Set disconnectTimer for sessionId ${sessionId}: ${activeSessions[sessionId].disconnectTimer}` + ); } + } - if (activeSessions[sessionId]) { - if (activeSessions[sessionId].listeners.length === 0 && activeSessions[sessionId].first === null && activeSessions[sessionId].second === null) { - delete sessionUsers[sessionId]; - delete activeSessions[sessionId]; - } + if (confirmEnd) { + activeSessions[sessionId].listeners.forEach((listenerWs) => { + if (listenerWs.readyState === WebSocket.OPEN) { + listenerWs.send(JSON.stringify({ type: 'END_SESSION' })); + } + }); + activeSessions[sessionId].first = null; + activeSessions[sessionId].second = null; + delete sessionUsers[sessionId]; + delete activeSessions[sessionId]; + } + + if (activeSessions[sessionId]) { + if ( + activeSessions[sessionId].listeners.length === 0 && + activeSessions[sessionId].first === null && + activeSessions[sessionId].second === null + ) { + delete sessionUsers[sessionId]; + delete activeSessions[sessionId]; } - + } }; - const handleKafkaMessage = async (message, key, wss) => { - const { user1, user2 } = JSON.parse(message); - let { questionComplexity, questionType } = JSON.parse(message); - - let usersInfo; - if (!sessionUsers) { - console.log('test'); - } else { - usersInfo = [user1, user2]; - } - sessionUsers[key] = usersInfo; - - function getRandomElement(array) { - const randomIndex = Math.floor(Math.random() * array.length); - return array[randomIndex]; - } - - let randomQuestion; - try { - // Fetch random question from API - while (true) { - let complexity, type; - if (questionComplexity === "Any") { - complexity = getRandomElement(difficultyOptions).uid; - } - - if (questionType === "Any") { - type = getRandomElement(categoriesOptions).label; - } - - const base_url = process.env.NODE_ENV === "production" ? "34.123.40.181:30700" : "localhost:8001"; - - const response = await axios.get(`http://${base_url}/questions/randomQuestion`, { - data: { - "difficulty": questionComplexity === "Any" ? complexity : questionComplexity, - "category": questionType === "Any" ? type : questionType - } - }); + const { user1, user2 } = JSON.parse(message); + let { questionComplexity, questionType } = JSON.parse(message); + + let usersInfo; + if (!sessionUsers) { + console.log('test'); + } else { + usersInfo = [user1, user2]; + } + sessionUsers[key] = usersInfo; + + function getRandomElement(array) { + const randomIndex = Math.floor(Math.random() * array.length); + return array[randomIndex]; + } + + let randomQuestion; + try { + // Fetch random question from API + while (true) { + let complexity, type; + if (questionComplexity === 'Any') { + complexity = getRandomElement(difficultyOptions).uid; + } + + if (questionType === 'Any') { + type = getRandomElement(categoriesOptions).label; + } + + const base_url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30700' + : 'localhost:5001'; + + const response = await axios.get( + `http://${base_url}/questions/randomQuestion`, + { + data: { + difficulty: + questionComplexity === 'Any' ? complexity : questionComplexity, + category: questionType === 'Any' ? type : questionType, + }, + } + ); - randomQuestion = response.data; + randomQuestion = response.data; - if (Object.keys(randomQuestion).length !== 0) { // Check if response is not empty - break; - } - } - } catch (error) { - console.error('Error fetching the random question from API:', error); + if (Object.keys(randomQuestion).length !== 0) { + // Check if response is not empty + break; + } } - randomQuestions[key] = randomQuestion + } catch (error) { + console.error('Error fetching the random question from API:', error); + } + randomQuestions[key] = randomQuestion; }; module.exports = { - handleConnection, - handleMessage, - handleClose, - handleKafkaMessage, -}; \ No newline at end of file + handleConnection, + handleMessage, + handleClose, + handleKafkaMessage, +}; diff --git a/collaboration-service/index.js b/collaboration-service/index.js index 3e025ec..c3041d3 100644 --- a/collaboration-service/index.js +++ b/collaboration-service/index.js @@ -1,65 +1,66 @@ const WebSocket = require('ws'); const { Kafka, Partitioners, logLevel } = require('kafkajs'); const { - handleConnection, - handleMessage, - handleClose, - handleKafkaMessage + handleConnection, + handleMessage, + handleClose, + handleKafkaMessage, } = require('./controllers/session-controller'); - -const host = process.env.NODE_ENV === "production" ? process.env.KAFKA_HOST : ":9092"; +const host = + process.env.NODE_ENV === 'production' + ? process.env.KAFKA_HOST + : 'localhost:9092'; console.log('Starting on host (index.js) ', host); const kafka = new Kafka({ - logLevel: logLevel.INFO, - brokers: [host], - clientId: 'matchmaking-consumer', - createPartitioner: Partitioners.LegacyPartitioner, - sasl: { - mechanism: 'plain', - username: 'user1', - password: '5PipD4K1m7' - }, - securityProtocol: 'sasl_plaintext' + brokers: [host], + clientId: 'matchmaking-consumer', + createPartitioner: Partitioners.LegacyPartitioner, + // sasl: { + // mechanism: 'plain', + // username: 'user1', + // password: '5PipD4K1m7', + // }, + // securityProtocol: 'sasl_plaintext', }); - const topic = 'session-information'; const consumer = kafka.consumer({ groupId: 'collaboration-service-consumer' }); const runKafkaConsumer = async (wss) => { - await consumer.connect(); - await consumer.subscribe({ topic, fromBeginning: true }); - await consumer.run({ - eachMessage: async ({ topic, partition, message }) => { - const prefix = `${topic}[${partition} | ${message.offset}] / ${message.timestamp}`; - console.log(`- ${prefix} ${message.key}#${message.value}`); - console.log(message.value.toString()); - handleKafkaMessage(message.value.toString(), message.key.toString(), wss); - }, - }); + await consumer.connect(); + await consumer.subscribe({ topic, fromBeginning: true }); + await consumer.run({ + eachMessage: async ({ topic, partition, message }) => { + const prefix = `${topic}[${partition} | ${message.offset}] / ${message.timestamp}`; + console.log(`- ${prefix} ${message.key}#${message.value}`); + console.log(message.value.toString()); + handleKafkaMessage(message.value.toString(), message.key.toString(), wss); + }, + }); }; - -const port = 8004; +const port = 5004; const wss = new WebSocket.Server({ port }); wss.on('connection', (ws, req) => { - console.log('connection established'); - handleConnection(ws, req); + console.log('connection established'); + handleConnection(ws, req); - ws.on('message', (message) => { - handleMessage(message, ws, req.url.substring(1)); - }); + ws.on('message', (message) => { + handleMessage(message, ws, req.url.substring(1)); + }); - ws.on('close', () => { - console.log('close event triggered'); - handleClose(ws, req.url.substring(1)); - }); + ws.on('close', () => { + console.log('close event triggered'); + handleClose(ws, req.url.substring(1)); + }); }); -runKafkaConsumer(wss).catch(e => console.error(`[collaboration-service] ${e.message}`, e)); +runKafkaConsumer(wss).catch((e) => + console.error(`[collaboration-service] ${e.message}`, e) +); console.log(`WebSocket server listening on port ${port}`); diff --git a/collaboration-service/k8/collaboration-service-values.yaml b/collaboration-service/k8/collaboration-service-values.yaml index 5f15081..9d64d6d 100644 --- a/collaboration-service/k8/collaboration-service-values.yaml +++ b/collaboration-service/k8/collaboration-service-values.yaml @@ -1,5 +1,5 @@ service: type: NodePort - port: 8004 - targetPort: 8004 + port: 5004 + targetPort: 5004 nodePort: 30100 \ No newline at end of file diff --git a/collaboration-service/k8/templates/deployment.yaml b/collaboration-service/k8/templates/deployment.yaml index 150ab8f..b3df2c0 100644 --- a/collaboration-service/k8/templates/deployment.yaml +++ b/collaboration-service/k8/templates/deployment.yaml @@ -17,7 +17,7 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" # image: imrajsingh/collaboration-service-image ports: - - containerPort: 8004 + - containerPort: 5004 env: - name: "NODE_ENV" value: "production" diff --git a/collaboration-service/package.json b/collaboration-service/package.json index 3a00fe1..4e1d51e 100644 --- a/collaboration-service/package.json +++ b/collaboration-service/package.json @@ -1,7 +1,6 @@ { "name": "collaboration-service", "version": "1.0.0", - "description": "", "main": "index.js", "dependencies": { "abbrev": "^1.1.1", @@ -162,5 +161,7 @@ "start": "node index.js" }, "author": "", - "license": "ISC" + "license": "ISC", + "keywords": [], + "description": "" } diff --git a/editor-service/Dockerfile b/editor-service/Dockerfile index f50553e..b9cf94c 100644 --- a/editor-service/Dockerfile +++ b/editor-service/Dockerfile @@ -17,8 +17,8 @@ FROM node:18-alpine as main COPY --from=build /app / -# Expose port 4000 -EXPOSE 4000 +# Expose port 5007 +EXPOSE 5007 # Define the command to run your app using CMD which defines your runtime. CMD [ "npm", "start" ] diff --git a/editor-service/index.js b/editor-service/index.js index 8880fe6..bcc3d72 100644 --- a/editor-service/index.js +++ b/editor-service/index.js @@ -8,10 +8,14 @@ const server = http.createServer(app); const allowedOrigins = [ 'http://localhost:3000', - 'http://localhost:8000', - 'http://localhost:8001', - 'http://localhost:8002', - 'http://localhost:8006', + 'http://localhost:5000', + 'http://localhost:5001', + 'http://localhost:5002', + 'http://localhost:5003', + 'http://localhost:5004', + 'http://localhost:5005', + 'http://localhost:5006', + 'http://localhost:5007', // node ip 'http://34.123.40.181:30800', 'http://34.123.40.181:30700', @@ -27,21 +31,22 @@ const allowedOrigins = [ ]; const corsOptions = { - credentials: true, - origin: function (origin, callback) { + credentials: true, + origin: function (origin, callback) { if (!origin) return callback(null, true); if (allowedOrigins.indexOf(origin) === -1) { - const msg = 'The CORS policy for this site does not allow access from the specified Origin.'; - return callback(new Error(msg), false); + const msg = + 'The CORS policy for this site does not allow access from the specified Origin.'; + return callback(new Error(msg), false); } return callback(null, true); - } + }, }; app.use(cors(corsOptions)); const io = socketIo(server, { - cors: corsOptions + cors: corsOptions, }); const sessionSockets = new Map(); @@ -62,28 +67,27 @@ io.on('connection', (socket) => { } socket.on('editorChange', (data) => { - if (sessionSockets.has(data.sessionId)) { const session = sessionSockets.get(data.sessionId); - session.readOnlySockets.forEach(sessionSocket => { + session.readOnlySockets.forEach((sessionSocket) => { if (sessionSocket !== socket) { sessionSocket.emit('editorUpdate', data); } }); } }); - + socket.on('editorChangeTimeUp', (data) => { if (sessionSockets.has(data.sessionId)) { const session = sessionSockets.get(data.sessionId); if (!data.isReadOnly) { - session.readOnlySockets.forEach(sessionSocket => { + session.readOnlySockets.forEach((sessionSocket) => { if (sessionSocket !== socket) { sessionSocket.emit('editorUpdate', data); } }); } else { - session.writableSockets.forEach(sessionSocket => { + session.writableSockets.forEach((sessionSocket) => { if (sessionSocket !== socket) { sessionSocket.emit('editorUpdate', data); } @@ -109,13 +113,16 @@ io.on('connection', (socket) => { } } - if (session.readOnlySockets.length === 0 && session.writableSockets.length === 0) { + if ( + session.readOnlySockets.length === 0 && + session.writableSockets.length === 0 + ) { sessionSockets.delete(sessionId); } } }); }); -server.listen(4000, () => { - console.log('Server is running on port 4000'); +server.listen(5007, () => { + console.log('Server is running on port 5007'); }); diff --git a/editor-service/k8/editor-service-values.yaml b/editor-service/k8/editor-service-values.yaml index da662ab..033131d 100644 --- a/editor-service/k8/editor-service-values.yaml +++ b/editor-service/k8/editor-service-values.yaml @@ -1,5 +1,5 @@ service: type: NodePort - port: 4000 - targetPort: 4000 + port: 5007 + targetPort: 5007 nodePort: 30200 \ No newline at end of file diff --git a/editor-service/k8/templates/deployment.yaml b/editor-service/k8/templates/deployment.yaml index 3980bcf..ca41e61 100644 --- a/editor-service/k8/templates/deployment.yaml +++ b/editor-service/k8/templates/deployment.yaml @@ -16,4 +16,4 @@ spec: - name: editor-service-container image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - - containerPort: 4000 + - containerPort: 5007 diff --git a/editor-service/package.json b/editor-service/package.json index 5e9e619..262d241 100644 --- a/editor-service/package.json +++ b/editor-service/package.json @@ -1,7 +1,6 @@ { "name": "editor-service", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -13,5 +12,6 @@ "dependencies": { "express": "^4.18.2", "socket.io": "^4.7.2" - } + }, + "description": "" } diff --git a/eval-service/Dockerfile b/eval-service/Dockerfile index 333f002..8a18ebe 100644 --- a/eval-service/Dockerfile +++ b/eval-service/Dockerfile @@ -18,8 +18,8 @@ FROM node:18-alpine as main # Bundle the app's source code inside the Docker image. COPY --from=build /app / -# Expose port 7000 -EXPOSE 7000 +# Expose port 5005 +EXPOSE 5005 # Define the command to run your app using CMD which defines your runtime. CMD [ "npm", "start" ] \ No newline at end of file diff --git a/eval-service/index.js b/eval-service/index.js index 29cea79..6782980 100644 --- a/eval-service/index.js +++ b/eval-service/index.js @@ -2,173 +2,189 @@ const express = require('express'); const axios = require('axios'); const cors = require('cors'); const app = express(); -const port = 7000; const cheerio = require('cheerio'); +require('dotenv').config(); app.use(express.json()); const allowedOrigins = [ - 'http://localhost:3000', - 'http://localhost:8000', - 'http://localhost:8001', - 'http://localhost:8002', - 'http://localhost:8006', - // node ip - 'http://34.123.40.181:30800', - 'http://34.123.40.181:30700', - 'http://34.123.40.181:30600', - 'http://34.123.40.181:30500', - 'http://34.123.40.181:30400', - 'http://34.123.40.181:30300', - 'http://34.123.40.181:30200', - 'http://34.123.40.181:30100', - 'http://34.123.40.181:30000', - // frontend ip - 'http://34.68.28.7:3000', + 'http://localhost:3000', + 'http://localhost:5000', + 'http://localhost:5001', + 'http://localhost:5002', + 'http://localhost:5003', + 'http://localhost:5004', + 'http://localhost:5005', + 'http://localhost:5006', + 'http://localhost:5007', + // node ip + 'http://34.123.40.181:30800', + 'http://34.123.40.181:30700', + 'http://34.123.40.181:30600', + 'http://34.123.40.181:30500', + 'http://34.123.40.181:30400', + 'http://34.123.40.181:30300', + 'http://34.123.40.181:30200', + 'http://34.123.40.181:30100', + 'http://34.123.40.181:30000', + // frontend ip + 'http://34.68.28.7:3000', ]; const corsOptions = { - credentials: true, - origin: function (origin, callback) { - if (!origin) return callback(null, true); - if (allowedOrigins.indexOf(origin) === -1) { - const msg = 'The CORS policy for this site does not allow access from the specified Origin.'; - return callback(new Error(msg), false); - } - return callback(null, true); + credentials: true, + origin: function (origin, callback) { + if (!origin) return callback(null, true); + if (allowedOrigins.indexOf(origin) === -1) { + const msg = + 'The CORS policy for this site does not allow access from the specified Origin.'; + return callback(new Error(msg), false); } + return callback(null, true); + }, }; app.use(cors(corsOptions)); -const apiKey = 'e7d334e146msh0b53aee19fe1157p10ef20jsn8aaf56e4b47f'; -const baseUrl = 'https://judge0-ce.p.rapidapi.com'; -const openaiKey = process.env.NODE_ENV === 'production' ? process.env.OPENAPI_KEY : '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'; +const apiKey = process.env.JUDGE0_API_KEY; +const baseUrl = process.env.JUDGE0_BASE_URL; +const openaiKey = + process.env.NODE_ENV === 'production' + ? process.env.OPENAPI_KEY + : process.env.OPEN_AI_API_KEY; -console.log("open api key: ", openaiKey); +console.log('open api key: ', openaiKey); function extractTextFromHTML(html) { - const $ = cheerio.load(html); - const textElements = []; + const $ = cheerio.load(html); + const textElements = []; - $('*').each((index, element) => { - const text = $(element).text().trim(); - if (text) { - textElements.push(text); - } - }); + $('*').each((index, element) => { + const text = $(element).text().trim(); + if (text) { + textElements.push(text); + } + }); - return textElements.join(' '); + return textElements.join(' '); } app.post('/compile', async (req, res) => { - try { - const { sourceCode, languageId } = req.body; - - const response = await axios.post( - `${baseUrl}/submissions/?base64_encoded=false&wait=false`, - { - source_code: sourceCode, - language_id: languageId, // Replace with the appropriate language ID (e.g., 1 for C++) - - }, - { - headers: { - 'X-RapidAPI-Host': 'judge0-ce.p.rapidapi.com', - 'X-RapidAPI-Key': apiKey, - 'Content-Type': 'application/json', - }, - } - ); - - - const submissionToken = response.data.token; - // Poll the status until the compilation is finished - const compilationResult = await pollCompilationStatus(submissionToken); - console.log('result:', compilationResult); - res.json({ result: compilationResult }); - } catch (error) { - res.status(500).json({ error: error.message }); - } + try { + const { sourceCode, languageId } = req.body; + + const response = await axios.post( + `${baseUrl}/submissions/?base64_encoded=false&wait=false`, + { + source_code: sourceCode, + language_id: languageId, // Replace with the appropriate language ID (e.g., 1 for C++) + }, + { + headers: { + 'X-RapidAPI-Host': 'judge0-ce.p.rapidapi.com', + 'X-RapidAPI-Key': apiKey, + 'Content-Type': 'application/json', + }, + } + ); + + const submissionToken = response.data.token; + // Poll the status until the compilation is finished + const compilationResult = await pollCompilationStatus(submissionToken); + console.log('result:', compilationResult); + res.json({ result: compilationResult }); + } catch (error) { + res.status(500).json({ error: error.message }); + } }); const pollCompilationStatus = async (submissionToken) => { - try { - while (true) { - const response = await axios.get(`https://judge0-ce.p.rapidapi.com/submissions/${submissionToken}`, { - headers: { - 'X-RapidAPI-Host': 'judge0-ce.p.rapidapi.com', - 'X-RapidAPI-Key': apiKey, - }, - }); - const status = response.data.status.description; - console.log(status); - if (status === 'In Queue' || status === 'Processing') { - // If the submission is still in the queue or processing, continue polling - await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second before polling again - } else { - // Handle other statuses as needed - const stdout = response.data.stdout; - const stderr = response.data.stderr; - - if (stdout != null) { - return stdout; - } else { - return stderr; - } - } + try { + while (true) { + const response = await axios.get( + `https://judge0-ce.p.rapidapi.com/submissions/${submissionToken}`, + { + headers: { + 'X-RapidAPI-Host': 'judge0-ce.p.rapidapi.com', + 'X-RapidAPI-Key': apiKey, + }, + } + ); + const status = response.data.status.description; + console.log(status); + if (status === 'In Queue' || status === 'Processing') { + // If the submission is still in the queue or processing, continue polling + await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for 1 second before polling again + } else { + // Handle other statuses as needed + const stdout = response.data.stdout; + const stderr = response.data.stderr; + + if (stdout != null) { + return stdout; + } else { + return stderr; } - } catch (error) { - throw new Error('Error polling submission status: ' + error.message); + } } + } catch (error) { + throw new Error('Error polling submission status: ' + error.message); + } }; app.post('/evaluate', async (req, res) => { - try { - console.log('Evaluating'); - const { code, language, description, compilationResult } = req.body; - const extractedText = extractTextFromHTML(description); - // Construct the input for ChatGPT - const chatGptInput = { - model: "gpt-3.5-turbo", - messages: [ - { - role: 'system', - content: 'You are a helpful computer science professor.', - }, - { - role: 'user', - content: `Imagine you are a helpful computer science professor. + try { + console.log('Evaluating'); + const { code, language, description, compilationResult } = req.body; + const extractedText = extractTextFromHTML(description); + // Construct the input for ChatGPT + const chatGptInput = { + model: 'gpt-3.5-turbo', + messages: [ + { + role: 'system', + content: 'You are a helpful computer science professor.', + }, + { + role: 'user', + content: `Imagine you are a helpful computer science professor. Here is the question description: ${extractedText} Here is the code the student wrote: ${code} in ${language} Here is the compilation result: ${compilationResult} - Repeat the question description and score the student's code out of 10 total marks based on - 1) Correctness of code, does it satisfy the question requirement or is it failing some edge cases (5 marks allocated) - 2) time complexity of algorithm used (3 marks allocated) - 3) readability of code (2 marks allocated) - if the code does not answer the question at all please give it a score of 0 out of 10. Please output the score as Student's Score : (the score you have given the student)/10`, - }, - ], - }; - console.log(chatGptInput); - // Make a request to the OpenAI GPT-3 API for code evaluation - const response = await axios.post('https://api.openai.com/v1/chat/completions', chatGptInput, { - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${openaiKey}`, - }, - }); - console.log('retrieved response from openai'); - - // Extract and return the response from ChatGPT - const chatGptMessageContent = response.data.choices[0].message.content; - - res.json({ result: chatGptMessageContent }); - } catch (error) { - res.status(500).json({ error: error.message }); + Repeat the question description and score the student's code out of 10 total marks`, + }, + ], + }; + console.log(chatGptInput); + // Make a request to the OpenAI GPT-3 API for code evaluation + const response = await axios.post( + 'https://api.openai.com/v1/chat/completions', + chatGptInput, + { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${openaiKey}`, + }, + } + ); + console.log('retrieved response from openai'); + + // Extract and return the response from ChatGPT + const chatGptMessageContent = response.data.choices[0].message.content; + + res.json({ result: chatGptMessageContent }); + } catch (error) { + console.error('Error message:', error.message); + console.error('Error stack:', error.stack); + if (error.response) { + console.error('Error response data:', error.response.data); + console.error('Error response status:', error.response.status); + console.error('Error response headers:', error.response.headers); } + res.status(500).json({ error: error.message }); + } }); -app.listen(port, () => { - console.log(`eval-service listening at http://localhost:${port}`); +app.listen(5005, () => { + console.log(`eval-service listening at http://localhost:5005`); }); diff --git a/eval-service/k8/templates/deployment.yaml b/eval-service/k8/templates/deployment.yaml index 4dcd7c1..63c1075 100644 --- a/eval-service/k8/templates/deployment.yaml +++ b/eval-service/k8/templates/deployment.yaml @@ -16,7 +16,7 @@ spec: - name: eval-service-container image: imrajsingh/eval-service-image ports: - - containerPort: 7000 + - containerPort: 5005 env: - name: OPENAPI_KEY value: "{{ .Values.secrets.openapi_key }}" diff --git a/eval-service/k8/templates/service.yaml b/eval-service/k8/templates/service.yaml index ea9ce3c..aefcd79 100644 --- a/eval-service/k8/templates/service.yaml +++ b/eval-service/k8/templates/service.yaml @@ -5,8 +5,8 @@ metadata: spec: type: NodePort ports: - - port: 7000 - targetPort: 7000 + - port: 5005 + targetPort: 5005 nodePort: 30300 selector: app: eval-service diff --git a/eval-service/package-lock.json b/eval-service/package-lock.json index 83ec69e..aa82547 100644 --- a/eval-service/package-lock.json +++ b/eval-service/package-lock.json @@ -12,6 +12,7 @@ "axios": "^1.5.1", "cheerio": "^1.0.0-rc.12", "cors": "^2.8.5", + "dotenv": "^16.3.1", "express": "^4.18.2" } }, @@ -296,6 +297,17 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/eval-service/package.json b/eval-service/package.json index 17eb109..8167b36 100644 --- a/eval-service/package.json +++ b/eval-service/package.json @@ -1,7 +1,6 @@ { "name": "eval-service", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -14,6 +13,8 @@ "axios": "^1.5.1", "cheerio": "^1.0.0-rc.12", "cors": "^2.8.5", + "dotenv": "^16.3.1", "express": "^4.18.2" - } + }, + "description": "" } diff --git a/frontend/app/collaboration/[sessionId]/page.tsx b/frontend/app/collaboration/[sessionId]/page.tsx index 26b37f1..4396669 100644 --- a/frontend/app/collaboration/[sessionId]/page.tsx +++ b/frontend/app/collaboration/[sessionId]/page.tsx @@ -53,7 +53,6 @@ const CollaborationSession = () => { const [isRedirect2nd, setIsRedirect2nd] = useState(false); const [userConfirmedRedirect, setUserConfirmedRedirect] = useState(false); - const [progress, setProgress] = useState(100); const [redirectTime, setRedirectTime] = useState(5000); @@ -107,10 +106,13 @@ const CollaborationSession = () => { } = useDisclosure(); useEffect(() => { - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30100" : 'localhost:8004'; - - console.log("collab url: " + url); - + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30100' + : 'localhost:5004'; + + console.log('collab url: ' + url); + const websocket = new WebSocket(`ws://${url}/${sessionId}`); const waitForQuestion = () => { @@ -120,7 +122,7 @@ const CollaborationSession = () => { resolve(JSON.parse(storedQuestion)); return; } - + const handler = (message: any) => { const data = JSON.parse(message.data); if (data.hasOwnProperty('question')) { @@ -187,7 +189,6 @@ const CollaborationSession = () => { setUserConfirmedRedirect(false); } - if (data.type === 'END_SESSION') { setIsEnded(true); handleEndSession(); @@ -227,8 +228,7 @@ const CollaborationSession = () => { }; sendLanguageToServer(language); - - }, [language]); + }, [language]); const router = useRouter(); @@ -263,7 +263,6 @@ const CollaborationSession = () => { onConfirmRedirectPopupOpen(); }; - const handleConfirmRedirect2nd = () => { onConfirmRedirectPopupOpen(); onWaiting2ndOpen(); @@ -276,7 +275,7 @@ const CollaborationSession = () => { ws.send(message); } handleEvaluateAndCompile(); - } + }; const handleCancelWait2nd = () => { if (ws && ws.readyState === WebSocket.OPEN) { @@ -288,7 +287,6 @@ const CollaborationSession = () => { } }; - useEffect(() => { if (isEndingSessionPopupOpen) { const timeout = setTimeout(() => { @@ -337,11 +335,10 @@ const CollaborationSession = () => { } }; - const handleCompileAndSwitchTabs = async () => { setSelectedTab('Executed Code'); - await handleCompile() - } + await handleCompile(); + }; const handleCompile = async () => { setIsExecuteButtonDisabled(true); @@ -349,11 +346,14 @@ const CollaborationSession = () => { try { const selectedLanguageId = languageIds[language]; const editorValue = writeEditorValue; - console.log("Editor value:", editorValue); + console.log('Editor value:', editorValue); + + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30300' + : 'localhost:5005'; - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30300" : 'localhost:7000'; - - console.log("eval url: " + url); + console.log('eval url: ' + url); const response = await axios.post(`http://${url}/compile`, { sourceCode: editorValue, @@ -380,9 +380,12 @@ const CollaborationSession = () => { const editorValue = writeEditorValue; const questionData = randomQuestion; - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30300" : 'localhost:7000'; + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30300' + : 'localhost:5005'; - console.log("eval url: " + url); + console.log('eval url: ' + url); if (questionData) { const response = await axios.post( @@ -411,14 +414,14 @@ const CollaborationSession = () => { }; const handleEvaluateAndCompile = async () => { - setSelectedTab('Question') + setSelectedTab('Question'); await handleCompile(); // First, compile the code await handleEvaluate(); // Then, evaluate the code const score = parseScoreFromEvaluationResult( localStorage.getItem(`evaluationResult_${userId}`) ?? '' ); - + const outcome = 0; const sessionIdString = Array.isArray(sessionId) ? sessionId[0] : sessionId; const feedback = localStorage.getItem(`evaluationResult_${userId}`) || ''; @@ -438,7 +441,6 @@ const CollaborationSession = () => { sendHistoryData(historyData); }; - interface HistoryData { userId: string; sessionId: string; @@ -471,10 +473,12 @@ const CollaborationSession = () => { async function sendHistoryData(data: HistoryData): Promise { try { + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30500' + : 'localhost:5006'; - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30500" : 'localhost:8006'; - - console.log("history url: " + url); + console.log('history url: ' + url); const response = await fetch(`http://${url}/history`, { method: 'POST', @@ -567,9 +571,7 @@ const CollaborationSession = () => { { items={tabs} variant="underlined" selectedKey={'Results'} - // @ts-ignore + // @ts-ignore > @@ -664,7 +666,6 @@ const CollaborationSession = () => { -
@@ -673,7 +674,7 @@ const CollaborationSession = () => { items={tabs} variant="underlined" selectedKey={'Chat'} - // @ts-ignore + // @ts-ignore > @@ -714,9 +715,7 @@ const CollaborationSession = () => { {

Compiling....

+ ) : compileResult ? ( + compileResult ) : ( - compileResult ? ( - compileResult - ) : ( - 'Your Code has not been evaluated.' - ) + 'Your Code has not been evaluated.' )} @@ -763,8 +760,9 @@ const CollaborationSession = () => {
{allowed && } @@ -778,12 +776,12 @@ const CollaborationSession = () => { setIsDisconnectPopupOpen(false); }} /> - +
{/* */}
diff --git a/frontend/app/components/ChatService/ChatComponent.tsx b/frontend/app/components/ChatService/ChatComponent.tsx index d85cf7f..9e49d7e 100644 --- a/frontend/app/components/ChatService/ChatComponent.tsx +++ b/frontend/app/components/ChatService/ChatComponent.tsx @@ -1,10 +1,9 @@ import { doc, getFirestore, serverTimestamp, setDoc } from 'firebase/firestore'; import { initializeApp } from 'firebase/app'; +import { getAuth, signInAnonymously } from 'firebase/auth'; import React, { useEffect, useState } from 'react'; import ChatRoom from './ChatRoom'; import Loading from './Loading'; -import { Textarea } from '@nextui-org/react'; -import { url } from 'inspector'; /* Call this component to display chat component on screen @@ -27,30 +26,42 @@ const ChatComponent: React.FC = (props: any) => { const jwtToken = localStorage.getItem('token'); try { - const chatServiceURL = process.env.NODE_ENV === "production" ? "34.123.40.181:30000" : "localhost:8003"; + const chatServiceURL = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30000' + : 'localhost:5003'; - console.log("chat url : " + chatServiceURL); + console.log('chat url : ' + chatServiceURL); - const response = await fetch(`http://${chatServiceURL}/firebase-config`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${jwtToken}`, - }, - }); + const response = await fetch( + `http://${chatServiceURL}/firebase-config`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${jwtToken}`, + }, + } + ); + + console.log('chat response: ', response); + console.log('chat response status: ', response.status); if (response.status === 200) { const data = await response.json(); - initializeApp(data.firebaseConfig); + const app = initializeApp(data.firebaseConfig); + + const auth = getAuth(app); + await signInAnonymously(auth); const db = getFirestore(); - await setDoc(doc(db, 'matched-tokens', matchToken), { + await setDoc(doc(db, 'chat', matchToken), { matchToken: matchToken, createdAt: serverTimestamp(), }) .then(() => { console.log('Document successfully written!'); - setDocRef(doc(db, 'matched-tokens', matchToken)); + setDocRef(doc(db, 'chat', matchToken)); }) .catch((error) => { console.error('Error adding document: ', error); diff --git a/frontend/app/components/ChatService/ChatRoom.tsx b/frontend/app/components/ChatService/ChatRoom.tsx index df8b0c7..9bf28fa 100644 --- a/frontend/app/components/ChatService/ChatRoom.tsx +++ b/frontend/app/components/ChatService/ChatRoom.tsx @@ -19,11 +19,11 @@ interface ChatRoomProps { const ChatRoom: React.FC = ({ docRef, userId }) => { const db = getFirestore(); const messageSpanRef = useRef(null); - const messagesRef = collection(db, 'matched-tokens', docRef.id, 'messages'); + const messagesRef = collection(db, 'chat', docRef.id, 'messages'); const [formValue, setFormValue] = useState(''); const messagesQuery = query( - collection(db, 'matched-tokens', docRef?.id, 'messages'), + collection(db, 'chat', docRef?.id, 'messages'), orderBy('createdAt') ); diff --git a/frontend/app/components/Collaboration/CollabEditor.tsx b/frontend/app/components/Collaboration/CollabEditor.tsx index 03fb23f..7eeaabc 100644 --- a/frontend/app/components/Collaboration/CollabEditor.tsx +++ b/frontend/app/components/Collaboration/CollabEditor.tsx @@ -12,7 +12,7 @@ import { useEffect } from 'react'; import io from 'socket.io-client'; -const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:4000'; +const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:5007'; console.log("editor url: " + url); @@ -45,7 +45,7 @@ const CollabEditor: React.FC = ({ useEffect(() => { - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:4000'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:5007'; console.log("editor url: " + url); diff --git a/frontend/app/components/History/HistoryTable.tsx b/frontend/app/components/History/HistoryTable.tsx index 654661a..5f19dea 100644 --- a/frontend/app/components/History/HistoryTable.tsx +++ b/frontend/app/components/History/HistoryTable.tsx @@ -60,17 +60,20 @@ const HistoryTable = () => { ]; async function getHistories(userId: string): Promise { + const historyUrl = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30500' + : 'localhost:5006'; - const historyUrl = process.env.NODE_ENV === 'production' ? "34.123.40.181:30500" : 'localhost:8006'; + console.log('history url: ' + historyUrl); - console.log("history url: " + historyUrl); - - - const res: Response = await fetch(`http://${historyUrl}/history?userId=${userId}`, { - method: 'GET', - headers: { token: localStorage.token }, - cache: 'no-store', - } + const res: Response = await fetch( + `http://${historyUrl}/history?userId=${userId}`, + { + method: 'GET', + headers: { token: localStorage.token }, + cache: 'no-store', + } ); console.log(res); const histories: History[] = await res.json(); @@ -78,8 +81,10 @@ const HistoryTable = () => { } async function getTickets(): Promise { - - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:8001'; + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30700' + : 'localhost:5001'; console.log('question url: ' + url); @@ -92,7 +97,6 @@ const HistoryTable = () => { return questions; } - React.useEffect(() => { const fetchQuestions = async () => { setIsLoading(true); @@ -131,14 +135,14 @@ const HistoryTable = () => { return diffDays; }; - const getQuestionName = (questionId: number) : string => { + const getQuestionName = (questionId: number): string => { const question = questions.find((q) => q.id == questionId); if (question) { return question.title; } else { - return "Unknown Question"; + return 'Unknown Question'; } - } + }; const generateDaysSubtitle = (attemptedDate: string) => { const daysDifference = daysPast(attemptedDate); @@ -182,7 +186,7 @@ const HistoryTable = () => { className="capitalize flex m-2" color={ difficultyColorMap[ - record.difficulty ? record.difficulty : 'Easy' + record.difficulty ? record.difficulty : 'Easy' ] } size="md" @@ -192,7 +196,9 @@ const HistoryTable = () => {
} - title={`${record.questionId}. ${getQuestionName(record.questionId)}`} + title={`${record.questionId}. ${getQuestionName( + record.questionId + )}`} subtitle={

{parseDateString(record.attemptDate)}

@@ -236,7 +242,7 @@ const HistoryTable = () => { }, }} > -
+
{ Your Code - { - + { > {/*
*/} - - Feedback - - - -

{record.score}/10

-
-
+ + Feedback + + + +

{record.score}/10

+
+
{/*
*/}
{/* */} - + {processNewLine(record.feedback).map((line) => (

{line} @@ -331,4 +339,4 @@ const HistoryTable = () => { ); }; -export default HistoryTable; \ No newline at end of file +export default HistoryTable; diff --git a/frontend/app/components/Leaderboard/Leaderboard.tsx b/frontend/app/components/Leaderboard/Leaderboard.tsx index 2aefc23..cbf2644 100644 --- a/frontend/app/components/Leaderboard/Leaderboard.tsx +++ b/frontend/app/components/Leaderboard/Leaderboard.tsx @@ -90,24 +90,25 @@ const Leaderboard = () => { - -

- - -
-
- -
-
- -
-
- -
-
-
- }> +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ } + > {rows.map((row: any, index: number) => ( @@ -125,11 +126,14 @@ const Leaderboard = () => { const getLeaders = async () => { try { - // const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30500" : 'localhost:8006'; + // const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30500" : 'localhost:5006'; - const url = process.env.NODE_ENV === 'production' ? '34.123.40.181:30500' : 'localhost:8006'; - - console.log("history url: ", url); + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30500' + : 'localhost:5006'; + + console.log('history url: ', url); const res = await fetch(`http://${url}/history/getLeaders`, { method: 'GET', @@ -157,11 +161,19 @@ const Leaderboard = () => { {tableStructure(dailyLeaders, 'day')} - + {tableStructure(weeklyLeaders, 'week')} - + {tableStructure(monthlyLeaders, 'month')} diff --git a/frontend/app/components/Matchmaking/Matchmaking.tsx b/frontend/app/components/Matchmaking/Matchmaking.tsx index 28ea5a5..22a59fe 100644 --- a/frontend/app/components/Matchmaking/Matchmaking.tsx +++ b/frontend/app/components/Matchmaking/Matchmaking.tsx @@ -62,7 +62,10 @@ const Matchmaking = () => { localStorage.setItem('searchQuestionType', searchQuestionType); } - const url = process.env.NODE_ENV !== 'production' ? 'localhost:8002' : "34.123.40.181:30600" + const url = + process.env.NODE_ENV !== 'production' + ? 'localhost:5002' + : '34.123.40.181:30600'; const socket = new WebSocket(`ws://${url}`); @@ -227,7 +230,6 @@ const Matchmaking = () => { console.log(sessionId); }; - return (

Race

diff --git a/frontend/app/components/Questions/QuestionsTable.tsx b/frontend/app/components/Questions/QuestionsTable.tsx index 0953bd4..4894e9a 100644 --- a/frontend/app/components/Questions/QuestionsTable.tsx +++ b/frontend/app/components/Questions/QuestionsTable.tsx @@ -51,7 +51,7 @@ const QuestionsTable: React.FC = () => { const [isLoading, setIsLoading] = React.useState(true); async function getTickets(): Promise { - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:8001'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:5001'; console.log('question url: ' + url); @@ -163,7 +163,7 @@ const QuestionsTable: React.FC = () => { return; } - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:8001'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:5001'; console.log('question url: ' + url); @@ -239,7 +239,7 @@ const QuestionsTable: React.FC = () => { return; } - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:8001'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:5001'; console.log('question url: ' + url); @@ -345,7 +345,7 @@ const QuestionsTable: React.FC = () => { console.log('deleting question with id: '); console.log(selectedDeleteQuestion?.id); - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:8001'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:5001'; console.log('question url: ' + url); diff --git a/frontend/app/components/Server/Collaboration/CollabEditor.tsx b/frontend/app/components/Server/Collaboration/CollabEditor.tsx index b35e5b8..3361a51 100644 --- a/frontend/app/components/Server/Collaboration/CollabEditor.tsx +++ b/frontend/app/components/Server/Collaboration/CollabEditor.tsx @@ -13,7 +13,7 @@ import { useEffect } from 'react'; import io from 'socket.io-client'; -const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:4000'; +const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:5007'; console.log('editor url: ' + url); @@ -36,7 +36,7 @@ const CollabEditor: React.FC = ({ side, sideJoined, editorVal buttonState, language, sessionId, isTimeUp }) => { const isReadOnly = sideJoined !== side && !isTimeUp; useEffect(() => { - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:4000'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30200" : 'localhost:5007'; console.log('question url: ' + url); diff --git a/frontend/app/questions/page.tsx b/frontend/app/questions/page.tsx index 75d1204..7bde248 100644 --- a/frontend/app/questions/page.tsx +++ b/frontend/app/questions/page.tsx @@ -16,7 +16,7 @@ export interface Question { } async function getTickets(): Promise { - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:8001'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30700" : 'localhost:5001'; console.log("question url: " + url); diff --git a/frontend/app/users/login/page.tsx b/frontend/app/users/login/page.tsx index 21378e6..12fb5d5 100644 --- a/frontend/app/users/login/page.tsx +++ b/frontend/app/users/login/page.tsx @@ -35,7 +35,7 @@ const LoginPage = () => { if (email && password) { console.log('Sending Request'); - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30800" : 'localhost:8000'; + const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30800" : 'localhost:5000'; console.log("login url: " + url); diff --git a/frontend/app/users/register/page.tsx b/frontend/app/users/register/page.tsx index 67c702d..d933b2a 100644 --- a/frontend/app/users/register/page.tsx +++ b/frontend/app/users/register/page.tsx @@ -47,7 +47,7 @@ const RegisterPage = () => { if (username) { - const url = process.env.NODE_ENV == 'production' ? "34.123.40.181:30800" : 'localhost:8000'; + const url = process.env.NODE_ENV == 'production' ? "34.123.40.181:30800" : 'localhost:5000'; console.log("registration url: " + url); console.log("ENV: " + process.env.NODE_ENV); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 75453ae..6c3ec3b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "frontend", "version": "0.1.0", + "license": "ISC", "dependencies": { "@nextui-org/react": "^2.1.13", "@react-stately/data": "^3.10.3", diff --git a/frontend/package.json b/frontend/package.json index 6cc521c..89bd4d1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -47,5 +47,10 @@ "postcss": "latest", "tailwindcss": "latest", "typescript": "latest" - } + }, + "description": "This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).", + "main": "next.config.js", + "keywords": [], + "author": "", + "license": "ISC" } diff --git a/history-service/Dockerfile b/history-service/Dockerfile index d534561..211cf5c 100644 --- a/history-service/Dockerfile +++ b/history-service/Dockerfile @@ -17,8 +17,8 @@ FROM node:20-alpine as main COPY --from=build /app / -# Expose port 8006 so it can be mapped by Docker daemon. -EXPOSE 8006 +# Expose port 5006 so it can be mapped by Docker daemon. +EXPOSE 5006 # Define the command to run your app using CMD which defines your runtime. CMD [ "npm", "start" ] diff --git a/history-service/controllers/history-controller.js b/history-service/controllers/history-controller.js index 54eebf7..de99c65 100644 --- a/history-service/controllers/history-controller.js +++ b/history-service/controllers/history-controller.js @@ -1,196 +1,232 @@ const History = require('../models/History'); - const addHistory = async (req, res) => { - const { userId, sessionId, questionId, raceOutcome, score, attemptDate, submission, feedback, difficulty, language } = req.body; - - if (!userId || !questionId || !sessionId || raceOutcome == undefined) { - return res.status(422).json({ - message: - `Invalid input, please enter a valid user id ${userId}, question id${questionId}, sessionId, and result`, - }); - } - - try { - // const historyEntry = new History({ userId, sessionId, questionId, raceOutcome, score, attemptDate, submission, feedback, difficulty }); - // await historyEntry.save(); - // res.status(201).json({ message: 'History entry added successfully.' }); - const existingRecord = await History.findOne({ sessionId: sessionId }); - console.log("existing record:", existingRecord); - - if (existingRecord) { - // If exists, update the raceOutcome of the existing record - const outcomeForExistingRecord = existingRecord.score == score ? 0 - : existingRecord.score > score ? 1 : 2; - const outcomeForNewRecord = existingRecord.score == score ? 0 - : existingRecord.score > score ? 2 : 1; - console.log('test1'); - console.log(outcomeForNewRecord); - console.log(outcomeForExistingRecord); - - await History.updateOne({ sessionId }, { $set: { raceOutcome: outcomeForExistingRecord } }); - console.log('test2'); - const historyEntry = new History({ userId: userId, sessionId: sessionId, questionId: questionId, raceOutcome: outcomeForNewRecord, score: score, attemptDate: attemptDate, submission: submission - , feedback: feedback, difficulty: difficulty, language: language }); - console.log('test2.5'); - console.log(historyEntry); - await historyEntry.save().then(result => console.log(result)).catch(err => console.log(err)); - res.status(200).json({ message: 'History entry updated successfully.' }); - } else { - // If not, add a new history entry - console.log(" new record"); - console.log('test3'); - const historyEntry = new History({ userId, sessionId, questionId, raceOutcome, score, attemptDate, submission, feedback, difficulty, language }); - console.log('test4'); - await historyEntry.save().then(result => console.log(result)).catch(err => console.log(err)); - res.status(200).json({ message: 'History entry added successfully.' }); - } - } catch (error) { - res.status(500).json({ error: `Internal server error ${error.message}` }); + const { + userId, + sessionId, + questionId, + raceOutcome, + score, + attemptDate, + submission, + feedback, + difficulty, + language, + } = req.body; + + if (!userId || !questionId || !sessionId || raceOutcome == undefined) { + return res.status(422).json({ + message: `Invalid input, please enter a valid user id ${userId}, question id${questionId}, sessionId, and result`, + }); + } + + try { + // const historyEntry = new History({ userId, sessionId, questionId, raceOutcome, score, attemptDate, submission, feedback, difficulty }); + // await historyEntry.save(); + // res.status(201).json({ message: 'History entry added successfully.' }); + const existingRecord = await History.findOne({ sessionId: sessionId }); + console.log('existing record:', existingRecord); + + if (existingRecord) { + // If exists, update the raceOutcome of the existing record + const outcomeForExistingRecord = + existingRecord.score == score + ? 0 + : existingRecord.score > score + ? 1 + : 2; + const outcomeForNewRecord = + existingRecord.score == score + ? 0 + : existingRecord.score > score + ? 2 + : 1; + console.log('test1'); + console.log(outcomeForNewRecord); + console.log(outcomeForExistingRecord); + + await History.updateOne( + { sessionId }, + { $set: { raceOutcome: outcomeForExistingRecord } } + ); + console.log('test2'); + const historyEntry = new History({ + userId: userId, + sessionId: sessionId, + questionId: questionId, + raceOutcome: outcomeForNewRecord, + score: score, + attemptDate: attemptDate, + submission: submission, + feedback: feedback, + difficulty: difficulty, + language: language, + }); + console.log('test2.5'); + console.log(historyEntry); + await historyEntry + .save() + .then((result) => console.log(result)) + .catch((err) => console.log(err)); + res.status(200).json({ message: 'History entry updated successfully.' }); + } else { + // If not, add a new history entry + console.log(' new record'); + console.log('test3'); + const historyEntry = new History({ + userId, + sessionId, + questionId, + raceOutcome, + score, + attemptDate, + submission, + feedback, + difficulty, + language, + }); + console.log('test4'); + await historyEntry + .save() + .then((result) => console.log(result)) + .catch((err) => console.log(err)); + res.status(200).json({ message: 'History entry added successfully.' }); } + } catch (error) { + res.status(500).json({ error: `Internal server error ${error.message}` }); + } }; - + const getHistory = async (req, res) => { - try { - const userId = req.query.userId; - const match = { $match: { userId: userId }}; - const sort = { $sort: { attemptDate: -1 }}; - - const userHistory = await History.aggregate([match, sort]); - console.log(userHistory) - res.status(200).json(userHistory); - } catch (error) { - console.log(error) - res.status(500).json({ error: 'Internal server error' }); - } + try { + const userId = req.query.userId; + const match = { $match: { userId: userId } }; + const sort = { $sort: { attemptDate: -1 } }; + + const userHistory = await History.aggregate([match, sort]); + console.log(userHistory); + res.status(200).json(userHistory); + } catch (error) { + console.log(error); + res.status(500).json({ error: 'Internal server error' }); + } }; const getUserNames = async (rankings) => { - // console.log(rankings); - const userPromises = rankings.map(async (user) => { - try { - const url = process.env.NODE_ENV === 'production' ? "34.123.40.181:30800" : "localhost:8000"; - - console.log("history service calling user-service on ... " + url); - - const res = await fetch(`http://${url}/users/getUser?userId=${user._id}`, { - method: "GET", - headers: { - 'Content-Type': 'application/json' - }, - }); - - if (res.ok) { - const userData = await res.json(); - // console.log(userData); - return { - ...user, - userName: userData.user.username - }; - } else { - console.log(`Failed to fetch user data for user ID: ${user._id}`); - return { - ...user, - userName: "Cannot find username" - }; - } - } catch (error) { - console.error("Error fetching user data:", error); - return user; + // console.log(rankings); + const userPromises = rankings.map(async (user) => { + try { + const url = + process.env.NODE_ENV === 'production' + ? '34.123.40.181:30800' + : 'localhost:5000'; + + console.log('history service calling user-service on ... ' + url); + + const res = await fetch( + `http://${url}/users/getUser?userId=${user._id}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, } - }); - - const usersWithNames = await Promise.all(userPromises); - - return usersWithNames; -} + ); + + if (res.ok) { + const userData = await res.json(); + // console.log(userData); + return { + ...user, + userName: userData.user.username, + }; + } else { + console.log(`Failed to fetch user data for user ID: ${user._id}`); + return { + ...user, + userName: 'Cannot find username', + }; + } + } catch (error) { + console.error('Error fetching user data:', error); + return user; + } + }); + const usersWithNames = await Promise.all(userPromises); + return usersWithNames; +}; const getLeaders = async (req, res) => { - const now = new Date(); - const oneDay = 60 * 60 * 24 * 1000; - const week = new Date(now.getTime() - 7 * oneDay); - const month = new Date(now.getTime() - 30 * oneDay); - const day = new Date(now.getTime() - oneDay); - console.log(week.toDateString()) - console.log(week.toISOString()) - console.log(week.toISOString() <= '2023-10-24T12:00:00.000+00:00') - const groups ={ - $group: { - _id: "$userId", - totalWins: { - $sum: { - $cond: [{ $eq: ['$raceOutcome', 1] }, 1, 0] - } + const now = new Date(); + const oneDay = 60 * 60 * 24 * 1000; + const week = new Date(now.getTime() - 7 * oneDay); + const month = new Date(now.getTime() - 30 * oneDay); + const day = new Date(now.getTime() - oneDay); + console.log(week.toDateString()); + console.log(week.toISOString()); + console.log(week.toISOString() <= '2023-10-24T12:00:00.000+00:00'); + const groups = { + $group: { + _id: '$userId', + totalWins: { + $sum: { + $cond: [{ $eq: ['$raceOutcome', 1] }, 1, 0], }, - totalGames: { $sum: 1 } - } - }; + }, + totalGames: { $sum: 1 }, + }, + }; - const pastDay = { - $match: { attemptDate: { $gte: day }} - }; - - const pastWeek = { - $match: { attemptDate: { $gte: week }} - }; - - const pastMonth = { - $match: { attemptDate: { $gte: month }} - }; + const pastDay = { + $match: { attemptDate: { $gte: day } }, + }; + const pastWeek = { + $match: { attemptDate: { $gte: week } }, + }; - const addWinRate = { - $addFields: { winRate: { $divide: ['$totalWins', '$totalGames'] }} - }; + const pastMonth = { + $match: { attemptDate: { $gte: month } }, + }; - const sort = { $sort: { totalWins: -1, winRate: -1 }}; + const addWinRate = { + $addFields: { winRate: { $divide: ['$totalWins', '$totalGames'] } }, + }; - const limit = { $limit: 5 }; + const sort = { $sort: { totalWins: -1, winRate: -1 } }; - try { - const weekUsersRankings = await getUserNames(await History.aggregate([ - pastWeek, - groups, - addWinRate, - sort, - limit - ])); - - const monthUsersRankings = await getUserNames(await History.aggregate([ - pastMonth, - groups, - addWinRate, - sort, - limit - ])); - - const dayUsersRankings = await getUserNames(await History.aggregate([ - pastDay, - groups, - addWinRate, - sort, - limit - ])); - - - - // console.log(weekUsersRankings); - - res.status(200).json({ - 'week': weekUsersRankings, - 'month': monthUsersRankings, - 'day': dayUsersRankings - }); - } catch (error) { - console.log(error); - res.status(500).json(({error: "internal server error"})); - } -} + const limit = { $limit: 5 }; + + try { + const weekUsersRankings = await getUserNames( + await History.aggregate([pastWeek, groups, addWinRate, sort, limit]) + ); + + const monthUsersRankings = await getUserNames( + await History.aggregate([pastMonth, groups, addWinRate, sort, limit]) + ); + + const dayUsersRankings = await getUserNames( + await History.aggregate([pastDay, groups, addWinRate, sort, limit]) + ); + + // console.log(weekUsersRankings); + + res.status(200).json({ + week: weekUsersRankings, + month: monthUsersRankings, + day: dayUsersRankings, + }); + } catch (error) { + console.log(error); + res.status(500).json({ error: 'internal server error' }); + } +}; module.exports = { - getHistory: getHistory, - addHistory: addHistory, - getLeaders: getLeaders -} + getHistory: getHistory, + addHistory: addHistory, + getLeaders: getLeaders, +}; diff --git a/history-service/index.js b/history-service/index.js index 1aee298..2b1963f 100644 --- a/history-service/index.js +++ b/history-service/index.js @@ -10,10 +10,14 @@ app.use(express.json()); const allowedOrigins = [ 'http://localhost:3000', - 'http://localhost:8000', - 'http://localhost:8001', - 'http://localhost:8002', - 'http://localhost:8006', + 'http://localhost:5000', + 'http://localhost:5001', + 'http://localhost:5002', + 'http://localhost:5003', + 'http://localhost:5004', + 'http://localhost:5005', + 'http://localhost:5006', + 'http://localhost:5007', // node ip 'http://34.123.40.181:30800', 'http://34.123.40.181:30700', @@ -27,7 +31,7 @@ const allowedOrigins = [ // frontend ip 'http://34.68.28.7:3000', ]; - + app.use( cors({ credentials: true, @@ -53,14 +57,14 @@ const historyRoutes = require('./routes/history-routes'); app.use('/history', historyRoutes); mongoose - .connect( - process.env.MONGO_URL, - { useNewUrlParser: true, useUnifiedTopology: true } - ) + .connect(process.env.MONGO_URL, { + useNewUrlParser: true, + useUnifiedTopology: true, + }) .then(() => { console.log('Connected to MongoDB Atlas'); - app.listen(8006, () => { - console.log('History server is running on port 8006'); + app.listen(5006, () => { + console.log('History server is running on port 5006'); }); }) .catch((err) => { @@ -70,4 +74,4 @@ mongoose const connection = mongoose.connection; connection.on('error', () => { console.log('Error connecting to MongoDB Atlas 2'); -}); \ No newline at end of file +}); diff --git a/history-service/k8/history-service-values.yaml b/history-service/k8/history-service-values.yaml index ec5f00c..04f27c1 100644 --- a/history-service/k8/history-service-values.yaml +++ b/history-service/k8/history-service-values.yaml @@ -4,6 +4,6 @@ secrets: service: type: NodePort - port: 8006 - targetPort: 8006 + port: 5006 + targetPort: 5006 nodePort: 30500 \ No newline at end of file diff --git a/history-service/k8/templates/deployment.yaml b/history-service/k8/templates/deployment.yaml index a5482c7..5e50ab9 100644 --- a/history-service/k8/templates/deployment.yaml +++ b/history-service/k8/templates/deployment.yaml @@ -16,7 +16,7 @@ spec: - name: history-service-container image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - - containerPort: 8006 + - containerPort: 5006 env: - name: MONGO_URL value: "{{ .Values.secrets.mongo_url }}" diff --git a/history-service/k8/templates/service.yaml b/history-service/k8/templates/service.yaml index da66872..9c3fa6c 100644 --- a/history-service/k8/templates/service.yaml +++ b/history-service/k8/templates/service.yaml @@ -5,8 +5,8 @@ metadata: spec: type: NodePort ports: - - port: 8006 - targetPort: 8006 + - port: 5006 + targetPort: 5006 nodePort: 30500 selector: app: history-service diff --git a/history-service/package.json b/history-service/package.json index 5f84193..4dc503a 100644 --- a/history-service/package.json +++ b/history-service/package.json @@ -1,7 +1,7 @@ { "name": "history-service", "version": "1.0.0", - "description": "", + "description": "add the following to your .env file", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", diff --git a/matchmaking-service/Dockerfile b/matchmaking-service/Dockerfile index 5575746..638bd95 100644 --- a/matchmaking-service/Dockerfile +++ b/matchmaking-service/Dockerfile @@ -18,7 +18,7 @@ COPY --from=build /app / # Expose the required ports for RabbitMQ and Kafka. # Adjust the port numbers if needed. -EXPOSE 8002 +EXPOSE 5002 # Define the command to run your app and start RabbitMQ and Kafka containers using CMD. CMD ["npm", "start"] \ No newline at end of file diff --git a/matchmaking-service/index.js b/matchmaking-service/index.js index 7d09acd..a366eb3 100644 --- a/matchmaking-service/index.js +++ b/matchmaking-service/index.js @@ -15,7 +15,7 @@ app.use(express.json()); const server = http.createServer(app); const wss = wsController.createWebSocket(server); -const port = 8002; +const port = 5002; server.listen(port, () => { console.log(`matchmaking server is running on port ${port}`); }); diff --git a/matchmaking-service/k8/deployment/deployment.yaml b/matchmaking-service/k8/deployment/deployment.yaml index 575c508..bb1de66 100644 --- a/matchmaking-service/k8/deployment/deployment.yaml +++ b/matchmaking-service/k8/deployment/deployment.yaml @@ -17,7 +17,7 @@ spec: image: imrajsingh/matchmaking-service-image # image: e0774189614/cs3219 ports: - - containerPort: 8002 + - containerPort: 5002 env: - name: KAFKA_PRODUCER_USERNAME value: user1 diff --git a/matchmaking-service/k8/services/service.yml b/matchmaking-service/k8/services/service.yml index fe897a5..49eb510 100644 --- a/matchmaking-service/k8/services/service.yml +++ b/matchmaking-service/k8/services/service.yml @@ -5,8 +5,8 @@ metadata: spec: type: NodePort ports: - - port: 8002 - targetPort: 8002 + - port: 5002 + targetPort: 5002 nodePort: 30600 selector: app: matchmaking-service \ No newline at end of file diff --git a/matchmaking-service/package-lock.json b/matchmaking-service/package-lock.json index 25c2e7e..af0b580 100644 --- a/matchmaking-service/package-lock.json +++ b/matchmaking-service/package-lock.json @@ -1,11 +1,11 @@ { - "name": "user-service", + "name": "matchmaking-service", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "user-service", + "name": "matchmaking-service", "version": "1.0.0", "license": "ISC", "dependencies": { diff --git a/matchmaking-service/package.json b/matchmaking-service/package.json index 6f3a656..776b81f 100644 --- a/matchmaking-service/package.json +++ b/matchmaking-service/package.json @@ -1,7 +1,7 @@ { "name": "matchmaking-service", "version": "1.0.0", - "description": "", + "description": "You will need to run the rabbitMQ and kafka docker container locally.\r Run\r ```bash\r docker-compose up\r ```\r to start all the containers", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", diff --git a/package.json b/package.json index 5480137..609c372 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,14 @@ { -"scripts": { + "scripts": { "start:frontend": "cd frontend && npm run dev", "start:user-service": "cd user-service && npm start", "start:question-service": "cd question-service && npm start", "start:history-service": "cd history-service && npm start", "start:matchmaking-service": "cd matchmaking-service && npm start ", + "start:eval-service": "cd eval-service && npm start ", + "start:editor-service": "cd editor-service && npm start ", "start:collaboration-service": "cd collaboration-service && npm start", "start:chat-service": "cd chat-service && npm start", - "start:all": "npm-run-all --parallel start:frontend start:user-service start:question-service start:collaboration-service start:history-service start:matchmaking-service start:chat-service" + "start:all": "npm-run-all --parallel start:frontend start:user-service start:question-service start:eval-service start:editor-service start:collaboration-service start:history-service start:matchmaking-service start:chat-service" + } } -} \ No newline at end of file diff --git a/question-service/Dockerfile b/question-service/Dockerfile index c070c9e..df327c6 100644 --- a/question-service/Dockerfile +++ b/question-service/Dockerfile @@ -15,8 +15,8 @@ FROM node:18-alpine as main # Bundle the app's source code inside the Docker image. COPY --from=build /app / -# Expose port 8001 so it can be mapped by Docker daemon. -EXPOSE 8001 +# Expose port 5001 so it can be mapped by Docker daemon. +EXPOSE 5001 # Define the command to run your app using CMD which defines your runtime. CMD [ "npm", "start" ] \ No newline at end of file diff --git a/question-service/index.js b/question-service/index.js index 6c3123c..7214bce 100644 --- a/question-service/index.js +++ b/question-service/index.js @@ -10,10 +10,14 @@ app.use(express.json()); const allowedOrigins = [ 'http://localhost:3000', - 'http://localhost:8000', - 'http://localhost:8001', - 'http://localhost:8002', - 'http://localhost:8006', + 'http://localhost:5000', + 'http://localhost:5001', + 'http://localhost:5002', + 'http://localhost:5003', + 'http://localhost:5004', + 'http://localhost:5005', + 'http://localhost:5006', + 'http://localhost:5007', // node ip 'http://34.123.40.181:30800', 'http://34.123.40.181:30700', @@ -27,7 +31,7 @@ const allowedOrigins = [ // frontend ip 'http://34.68.28.7:3000', ]; - + app.use( cors({ credentials: true, @@ -53,14 +57,14 @@ const questionRoutes = require('./routes/question-routes'); app.use('/questions', questionRoutes); mongoose - .connect( - process.env.MONGO_URL, - { useNewUrlParser: true, useUnifiedTopology: true } - ) + .connect(process.env.MONGO_URL, { + useNewUrlParser: true, + useUnifiedTopology: true, + }) .then(() => { console.log('Connected to MongoDB Atlas'); - app.listen(8001, () => { - console.log('Server is running on port 8001'); + app.listen(5001, () => { + console.log('Server is running on port 5001'); }); }) .catch((err) => { @@ -70,4 +74,4 @@ mongoose const connection = mongoose.connection; connection.on('error', () => { console.log('Error connecting to MongoDB Atlas 2'); -}); \ No newline at end of file +}); diff --git a/question-service/k8/question-service-values.yaml b/question-service/k8/question-service-values.yaml index 16139e3..9492ff9 100644 --- a/question-service/k8/question-service-values.yaml +++ b/question-service/k8/question-service-values.yaml @@ -4,6 +4,6 @@ secrets: service: type: NodePort - port: 8001 - targetPort: 8001 + port: 5001 + targetPort: 5001 nodePort: 30700 \ No newline at end of file diff --git a/question-service/k8/templates/deployment.yaml b/question-service/k8/templates/deployment.yaml index d346bbd..2be992a 100644 --- a/question-service/k8/templates/deployment.yaml +++ b/question-service/k8/templates/deployment.yaml @@ -16,7 +16,7 @@ spec: - name: question-service-container image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - - containerPort: 8001 + - containerPort: 5001 env: - name: MONGO_URL value: "{{ .Values.secrets.mongo_url }}" diff --git a/question-service/package.json b/question-service/package.json index 8a596e7..73fc01b 100644 --- a/question-service/package.json +++ b/question-service/package.json @@ -1,7 +1,6 @@ { "name": "question-service", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -17,5 +16,6 @@ "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mongoose": "^7.5.3" - } + }, + "description": "" } diff --git a/user-service/Dockerfile b/user-service/Dockerfile index 1c0b937..69e24f8 100644 --- a/user-service/Dockerfile +++ b/user-service/Dockerfile @@ -16,8 +16,8 @@ FROM node:20-alpine as main # Bundle the app's source code inside the Docker image. COPY --from=build /app / -# Expose port 8000 so it can be mapped by Docker daemon. -EXPOSE 8000 +# Expose port 5000 so it can be mapped by Docker daemon. +EXPOSE 5000 # Define the command to run your app using CMD which defines your runtime. CMD [ "npm", "start" ] diff --git a/user-service/index.js b/user-service/index.js index e64218b..5ecc8ee 100644 --- a/user-service/index.js +++ b/user-service/index.js @@ -8,11 +8,18 @@ const app = express(); app.use(express.json()); const allowedOrigins = [ + // Local ip 'http://localhost:3000', - 'http://localhost:8000', - 'http://localhost:8001', - 'http://localhost:8002', - 'http://localhost:8006', + 'http://localhost:5000', + 'http://localhost:5001', + 'http://localhost:5002', + 'http://localhost:5003', + 'http://localhost:5004', + 'http://localhost:5005', + 'http://localhost:5006', + 'http://localhost:5007', + + // Deployment ip below // node ip 'http://34.123.40.181:30800', 'http://34.123.40.181:30700', @@ -51,6 +58,6 @@ const userRoutes = require('./routes/user-routes'); app.use('/users', userRoutes); -app.listen(8000, () => { - console.log('User service started on port 8000'); +app.listen(5000, () => { + console.log('User service started on port 5000'); }); diff --git a/user-service/k8/templates/deployment.yaml b/user-service/k8/templates/deployment.yaml index fff13d1..5fad36f 100644 --- a/user-service/k8/templates/deployment.yaml +++ b/user-service/k8/templates/deployment.yaml @@ -16,7 +16,7 @@ spec: - name: user-service-container image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - - containerPort: 8000 + - containerPort: 5000 env: - name: POSTGRES_USER value: "{{ .Values.secrets.postgres_user }}" diff --git a/user-service/package.json b/user-service/package.json index cbe2a54..1172253 100644 --- a/user-service/package.json +++ b/user-service/package.json @@ -1,7 +1,6 @@ { "name": "user-service", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -17,5 +16,6 @@ "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "pg": "^8.11.3" - } + }, + "description": "" }