Skip to content

Commit

Permalink
Correct various bug in card reminder (#5310)
Browse files Browse the repository at this point in the history
Signed-off-by: freddidierRTE <[email protected]>
  • Loading branch information
freddidierRTE authored and vlo-rte committed Nov 6, 2023
1 parent 7acf685 commit 13dc981
Show file tree
Hide file tree
Showing 17 changed files with 767 additions and 800 deletions.
9 changes: 5 additions & 4 deletions config/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ services:
# volumes:
# - "./rabbit-persistance:/var/lib/rabbitmq/mnesia/"


# Port closed for security reasons , be careful if you open it
# ports:
# - "5672:5672"
# !!! WARNING !!!
# Port is to be closed for security reasons , be careful if you open it
# Port open here for dev only
ports:
- "5672:5672"
# - "15672:15672"

# If you open the port, you must change default user and password as follow
Expand Down
72 changes: 32 additions & 40 deletions node-services/cards-reminder/src/cardsReminder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,29 @@ import RemindDatabaseService from './domain/server-side/remindDatabaseService';
import AuthorizationService from './common/client-side/authorizationService';

const app = express();
app.disable("x-powered-by");
app.disable('x-powered-by');

app.use(bodyParser.json());

app.use(express.static("public"));
const adminPort = config.get('operatorfabric.cardsReminder.adminPort');


const activeOnStartUp = config.get('operatorfabric.cardsReminder.activeOnStartup');

const authenticationService = new AuthenticationService()
.setLogger(logger);

const remindDatabaseService = new RemindDatabaseService()
.setMongoDbConfiguration(config.get("operatorfabric.mongodb"))
.setMongoDbConfiguration(config.get('operatorfabric.mongodb'))
.setRemindersCollection(ReminderService.REMINDERS_COLLECTION)
.setLogger(logger)
.setLogger(logger);


const reminderService = new ReminderService()
.setLogger(logger)
.setDatabaseService(remindDatabaseService);
const reminderService = new ReminderService().setLogger(logger).setDatabaseService(remindDatabaseService);

const rRuleRemindDatabaseService = new RemindDatabaseService()
.setMongoDbConfiguration(config.get("operatorfabric.mongodb"))
.setMongoDbConfiguration(config.get('operatorfabric.mongodb'))
.setRemindersCollection(RRuleReminderService.REMINDERS_COLLECTION)
.setLogger(logger)
.setLogger(logger);

const rruleReminderService = new RRuleReminderService()
.setLogger(logger)
Expand All @@ -62,7 +58,7 @@ const opfabServicesInterface = new CardsReminderOpfabServicesInterface()
.setOpfabGetTokenUrl(config.get('operatorfabric.servicesUrls.authToken'))
.setAuthenticationService(authenticationService)
.setLogger(logger)
.setEventBusConfiguration(config.get("operatorfabric.rabbitmq"))
.setEventBusConfiguration(config.get('operatorfabric.rabbitmq'))
.addListener(rruleReminderService)
.addListener(reminderService);

Expand All @@ -71,56 +67,52 @@ const authorizationService = new AuthorizationService()
.setOpfabServicesInterface(opfabServicesInterface)
.setLogger(logger);

const cardsReminderService = new CardsReminderService(opfabServicesInterface, rruleReminderService, reminderService, config.get('operatorfabric.cardsReminder.checkPeriodInSeconds'), logger);

const cardsReminderService = new CardsReminderService(
opfabServicesInterface,
rruleReminderService,
reminderService,
remindDatabaseService,
config.get('operatorfabric.cardsReminder.checkPeriodInSeconds'),
logger
);

app.get('/status', (req, res) => {

authorizationService.isAdminUser(req).then(isAdmin => {
if (!isAdmin)
res.status(403).send();
else
res.send(cardsReminderService.isActive());
})

authorizationService.isAdminUser(req).then((isAdmin) => {
if (!isAdmin) res.status(403).send();
else res.send(cardsReminderService.isActive());
});
});

app.get('/start', (req, res) => {

authorizationService.isAdminUser(req).then(isAdmin => {
if (!isAdmin)
res.status(403).send();
authorizationService.isAdminUser(req).then((isAdmin) => {
if (!isAdmin) res.status(403).send();
else {
cardsReminderService.start();
res.send('Start service');
}
})
});
});

app.get('/stop', (req, res) => {

authorizationService.isAdminUser(req).then(isAdmin => {
if (!isAdmin)
res.status(403).send();
authorizationService.isAdminUser(req).then((isAdmin) => {
if (!isAdmin) res.status(403).send();
else {
logger.info('Stop card reminder service asked');
cardsReminderService.stop();
res.send('Stop service');
}
})
});
});

app.get('/reset', (req, res) => {

authorizationService.isAdminUser(req).then(isAdmin => {
if (!isAdmin)
res.status(403).send();
authorizationService.isAdminUser(req).then((isAdmin) => {
if (!isAdmin) res.status(403).send();
else {
logger.info('Reset card reminder service asked');
cardsReminderService.reset();
res.send('Reset service');
}
})
});
});

app.listen(adminPort, () => {
Expand All @@ -132,9 +124,9 @@ opfabServicesInterface.startListener();
async function start() {
await remindDatabaseService.connectToMongoDB();
await rRuleRemindDatabaseService.connectToMongoDB();
if (activeOnStartUp) {
cardsReminderService.start();
}
logger.info('Application started');
if (activeOnStartUp) {
cardsReminderService.start();
}
logger.info('Application started');
}
start();
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import CardsReminderOpfabServicesInterface from '../server-side/cardsReminderOpf

import ReminderService from '../application/reminderService';
import {RRuleReminderService} from './rruleReminderService';
import {Card} from '../model/card.model';
import RemindDatabaseService from '../server-side/remindDatabaseService';

export default class CardsReminderControl {
private opfabServicesInterface: CardsReminderOpfabServicesInterface;
private reminderService: ReminderService;
private rruleReminderService: RRuleReminderService;
private remindDatabaseService: RemindDatabaseService;

logger: any;

Expand All @@ -39,7 +42,12 @@ export default class CardsReminderControl {
return this;
}

public async checkCardsReminder():Promise<boolean> {
public setRemindDatabaseService(remindDatabaseService: RemindDatabaseService): this {
this.remindDatabaseService = remindDatabaseService;
return this;
}

public async checkCardsReminder(): Promise<boolean> {
const cards = await this.reminderService.getCardsToRemindNow();
for (const card of cards) {
try {
Expand All @@ -62,20 +70,19 @@ export default class CardsReminderControl {
return Promise.resolve(true);
}

public resetReminderDatabase() {
this.reminderService.clearReminders();
this.rruleReminderService.clearReminders();
public async resetReminderDatabase(): Promise<boolean> {
await this.reminderService.clearReminders();
await this.rruleReminderService.clearReminders();

this.rruleReminderService
.getAllCardsToRemind()
.then((cardsWithReminders) =>
cardsWithReminders.forEach((card) => {
this.reminderService.addCardReminder(card);
this.rruleReminderService.addCardReminder(card);
})
)
.catch((error) => {
this.logger.error('resetReminderDatabase error ' + error);
});
try {
const cardsWithReminders:Card[] = await this.remindDatabaseService.getAllCardsWithReminder();
for(const card of cardsWithReminders) {
await this.reminderService.addCardReminder(card);
await this.rruleReminderService.addCardReminder(card);
}
} catch (error) {
this.logger.error('resetReminderDatabase error ' + error);
}
return Promise.resolve(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* This file is part of the OperatorFabric project.
*/


import {EventListener} from '../../common/server-side/eventListener';
import {getNextTimeForRepeating} from '../application/reminderUtils';
import {Card} from '../model/card.model';
Expand All @@ -16,33 +15,27 @@ import {CardOperation} from '../model/card-operation.model';
import RemindDatabaseService from '../server-side/remindDatabaseService';

export default class ReminderService implements EventListener {

public static REMINDERS_COLLECTION = "reminders";
public static REMINDERS_COLLECTION = 'reminders';
private static MAX_MILLISECONDS_FOR_REMINDING_AFTER_EVENT_STARTS = 60000 * 15; // 15 minutes

private databaseService: RemindDatabaseService;

logger: any;


public setLogger(logger: any) {
this.logger = logger;
return this;
}

async onMessage(message: any) {
try {
const cardOperation : CardOperation = JSON.parse(message.content);
// Hack to fix enumeration value parsing from json
const type = '' + cardOperation.type;

if (type === 'ADD' || type === 'UPDATE')
this.addCardReminder(cardOperation.card).catch(error => {
this.logger.error("Error on addCardReminder " + error)});
else if (type == 'DELETE')
this.databaseService.removeReminder(cardOperation.cardId);
} catch(error) {
this.logger.error("Error on card operation received " + error);
const cardOperation: CardOperation = JSON.parse(message.content);

if (cardOperation.type === 'ADD' || cardOperation.type === 'UPDATE')
await this.addCardReminder(cardOperation.card);
else if (cardOperation.type === 'DELETE') await this.databaseService.removeReminder(cardOperation.cardId);
} catch (error) {
this.logger.error('Error on card operation received ' + error);
}
}

Expand All @@ -51,84 +44,73 @@ export default class ReminderService implements EventListener {
return this;
}

public async addCardReminder(card: Card, startingDate?: number) {
public async addCardReminder(card: Card, startingDate?: number): Promise<void> {
if (card) {
const cardId = card.id? card.id : card._id;
const cardId = card.id ? card.id : card._id;
if (card.secondsBeforeTimeSpanForReminder === undefined || card.secondsBeforeTimeSpanForReminder === null)
return;
const reminderItem = await this.databaseService.getReminder(cardId);
if (reminderItem) {
if (reminderItem.cardUid === card.uid) {
return;
} else {
this.databaseService.removeReminder(cardId);
await this.databaseService.removeReminder(cardId);
}
}

const dateForReminder: number = getNextTimeForRepeating(card, startingDate);
if (dateForReminder >= 0) {

const reminder = new Reminder(
cardId,
card.uid,
dateForReminder - card.secondsBeforeTimeSpanForReminder * 1000,
false
)

cardId,
card.uid,
dateForReminder - card.secondsBeforeTimeSpanForReminder * 1000,
false
);

this.logger.info(
`Reminder Will remind card ${cardId} at
${new Date(dateForReminder - card.secondsBeforeTimeSpanForReminder * 1000)}`
);
this.databaseService.persistReminder(reminder);
await this.databaseService.persistReminder(reminder);
}
}
return Promise.resolve();
}

public async getCardsToRemindNow(): Promise<Card[]> {
const cardsToRemind = [];
const reminders = await this.databaseService.getItemsToRemindNow();
const reminders = await this.databaseService.getItemsToRemindNow();

for(const reminder of reminders) {
for (const reminder of reminders) {
const card = await this.databaseService.getCardByUid(reminder.cardUid);
if (card) {
cardsToRemind.push(card);
} else {
// the card has been deleted in this case
this.databaseService.removeReminder(reminder.cardId);
await this.databaseService.removeReminder(reminder.cardId);
}
}
return cardsToRemind;
}

public async setCardHasBeenRemind(card: Card) {
const reminderItem = await this.databaseService.getReminder(card._id);
if (reminderItem) {
if (!card.timeSpans[0].recurrence) {
reminderItem.hasBeenRemind = true;
this.databaseService.persistReminder(reminderItem);
}
else this.setNextRemindWhenRecurrenceAndRemindHasBeenDone(card, reminderItem);
}
if (reminderItem) await this.setNextRemindWhenRecurrenceAndRemindHasBeenDone(card, reminderItem);
}

private setNextRemindWhenRecurrenceAndRemindHasBeenDone(card: Card, reminderItem: any) {

private async setNextRemindWhenRecurrenceAndRemindHasBeenDone(card: Card, reminderItem: any) {
const reminderDate: number = reminderItem.timeForReminding;
this.databaseService.removeReminder(card._id);
await this.databaseService.removeReminder(card._id);
this.addCardReminder(
card,
reminderDate + card.secondsBeforeTimeSpanForReminder + ReminderService.MAX_MILLISECONDS_FOR_REMINDING_AFTER_EVENT_STARTS
reminderDate +
card.secondsBeforeTimeSpanForReminder * 1000 +
ReminderService.MAX_MILLISECONDS_FOR_REMINDING_AFTER_EVENT_STARTS +
1
);
}


public async getAllCardsToRemind(): Promise<Card[]> {
return this.databaseService.getAllCardsToRemind();
public async clearReminders() {
await this.databaseService.clearReminders();
}

public clearReminders() {
this.databaseService.clearReminders();
}

}
}
Loading

0 comments on commit 13dc981

Please sign in to comment.