microservices/assignment-service/routes/InstructorRouter.js

268 lines
10 KiB
JavaScript
Raw Normal View History

2025-04-24 11:36:30 -07:00
const intructorRouter = require("express").Router();
const passport = require("passport");
const axios = require("axios");
const multer = require("multer");
const FormData = require("form-data");
2025-05-02 12:41:41 -07:00
2025-05-01 16:07:55 -07:00
const DB_ASSIGNMENT_SERVICE_URL =
process.env.DB_ASSIGNMENT_SERVICE_URL || "http://localhost:3000";
const DEPLOY_API_URL = process.env.DEPLOY_API_URL || "http://localhost:3600";
2025-05-07 23:30:37 -07:00
const PROXY_URL = process.env.PROXY_URL;
2025-04-29 12:01:10 -07:00
console.log("DB_ASSIGNMENT_SERVICE_URL:", DB_ASSIGNMENT_SERVICE_URL);
console.log("DEPLOY_API_URL:", DEPLOY_API_URL);
2025-05-02 12:41:41 -07:00
// Use memory storage to keep file in RAM
const upload = multer({ storage: multer.memoryStorage() });
2025-04-25 11:07:46 -07:00
// This endpoint is for instructors to create a new assignment
intructorRouter.post(
"/create",
upload.single("file"),
// passport.authenticate("jwt", { session: false }),
2025-04-29 12:01:10 -07:00
async (req, res) => {
2025-05-01 16:07:55 -07:00
try {
2025-05-02 12:41:41 -07:00
const file = req.file;
const assignmentData = req.body;
if (!file) {
return res.status(400).send("No file uploaded.");
2025-05-02 12:41:41 -07:00
}
//insert the initial assignment data into the database
2025-05-01 16:07:55 -07:00
console.log("Creating a new assignment with data:", req.body);
const dbResponse = await axios.post(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments`,
req.body
);
const assignmentId = dbResponse.data.assignment.assignmentid;
console.log("Assignment created with ID:", assignmentId);
console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", dbResponse.data);
// call upload api to upload the file to S3
console.log("Uploading file to:", `${DEPLOY_API_URL}/${assignmentData.appname}/upload`);
const uploadResponse = await axios.post(`${DEPLOY_API_URL}/${assignmentData.appname}/upload`, {
"appName": assignmentData.appname,
"notebookName": file.originalname,
"fileContentBase64": file.buffer.toString('base64'),
});
console.log('Response from DEPLOY_API_URL:', uploadResponse.data);
// Deploy a new Battlesnake API
console.log('Deploying a new Battlesnake API');
console.log("DEPLOY_API_URL:", DEPLOY_API_URL, assignmentData.appname);
const deployResponse = await axios.post(`${DEPLOY_API_URL}/deploy`, {
"appName": assignmentData.appname
});
console.log('Response from DEPLOY_API_URL:', deployResponse.data);
const ipv6 = deployResponse.data.ipv6;
console.log("Deployed Battlesnake API IPv6:", ipv6);
// Update the assignment with the deployment details
const updatedAssignmentData = {
2025-05-07 23:30:37 -07:00
assignmenturl: `${PROXY_URL}/${ipv6}`,
}
2025-05-08 00:14:10 -07:00
console.log("Updating assignment with deployment details:", updatedAssignmentData);
const updateRespone = await axios.put(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`,
updatedAssignmentData
);
console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", updateRespone.data);
res.status(deployResponse.status).json(deployResponse.data);
2025-05-01 16:07:55 -07:00
} catch (error) {
console.error("Error creating assignment:", error.message);
//delete the file from s3 and the database if the assignment creation fails
try {
console.log("Deleting file from S3 due to error in assignment creation");
await axios.post(`${DEPLOY_API_URL}/${req.body.appname}/delete`, {
"appName": req.body.appname
});
console.log('Response from DEPLOY_API_URL:', error.response.data);
} catch (deleteError) {
console.error("Error deleting file from S3:", deleteError.message);
}
//delete the assignment from the database
try {
console.log("Deleting assignment from database due to error in assignment creation");
await axios.delete(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`
);
} catch (deleteError) {
console.error("Error deleting assignment from database:", deleteError.message);
}
//send the error response to the client
console.error("Error response from DB_ASSIGNMENT_SERVICE_URL:", error.response.data);
console.error("Error response status:", error.response.status);
2025-05-01 16:07:55 -07:00
res.status(error.response?.status || 500).json({ error: error.message });
}
2025-04-24 11:36:30 -07:00
}
2025-05-01 16:07:55 -07:00
);
2025-04-24 11:36:30 -07:00
2025-04-29 12:01:10 -07:00
// This endpoint is for instructors to get details of a specific assignment
intructorRouter.get("/details/:id", async (req, res) => {
2025-04-24 11:36:30 -07:00
try {
2025-04-29 12:01:10 -07:00
const assignmentId = req.params.id;
console.log("Fetching details for assignmentId:", assignmentId);
2025-05-01 16:07:55 -07:00
const response = await axios.get(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`
);
2025-04-29 12:01:10 -07:00
console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data);
2025-08-25 14:23:55 -07:00
console.log("Response status:", response.status);
2025-04-24 11:36:30 -07:00
res.status(response.status).json(response.data);
} catch (error) {
2025-04-29 12:01:10 -07:00
console.error("Error fetching assignment details:", error.message);
2025-04-24 11:36:30 -07:00
res.status(error.response?.status || 500).json({ error: error.message });
}
});
2025-04-29 12:01:10 -07:00
// This endpoint is for instructors to get a list of assignments they have created
2025-05-01 16:07:55 -07:00
intructorRouter.get(
"/list/:id",
// passport.authenticate("jwt", { session: false }),
async (req, res) => {
2025-08-25 14:23:55 -07:00
console.log("/list/:id endpoint hit");
2025-05-01 16:07:55 -07:00
// if (req.isAuthenticated()) {
2025-04-29 12:01:10 -07:00
try {
const instructorId = req.params.id;
2025-08-25 14:23:55 -07:00
console.log("Fetching assignments for instructorId:", instructorId);
2025-05-01 16:07:55 -07:00
const response = await axios.get(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/instructor/${instructorId}`
);
2025-08-25 14:23:55 -07:00
console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data);
console.log("Response status:", response.status);
2025-04-29 12:01:10 -07:00
res.status(response.status).json(response.data);
} catch (error) {
2025-08-25 14:23:55 -07:00
console.log("Error fetching assignments:", error.response);
console.error("Error fetching assignments:", error.message);
2025-04-29 12:01:10 -07:00
res.status(error.response?.status || 500).json({ error: error.message });
}
2025-05-01 16:07:55 -07:00
// } else {
// return res.status(401).json({ error: "Not authenticated" });
// }
}
);
2025-04-29 12:01:10 -07:00
2025-04-25 11:07:46 -07:00
// This endpoint is for instructors to update an assignment
2025-05-01 16:07:55 -07:00
intructorRouter.put(
"/update/:id",
2025-05-05 22:21:24 -07:00
upload.none(), // No file upload for this endpoint
2025-05-01 16:07:55 -07:00
// passport.authenticate("jwt", { session: false }),
2025-04-29 12:01:10 -07:00
async (req, res) => {
2025-05-01 16:07:55 -07:00
try {
const assignmentId = req.params.id;
2025-05-05 22:21:24 -07:00
console.log("Updating assignment with ID:", assignmentId);
console.log("Request body:", req.body);
2025-05-01 16:07:55 -07:00
const response = await axios.put(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`,
req.body
);
2025-05-05 22:21:24 -07:00
console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data);
2025-05-01 16:07:55 -07:00
res.status(response.status).json(response.data);
} catch (error) {
2025-05-05 22:21:24 -07:00
console.error("Error updating assignment:", error.message);
2025-05-01 16:07:55 -07:00
res.status(error.response?.status || 500).json({ error: error.message });
}
2025-04-24 11:36:30 -07:00
}
2025-05-01 16:07:55 -07:00
);
2025-04-24 11:36:30 -07:00
2025-04-25 11:07:46 -07:00
// This endpoint is for instructors to delete an assignment
2025-05-01 16:07:55 -07:00
intructorRouter.delete(
"/delete/:id",
// passport.authenticate("jwt", { session: false }),
2025-04-29 12:01:10 -07:00
async (req, res) => {
2025-05-01 16:07:55 -07:00
try {
2025-05-06 13:28:01 -07:00
2025-05-01 16:07:55 -07:00
const assignmentId = req.params.id;
2025-05-06 13:28:01 -07:00
//get the assignment data from the database
console.log("Fetching assignment data for ID:", assignmentId);
const assignmentResponse = await axios.get(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`
);
const assignmentData = assignmentResponse.data;
console.log("Assignment data:", assignmentData);
if (!assignmentData) {
return res.status(404).json({ error: "Assignment not found" });
2025-08-25 14:23:55 -07:00
}
2025-05-06 13:28:01 -07:00
// Delete the Battlesnake API
2025-08-25 14:23:55 -07:00
if (assignmentData.appname) {
console.log(`Deleting Battlesnake API: ${assignmentData.appname}`);
const deployResponse = await axios.post(`${DEPLOY_API_URL}/${assignmentData.appname}/delete`, {
"appName": assignmentData.appname
});
//throw error if the response is not 200
console.log('Response from DEPLOY_API_URL:', deployResponse.data);
if (deployResponse.status !== 200) {
throw new Error(`Failed to delete Battlesnake API: ${deployResponse.statusText}`);
}
console.log('Response from DEPLOY_API_URL:', deployResponse.data);
2025-05-06 13:28:01 -07:00
}
2025-08-25 14:23:55 -07:00
2025-05-08 00:14:10 -07:00
console.log("Deleting assignment from database:", assignmentId);
2025-05-01 16:07:55 -07:00
const response = await axios.delete(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${assignmentId}`
);
2025-05-08 00:14:10 -07:00
console.log("Response from DB_ASSIGNMENT_SERVICE_URL:", response.data);
2025-05-01 16:07:55 -07:00
res.status(response.status).json(response.data);
} catch (error) {
res.status(error.response?.status || 500).json({ error: error.message });
}
2025-04-24 11:36:30 -07:00
}
2025-05-01 16:07:55 -07:00
);
2025-04-24 11:36:30 -07:00
//get assignment by appname
intructorRouter.get(
"/checkAssignmentByAppName/:appName",
// passport.authenticate("jwt", { session: false }),
async (req, res) => {
try {
const appName = req.params.appName;
console.log("Fetching assignment for appName:", appName);
const response = await axios.get(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/appname/${appName}`
);
console.log("Response data:", response.data);
2025-08-25 14:23:55 -07:00
res.status(response.status).json({ "exists": (response.data !== null && response.data !== undefined) });
} catch (error) {
console.error("Error fetching assignment by app name:", error.message);
res.status(error.response?.status || 500).json({ error: error.message });
}
}
);
//get assignment by qrcode number
intructorRouter.get(
"/checkAssignmentByQRCode/:qrcode",
// passport.authenticate("jwt", { session: false }),
async (req, res) => {
try {
const qrcode = req.params.qrcode;
console.log("Fetching assignment for qrcode:", qrcode);
const response = await axios.get(
`${DB_ASSIGNMENT_SERVICE_URL}/assignments/${qrcode}`
);
console.log("Response data:", response.data);
2025-08-25 14:23:55 -07:00
res.status(response.status).json({ "exists": (response.data !== null && response.data !== undefined) });
} catch (error) {
console.error("Error fetching assignment by QR code:", error.message);
res.status(error.response?.status || 500).json({ error: error.message });
}
}
);
2025-05-01 16:07:55 -07:00
module.exports = intructorRouter;