committed
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
@@ -128,3 +129,10 @@ dist
|
|||||||
.yarn/build-state.yml
|
.yarn/build-state.yml
|
||||||
.yarn/install-state.gz
|
.yarn/install-state.gz
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
=======
|
||||||
|
node_modules/
|
||||||
|
.env
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
|
||||||
|
>>>>>>> b3f28e6 (committed)
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
FROM node:22
|
||||||
|
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD [ "node", "src/server.js" ]
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
depends_on:
|
||||||
|
- mongodb
|
||||||
|
- kafka
|
||||||
|
environment:
|
||||||
|
- MONGODB_URI=mongodb://mongodb:27017/test # Updated to use 'test' database
|
||||||
|
- KAFKA_BROKERS=kafka:9092
|
||||||
|
|
||||||
|
mongodb:
|
||||||
|
image: mongo:latest
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
volumes:
|
||||||
|
- mongodb_data:/data/db
|
||||||
|
|
||||||
|
kafka:
|
||||||
|
image: wurstmeister/kafka:latest
|
||||||
|
ports:
|
||||||
|
- "9092:9092"
|
||||||
|
environment:
|
||||||
|
KAFKA_ADVERTISED_HOST_NAME: kafka
|
||||||
|
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
||||||
|
depends_on:
|
||||||
|
- zookeeper
|
||||||
|
|
||||||
|
zookeeper:
|
||||||
|
image: wurstmeister/zookeeper:latest
|
||||||
|
ports:
|
||||||
|
- "2181:2181"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mongodb_data:{}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const notificationSchema = new mongoose.Schema({
|
||||||
|
message: { type: String, required: true },
|
||||||
|
userId: { type: String, required: true },
|
||||||
|
priority: { type: String, enum: ['low', 'normal', 'high'], default: 'normal' },
|
||||||
|
sendTime: { type: Date },
|
||||||
|
createdAt: { type: Date, default: Date.now },
|
||||||
|
status: { type: String, enum: ['pending', 'sent', 'failed'], default: 'pending' }
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Notification', notificationSchema);
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const userSchema = new mongoose.Schema({
|
||||||
|
userId: { type: String, required: true, unique: true },
|
||||||
|
preferences: {
|
||||||
|
channels: [{ type: String, enum: ['email', 'sms', 'push'] }],
|
||||||
|
quietHours: {
|
||||||
|
start: { type: String, match: /^([01]\d|2[0-3]):([0-5]\d)$/ },
|
||||||
|
end: { type: String, match: /^([01]\d|2[0-3]):([0-5]\d)$/ }
|
||||||
|
},
|
||||||
|
notificationLimit: { type: Number, default: 3 }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('User', userSchema);
|
||||||
|
|
||||||
Generated
+1127
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "notification-system",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node src/server.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "commonjs",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^1.20.3",
|
||||||
|
"express": "^4.21.2",
|
||||||
|
"kafkajs": "^2.2.4",
|
||||||
|
"mongoose": "^8.9.3",
|
||||||
|
"node-schedule": "^2.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const Notification = require('../models/notification');
|
||||||
|
|
||||||
|
async function aggregateLowPriorityNotifications(userId) {
|
||||||
|
const oneHourFromNow = new Date(Date.now() + 60 * 60 * 1000);
|
||||||
|
const notifications = await Notification.find({
|
||||||
|
userId,
|
||||||
|
priority: 'low',
|
||||||
|
sendTime: { $lte: oneHourFromNow },
|
||||||
|
status: 'pending'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (notifications.length > 1) {
|
||||||
|
const summary = `You have ${notifications.length}
|
||||||
|
${notifications.map(n => '- ' + n.message).join('\n')}`;
|
||||||
|
|
||||||
|
await Notification.updateMany(
|
||||||
|
{ _id: { $in: notifications.map(n => n._id) } },
|
||||||
|
{ $set: { status: 'aggregated' } }
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Notification({
|
||||||
|
userId,
|
||||||
|
message: summary,
|
||||||
|
priority: 'low',
|
||||||
|
sendTime: new Date(),
|
||||||
|
status: 'pending'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { aggregateLowPriorityNotifications };
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
const Notification = require('../models/notification');
|
||||||
|
|
||||||
|
async function checkDuplication(notification) {
|
||||||
|
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
||||||
|
const similarNotification = await Notification.findOne({
|
||||||
|
userId: notification.userId,
|
||||||
|
message: notification.message,
|
||||||
|
createdAt: { $gte: oneHourAgo },
|
||||||
|
status: 'sent'
|
||||||
|
});
|
||||||
|
|
||||||
|
return !!similarNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { checkDuplication };
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
const User = require('../models/user');
|
||||||
|
|
||||||
|
function isInQuietHours(user, currentTime) {
|
||||||
|
if (!user.preferences.quietHours) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { start, end } = user.preferences.quietHours;
|
||||||
|
const [startHour, startMinute] = start.split(':').map(Number);
|
||||||
|
const [endHour, endMinute] = end.split(':').map(Number);
|
||||||
|
|
||||||
|
const startTime = new Date(currentTime);
|
||||||
|
startTime.setHours(startHour, startMinute, 0);
|
||||||
|
|
||||||
|
const endTime = new Date(currentTime);
|
||||||
|
endTime.setHours(endHour, endMinute, 0);
|
||||||
|
|
||||||
|
if (endTime < startTime) {
|
||||||
|
endTime.setDate(endTime.getDate() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentTime >= startTime && currentTime < endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { isInQuietHours };
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
const User = require('../models/user');
|
||||||
|
const Notification = require('../models/notification');
|
||||||
|
|
||||||
|
async function checkThrottling(userId) {
|
||||||
|
const user = await User.findOne({ userId });
|
||||||
|
if (!user) {
|
||||||
|
throw new Error('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
|
||||||
|
const recentNotifications = await Notification.countDocuments({
|
||||||
|
userId,
|
||||||
|
createdAt: { $gte: oneHourAgo },
|
||||||
|
status: 'sent'
|
||||||
|
});
|
||||||
|
|
||||||
|
return recentNotifications < user.preferences.notificationLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { checkThrottling };
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
const Notification = require('../models/notification');
|
||||||
|
|
||||||
|
async function getUrgentAlerts() {
|
||||||
|
return Notification.find({
|
||||||
|
priority: 'high',
|
||||||
|
status: 'pending'
|
||||||
|
}).sort({ createdAt: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getUrgentAlerts };
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const Notification = require('../models/notification');
|
||||||
|
|
||||||
|
router.get('/analytics', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const totalSent = await Notification.countDocuments({ status: 'sent' });
|
||||||
|
const totalFailed = await Notification.countDocuments({ status: 'failed' });
|
||||||
|
const totalRetried = await Notification.countDocuments({ status: 'retried' });
|
||||||
|
|
||||||
|
const deliveryStats = {
|
||||||
|
totalSent,
|
||||||
|
totalFailed,
|
||||||
|
totalRetried
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const sentNotifications = await Notification.find({ status: 'sent' });
|
||||||
|
const totalDeliveryTime = sentNotifications.reduce((sum, notification) => {
|
||||||
|
return sum + (notification.sentAt - notification.createdAt);
|
||||||
|
}, 0);
|
||||||
|
const averageDeliveryTime = totalDeliveryTime / sentNotifications.length;
|
||||||
|
|
||||||
|
|
||||||
|
const totalResponses = await Notification.countDocuments({ userResponded: true });
|
||||||
|
const responseRate = totalResponses / totalSent;
|
||||||
|
|
||||||
|
const userEngagement = {
|
||||||
|
averageDeliveryTime,
|
||||||
|
responseRate
|
||||||
|
};
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
deliveryStats,
|
||||||
|
userEngagement
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error generating analytics:', error);
|
||||||
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
const User = require('../models/user');
|
||||||
|
const Notification = require('../models/notification');
|
||||||
|
const { checkThrottling } = require('../queries/throttling');
|
||||||
|
const { isInQuietHours } = require('../queries/quietHours');
|
||||||
|
const { checkDuplication } = require('../queries/deduplication');
|
||||||
|
const { aggregateLowPriorityNotifications } = require('../queries/aggregation');
|
||||||
|
const { getUrgentAlerts } = require('../queries/urgentAlerts');
|
||||||
|
const { MongoClient } = require('mongodb');
|
||||||
|
const mongoClient = new MongoClient('mongodb://localhost:27017');
|
||||||
|
|
||||||
|
async function deliverNotifications() {
|
||||||
|
|
||||||
|
const urgentAlerts = await getUrgentAlerts();
|
||||||
|
for (const alert of urgentAlerts) {
|
||||||
|
await processNotification(alert);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pendingNotifications = await Notification.find({ status: 'pending', priority: { $ne: 'high' } });
|
||||||
|
for (const notification of pendingNotifications) {
|
||||||
|
await processNotification(notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processNotification(notification) {
|
||||||
|
await mongoClient.connect();
|
||||||
|
const user = await User.findOne({ userId: notification.userId });
|
||||||
|
if (!user) {
|
||||||
|
console.error(`User not found for notification: ${notification._id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await checkThrottling(user.userId))) {
|
||||||
|
await rescheduleNotification(notification);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInQuietHours(user, new Date())) {
|
||||||
|
await rescheduleNotification(notification);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await checkDuplication(notification)) {
|
||||||
|
|
||||||
|
const db = mongoClient.db('test');
|
||||||
|
await Notification.updateOne({ _id: notification._id }, { status: 'suppressed' });
|
||||||
|
// await db.collection('scheduledNotifications').deleteOne({ _id: notification._id });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.priority === 'low') {
|
||||||
|
const aggregatedNotification = await aggregateLowPriorityNotifications(user.userId);
|
||||||
|
if (aggregatedNotification) {
|
||||||
|
await sendNotification(aggregatedNotification, user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await sendNotification(notification, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendNotification(notification, user) {
|
||||||
|
for (const channel of user.preferences.channels) {
|
||||||
|
try {
|
||||||
|
switch (channel) {
|
||||||
|
case 'email':
|
||||||
|
await sendEmail(notification, user);
|
||||||
|
break;
|
||||||
|
case 'sms':
|
||||||
|
await sendSMS(notification, user);
|
||||||
|
break;
|
||||||
|
case 'push':
|
||||||
|
await sendPushNotification(notification, user);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await Notification.updateOne({ _id: notification._id }, { status: 'sent' });
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to send notification via ${channel}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Notification.updateOne({ _id: notification._id }, { status: 'failed' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function rescheduleNotification(notification) {
|
||||||
|
const newSendTime = new Date(Date.now() + 60 * 60 * 1000); // Reschedule for 1 hour later
|
||||||
|
const db = mongoClient.db('test');
|
||||||
|
await Notification.updateOne({ _id: notification._id }, { sendTime: newSendTime });
|
||||||
|
await db.collection('scheduledNotifications').updateOne({ _id: notification._id }, { sendTime: newSendTime });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock delivery functions
|
||||||
|
async function sendEmail(notification, user) {
|
||||||
|
console.log(`Sending email to ${user.userId}: ${notification.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendSMS(notification, user) {
|
||||||
|
console.log(`Sending SMS to ${user.userId}: ${notification.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendPushNotification(notification, user) {
|
||||||
|
console.log(`Sending push notification to ${user.userId}: ${notification.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { deliverNotifications,sendNotification };
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const { Kafka } = require('kafkajs');
|
||||||
|
const router = express.Router();
|
||||||
|
const Notification = require('../models/notification');
|
||||||
|
const { MongoClient } = require('mongodb');
|
||||||
|
const kafka = new Kafka({ clientId: 'notification-app', brokers: ['localhost:9092'] });
|
||||||
|
const producer = kafka.producer();
|
||||||
|
const mongoClient = new MongoClient('mongodb://localhost:27017');
|
||||||
|
|
||||||
|
router.post('/notify', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { message, userId, priority, sendTime } = req.body;
|
||||||
|
|
||||||
|
if (!message || !userId) {
|
||||||
|
return res.status(400).json({ error: 'Missing required fields' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const notification = new Notification({
|
||||||
|
message,
|
||||||
|
userId,
|
||||||
|
priority: priority || 'normal',
|
||||||
|
sendTime: sendTime,
|
||||||
|
createdAt: new Date(),
|
||||||
|
status: 'pending'
|
||||||
|
});
|
||||||
|
|
||||||
|
await notification.save();
|
||||||
|
// await mongoClient.connect();
|
||||||
|
// const db = mongoClient.db('notifications');
|
||||||
|
// await db.collection('notification').insertOne(notification);
|
||||||
|
|
||||||
|
|
||||||
|
// Publish to Kafka
|
||||||
|
await producer.connect();
|
||||||
|
await producer.send({
|
||||||
|
topic: 'notifications',
|
||||||
|
messages: [{ value: JSON.stringify(notification) }],
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Notification received' });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error processing notification:', error);
|
||||||
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
|
} finally {
|
||||||
|
await producer.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
const { Kafka } = require('kafkajs');
|
||||||
|
const { MongoClient } = require('mongodb');
|
||||||
|
const User = require('../models/user');
|
||||||
|
const Notification = require('../models/notification');
|
||||||
|
const schedule = require('node-schedule');
|
||||||
|
// const {sendNotification} = require('./notificationDelivery')
|
||||||
|
const { checkDuplication } = require('../queries/deduplication');
|
||||||
|
const kafka = new Kafka({ clientId: 'notification-processor', brokers: ['localhost:9092'] });
|
||||||
|
const consumer = kafka.consumer({ groupId: 'notification-processor-group' });
|
||||||
|
const mongoClient = new MongoClient('mongodb://localhost:27017');
|
||||||
|
|
||||||
|
async function processNotifications() {
|
||||||
|
await consumer.connect();
|
||||||
|
await consumer.subscribe({ topic: 'notifications', fromBeginning: true });
|
||||||
|
|
||||||
|
await consumer.run({
|
||||||
|
eachMessage: async ({ message }) => {
|
||||||
|
const notification = JSON.parse(message.value.toString());
|
||||||
|
if (notification.priority == 'high' || !notification.sendTime || new Date(notification.sendTime) <= new Date() )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Process immediately
|
||||||
|
// if (await checkDuplication(notification)) {
|
||||||
|
// await Notification.updateOne({ _id: notification._id }, { status: 'suppressed' });
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// const user = await User.findOne({ userId: notification.userId });
|
||||||
|
await sendNotification(notification);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Schedule for later
|
||||||
|
|
||||||
|
await storeNotification(notification);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function storeNotification(notification) {
|
||||||
|
await mongoClient.connect();
|
||||||
|
const db = mongoClient.db('test');
|
||||||
|
await db.collection('scheduledNotifications').insertOne({
|
||||||
|
...notification,
|
||||||
|
sendTime: new Date(notification.sendTime),
|
||||||
|
createdAt:new Date(notification.createdAt)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkScheduledNotifications() {
|
||||||
|
const db = mongoClient.db('test');
|
||||||
|
const now = new Date();
|
||||||
|
const notifications = await db.collection('scheduledNotifications')
|
||||||
|
.find({ sendTime: { $lte: now } })
|
||||||
|
.toArray();
|
||||||
|
console.log(notifications)
|
||||||
|
for (const notification of notifications) {
|
||||||
|
const user = await User.findOne({ userId: notification.userId });
|
||||||
|
await sendNotification(notification,user);
|
||||||
|
await db.collection('scheduledNotifications').deleteOne({ _id: notification._id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendNotification(notification) {
|
||||||
|
|
||||||
|
console.log('Sending notification:', notification);
|
||||||
|
}
|
||||||
|
// async function sendNotification(notification, user) {
|
||||||
|
// for (const channel of user.preferences.channels) {
|
||||||
|
// try {
|
||||||
|
// switch (channel) {
|
||||||
|
// case 'email':
|
||||||
|
// await sendEmail(notification, user);
|
||||||
|
// break;
|
||||||
|
// case 'sms':
|
||||||
|
// await sendSMS(notification, user);
|
||||||
|
// break;
|
||||||
|
// case 'push':
|
||||||
|
// await sendPushNotification(notification, user);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// await Notification.updateOne({ _id: notification._id }, { status: 'sent' });
|
||||||
|
// return;
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error(`Failed to send notification via ${channel}:`, error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async function sendEmail(notification, user) {
|
||||||
|
// console.log(`Sending email to ${user.userId}: ${notification.message}`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async function sendSMS(notification, user) {
|
||||||
|
// console.log(`Sending SMS to ${user.userId}: ${notification.message}`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async function sendPushNotification(notification, user) {
|
||||||
|
// console.log(`Sending push notification to ${user.userId}: ${notification.message}`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // If all channels fail, mark as failed
|
||||||
|
// await Notification.updateOne({ _id: notification._id }, { status: 'failed' });
|
||||||
|
// }
|
||||||
|
// Run the processor
|
||||||
|
processNotifications().catch(console.error);
|
||||||
|
|
||||||
|
// Schedule periodic checks for pending notifications
|
||||||
|
schedule.scheduleJob('*/1 * * * *', checkScheduledNotifications);
|
||||||
|
|
||||||
|
module.exports = { processNotifications, checkScheduledNotifications };
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const { Kafka } = require('kafkajs');
|
||||||
|
const notificationIngestion = require('../services/notificationIngestion');
|
||||||
|
const notificationProcessing = require('../services/notificationProcessing');
|
||||||
|
const notificationDelivery = require('../services/notificationDelivery');
|
||||||
|
const analytics = require('../services/analytics');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
|
||||||
|
mongoose.connect('mongodb://localhost:27017', { useNewUrlParser: true, useUnifiedTopology: true });
|
||||||
|
|
||||||
|
const kafka = new Kafka({
|
||||||
|
clientId: 'client1',
|
||||||
|
brokers: ['localhost:9092']
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use('/api', notificationIngestion);
|
||||||
|
app.use('/api', analytics);
|
||||||
|
|
||||||
|
|
||||||
|
notificationProcessing.processNotifications().catch(console.error);
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
notificationDelivery.deliverNotifications().catch(console.error);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
const PORT = process.env.PORT || 3000;
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Server running on port ${PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
Reference in New Issue
Block a user