Skip to content

Commit

Permalink
Add collab service kubernetes
Browse files Browse the repository at this point in the history
  • Loading branch information
jq1836 committed Nov 5, 2024
2 parents eb7d5ba + dda9217 commit c90bf92
Show file tree
Hide file tree
Showing 45 changed files with 3,932 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ EMAIL_PASSWORD=
## Matching service variables
MATCHING_SERVICE_SERVICE_PORT=6969

## Collab service variables
COLLAB_SERVICE_SERVICE_PORT=3002
COLLAB_SVC_DB_URI=
OPENAI_API_KEY=

## Redis variables
REDIS_SERVICE_PORT=6379

Expand Down
4 changes: 4 additions & 0 deletions api-gateway/templates/api_conf.d/api_backends.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ upstream matching-service {
server $MATCHING_SERVICE_SERVICE_HOST:$MATCHING_SERVICE_SERVICE_PORT;
}

upstream collab-service {
server $COLLAB_SERVICE_SERVICE_HOST:$COLLAB_SERVICE_SERVICE_PORT;
}

upstream frontend {
server $FRONTEND_SERVICE_HOST:$FRONTEND_SERVICE_PORT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
location /private/collab-service/ {
proxy_pass http://collab-service/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
location /public/collab-service/ {
location /public/collab-service/chat {
proxy_pass http://collab-service/chat;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /public/collab-service/yjs {
proxy_pass http://collab-service/yjs;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
2 changes: 2 additions & 0 deletions collab-service/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.env
6 changes: 6 additions & 0 deletions collab-service/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": false
}
21 changes: 21 additions & 0 deletions collab-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Base image
FROM node:20-alpine AS base
WORKDIR /app
COPY package*.json ./

# Install dependencies in base stage
RUN npm install

# Development stage
FROM base AS dev
COPY . .
# Run the JavaScript code directly in dev mode (useful for hot-reloading)
CMD ["npm", "run", "dev"]

# Production stage
FROM node:20-alpine AS prod
WORKDIR /app
COPY --from=base /app/node_modules ./node_modules
COPY . .
# Start the server in production mode
CMD ["npm", "start"]
19 changes: 19 additions & 0 deletions collab-service/app/controller/ai-controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { sendAiMessage } from "../model/repository.js";

// send ai message
export async function sendAiMessageController(req, res) {
const { message } = req.body;
if (!message) {
return res.status(400).json({ error: "Message content is required" });
}

const data = await sendAiMessage(message);
const aiResponse =
data.choices?.[0]?.message?.content || "No response from AI";

if (aiResponse) {
res.status(200).json({ data });
} else {
res.status(500).json({ error: "Failed to retrieve AI response" });
}
}
107 changes: 107 additions & 0 deletions collab-service/app/controller/collab-controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {
newRoom,
getRoomId,
getAllRooms,
fetchRoomChatHistory,
getQuestionIdByRoomId,
getAllRoomsByUserId,
} from "../model/repository.js";
import crypto from "crypto";

// Create a room between two users
export async function createRoom(req, res) {
const { user1, user2, question_id } = req.body;

if (!user1 || !user2 || !question_id) {
return res
.status(400)
.json({ error: "user1,user2 and question_id are required" });
}

// Generate a unique room ID by hashing the two user IDs
const timeSalt = new Date().toISOString().slice(0, 19);
const roomId = crypto
.createHash("sha256")
.update(user1 + user2 + timeSalt)
.digest("hex");
const room = await newRoom(user1, user2, roomId, question_id);

if (room) {
res.status(201).json(room);
} else {
res.status(500).json({ error: "Failed to create room" });
}
}

// Get room ID by user
export async function getRoomByUser(req, res) {
const { user } = req.params;

if (!user) {
return res.status(400).json({ error: "User is required" });
}

const room = await getRoomId(user);

if (room) {
res.status(200).json(room);
} else {
res.status(404).json({ error: `Room not found for user: ${user}` });
}
}

// Get all rooms
export async function getAllRoomsController(req, res) {
const rooms = await getAllRooms();

if (rooms) {
res.status(200).json(rooms);
} else {
res.status(500).json({ error: "Failed to retrieve rooms" });
}
}

// Get all rooms by user
export async function getAllRoomsByUser(req, res) {
const { user } = req.params;
const rooms = await getAllRoomsByUserId(user);

if (rooms) {
res.status(200).json(rooms);
} else {
res.status(500).json({ error: "Failed to retrieve rooms" });
}
}
export async function getRoomChatHistory(req, res) {
const { roomId } = req.params;

if (!roomId) {
return res.status(400).json({ error: "Room ID is required" });
}

const room = await fetchRoomChatHistory(roomId);

if (room) {
res.status(200).json(room);
} else {
res.status(404).json({ error: `Room not found for ID: ${roomId}` });
}
}

// Get QuestionId from the room based on the roomId
export async function getQuestionId(req, res) {
const { roomId } = req.params;

if (!roomId) {
return res.status(400).json({ error: "Room ID is required" });
}
const questionId = await getQuestionIdByRoomId(roomId);

if (questionId) {
res.status(200).json({ questionId });
} else {
res
.status(404)
.json({ error: `Question ID not found for room ID: ${roomId}` });
}
}
56 changes: 56 additions & 0 deletions collab-service/app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import express from "express";
import cors from "cors";
import collabRoutes from "./routes/collab-routes.js";

const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cors()); // config cors so that front-end can use
app.options("*", cors());

// To handle CORS Errors
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*"); // "*" -> Allow all links to access

res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);

// Browsers usually send this before PUT or POST Requests
if (req.method === "OPTIONS") {
res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH");
return res.status(200).json({});
}

// Continue Route Processing
next();
});

app.use("/collab", collabRoutes);

app.get("/", (req, res, next) => {
console.log("Sending Greetings!");
res.json({
message: "Hello World from collab-service",
});
});

// Handle When No Route Match Is Found
app.use((req, res, next) => {
const error = new Error("Route Not Found");
error.status = 404;
next(error);
});

app.use((error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message,
},
});
});

export default app;
Loading

0 comments on commit c90bf92

Please sign in to comment.