Use service registry instead of adding services to request
This commit is contained in:
1 parent
139c1fd215
commit
83e489cfe5
1 file changed
+149
-113
+149
-113
@@ -8,16 +8,31 @@ import cors from "cors";
|
||||
import logger from "./utils/logger.js";
|
||||
import { verifyJWT } from "./middleware/verifyJWT.js";
|
||||
import { handleErrors } from "./middleware/handleErrors.js";
|
||||
import authRouter from "./routes/authRoute.js";
|
||||
import inviteRouter from "./routes/inviteRoute.js";
|
||||
import monitorRouter from "./routes/monitorRoute.js";
|
||||
import checkRouter from "./routes/checkRoute.js";
|
||||
import maintenanceWindowRouter from "./routes/maintenanceWindowRoute.js";
|
||||
import settingsRouter from "./routes/settingsRoute.js";
|
||||
import statusPageRouter from "./routes/statusPageRoute.js";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
import queueRouter from "./routes/queueRoute.js";
|
||||
import AuthRoutes from "./routes/authRoute.js";
|
||||
import AuthController from "./controllers/authController.js";
|
||||
|
||||
import InviteRoutes from "./routes/inviteRoute.js";
|
||||
import InviteController from "./controllers/inviteController.js";
|
||||
|
||||
import MonitorRoutes from "./routes/monitorRoute.js";
|
||||
import MonitorController from "./controllers/monitorController.js";
|
||||
|
||||
import CheckRoutes from "./routes/checkRoute.js";
|
||||
import CheckController from "./controllers/checkController.js";
|
||||
|
||||
import MaintenanceWindowRoutes from "./routes/maintenanceWindowRoute.js";
|
||||
import MaintenanceWindowController from "./controllers/maintenanceWindowController.js";
|
||||
|
||||
import SettingsRoutes from "./routes/settingsRoute.js";
|
||||
import SettingsController from "./controllers/settingsController.js";
|
||||
|
||||
import StatusPageRoutes from "./routes/statusPageRoute.js";
|
||||
import StatusPageController from "./controllers/statusPageController.js";
|
||||
|
||||
import QueueRoutes from "./routes/queueRoute.js";
|
||||
import QueueController from "./controllers/queueController.js";
|
||||
|
||||
//JobQueue service and dependencies
|
||||
import JobQueue from "./service/jobQueue.js";
|
||||
@@ -41,102 +56,68 @@ import mjml2html from "mjml";
|
||||
import SettingsService from "./service/settingsService.js";
|
||||
import AppSettings from "./db/models/AppSettings.js";
|
||||
|
||||
// Status Service and dependencies
|
||||
import StatusService from "./service/statusService.js";
|
||||
|
||||
// Notification Service and dependencies
|
||||
import NotificationService from "./service/notificationService.js";
|
||||
|
||||
import db from "./db/mongo/MongoDB.js";
|
||||
// Service Registry
|
||||
import ServiceRegistry from "./service/serviceRegistry.js";
|
||||
|
||||
import MongoDB from "./db/mongo/MongoDB.js";
|
||||
|
||||
const SERVICE_NAME = "Server";
|
||||
const SHUTDOWN_TIMEOUT = 1000;
|
||||
|
||||
let isShuttingDown = false;
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const openApiSpec = JSON.parse(
|
||||
fs.readFileSync(path.join(__dirname, "openapi.json"), "utf8")
|
||||
);
|
||||
|
||||
let server;
|
||||
|
||||
const PORT = 5000;
|
||||
|
||||
const shutdown = async () => {
|
||||
if (isShuttingDown) {
|
||||
return;
|
||||
}
|
||||
isShuttingDown = true;
|
||||
logger.info({ message: "Attempting graceful shutdown" });
|
||||
setTimeout(() => {
|
||||
logger.error({
|
||||
message: "Could not shut down in time, forcing shutdown",
|
||||
service: SERVICE_NAME,
|
||||
method: "shutdown",
|
||||
});
|
||||
process.exit(1);
|
||||
}, SHUTDOWN_TIMEOUT);
|
||||
try {
|
||||
server.close();
|
||||
await ServiceRegistry.get(JobQueue.SERVICE_NAME).obliterate();
|
||||
await ServiceRegistry.get(MongoDB.SERVICE_NAME).disconnect();
|
||||
logger.info({ message: "Graceful shutdown complete" });
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "shutdown",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
};
|
||||
// Need to wrap server setup in a function to handle async nature of JobQueue
|
||||
const startApp = async () => {
|
||||
const app = express();
|
||||
|
||||
// middlewares
|
||||
app.use(
|
||||
cors()
|
||||
//We will add configuration later
|
||||
);
|
||||
app.use(express.json());
|
||||
app.use(helmet());
|
||||
|
||||
// Add db, jobQueue, emailService, and settingsService to request object for easy access
|
||||
app.use((req, res, next) => {
|
||||
req.db = db;
|
||||
req.jobQueue = jobQueue;
|
||||
req.emailService = emailService;
|
||||
req.settingsService = settingsService;
|
||||
next();
|
||||
});
|
||||
|
||||
// Swagger UI
|
||||
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(openApiSpec));
|
||||
|
||||
//routes
|
||||
app.use("/api/v1/auth", authRouter);
|
||||
app.use("/api/v1/settings", verifyJWT, settingsRouter);
|
||||
app.use("/api/v1/invite", inviteRouter);
|
||||
app.use("/api/v1/monitors", verifyJWT, monitorRouter);
|
||||
app.use("/api/v1/checks", verifyJWT, checkRouter);
|
||||
app.use("/api/v1/maintenance-window", verifyJWT, maintenanceWindowRouter);
|
||||
app.use("/api/v1/queue", verifyJWT, queueRouter);
|
||||
app.use("/api/v1/status-page", statusPageRouter);
|
||||
|
||||
app.use("/api/v1/dummy-data", async (req, res) => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
"https://gist.githubusercontent.com/ajhollid/9afa39410c7bbf52cc905f285a2225bf/raw/429a231a3559ebc95f6f488ed2c766bd7d6f46e5/dummyData.json",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "no-cache",
|
||||
},
|
||||
}
|
||||
);
|
||||
return res.status(200).json(response.data);
|
||||
} catch (error) {
|
||||
return res.status(500).json({ message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
//health check
|
||||
app.use("/api/v1/healthy", (req, res) => {
|
||||
try {
|
||||
logger.info({ message: "Checking Health of the server." });
|
||||
return res.status(200).json({ message: "Healthy" });
|
||||
} catch (error) {
|
||||
logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "healthCheck",
|
||||
stack: error.stack,
|
||||
});
|
||||
return res.status(500).json({ message: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Error handler middleware
|
||||
* Should be called last
|
||||
*/
|
||||
app.use(handleErrors);
|
||||
// Create DB
|
||||
const db = new MongoDB();
|
||||
await db.connect();
|
||||
|
||||
// Create services
|
||||
await db.connect();
|
||||
const server = app.listen(PORT, () => {
|
||||
logger.info({ message: `server started on port:${PORT}` });
|
||||
});
|
||||
|
||||
const settingsService = new SettingsService(AppSettings);
|
||||
await settingsService.loadSettings();
|
||||
const emailService = new EmailService(
|
||||
@@ -162,39 +143,94 @@ const startApp = async () => {
|
||||
Worker
|
||||
);
|
||||
|
||||
const shutdown = async () => {
|
||||
if (isShuttingDown) {
|
||||
return;
|
||||
}
|
||||
isShuttingDown = true;
|
||||
logger.info({ message: "Attempting graceful shutdown" });
|
||||
setTimeout(() => {
|
||||
logger.error({
|
||||
message: "Could not shut down in time, forcing shutdown",
|
||||
service: SERVICE_NAME,
|
||||
method: "shutdown",
|
||||
});
|
||||
process.exit(1);
|
||||
}, SHUTDOWN_TIMEOUT);
|
||||
try {
|
||||
server.close();
|
||||
await jobQueue.obliterate();
|
||||
await db.disconnect();
|
||||
logger.info({ message: "Graceful shutdown complete" });
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "shutdown",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
};
|
||||
// Register services
|
||||
ServiceRegistry.register(JobQueue.SERVICE_NAME, jobQueue);
|
||||
ServiceRegistry.register(MongoDB.SERVICE_NAME, db);
|
||||
ServiceRegistry.register(SettingsService.SERVICE_NAME, settingsService);
|
||||
ServiceRegistry.register(EmailService.SERVICE_NAME, emailService);
|
||||
ServiceRegistry.register(NetworkService.SERVICE_NAME, networkService);
|
||||
ServiceRegistry.register(StatusService.SERVICE_NAME, statusService);
|
||||
ServiceRegistry.register(NotificationService.SERVICE_NAME, notificationService);
|
||||
server = app.listen(PORT, () => {
|
||||
logger.info({ message: `server started on port:${PORT}` });
|
||||
});
|
||||
|
||||
process.on("SIGUSR2", shutdown);
|
||||
process.on("SIGINT", shutdown);
|
||||
process.on("SIGTERM", shutdown);
|
||||
|
||||
//Create controllers
|
||||
const authController = new AuthController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
ServiceRegistry.get(EmailService.SERVICE_NAME),
|
||||
ServiceRegistry.get(JobQueue.SERVICE_NAME)
|
||||
);
|
||||
|
||||
const monitorController = new MonitorController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
ServiceRegistry.get(JobQueue.SERVICE_NAME)
|
||||
);
|
||||
|
||||
const settingsController = new SettingsController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME)
|
||||
);
|
||||
|
||||
const checkController = new CheckController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME)
|
||||
);
|
||||
|
||||
const inviteController = new InviteController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
ServiceRegistry.get(EmailService.SERVICE_NAME)
|
||||
);
|
||||
|
||||
const maintenanceWindowController = new MaintenanceWindowController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME)
|
||||
);
|
||||
|
||||
const queueController = new QueueController(ServiceRegistry.get(JobQueue.SERVICE_NAME));
|
||||
|
||||
const statusPageController = new StatusPageController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME)
|
||||
);
|
||||
|
||||
//Create routes
|
||||
const authRoutes = new AuthRoutes(authController);
|
||||
const monitorRoutes = new MonitorRoutes(monitorController);
|
||||
const settingsRoutes = new SettingsRoutes(settingsController);
|
||||
const checkRoutes = new CheckRoutes(checkController);
|
||||
const inviteRoutes = new InviteRoutes(inviteController);
|
||||
const maintenanceWindowRoutes = new MaintenanceWindowRoutes(
|
||||
maintenanceWindowController
|
||||
);
|
||||
const queueRoutes = new QueueRoutes(queueController);
|
||||
const statusPageRoutes = new StatusPageRoutes(statusPageController);
|
||||
// Middleware
|
||||
app.use(
|
||||
cors()
|
||||
//We will add configuration later
|
||||
);
|
||||
app.use(express.json());
|
||||
app.use(helmet());
|
||||
// Swagger UI
|
||||
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(openApiSpec));
|
||||
|
||||
//routes
|
||||
app.use("/api/v1/auth", authRoutes.getRouter());
|
||||
app.use("/api/v1/settings", verifyJWT, settingsRoutes.getRouter());
|
||||
app.use("/api/v1/invite", inviteRoutes.getRouter());
|
||||
app.use("/api/v1/monitors", verifyJWT, monitorRoutes.getRouter());
|
||||
app.use("/api/v1/checks", verifyJWT, checkRoutes.getRouter());
|
||||
app.use("/api/v1/maintenance-window", verifyJWT, maintenanceWindowRoutes.getRouter());
|
||||
app.use("/api/v1/queue", verifyJWT, queueRoutes.getRouter());
|
||||
app.use("/api/v1/status-page", statusPageRoutes.getRouter());
|
||||
app.use(handleErrors);
|
||||
};
|
||||
|
||||
startApp().catch((error) => {
|
||||
|
||||
Reference in new issue
Block a user