Skip to content

Commit

Permalink
[bug] Add notification rules; For bug 70325
Browse files Browse the repository at this point in the history
  • Loading branch information
konovalovsergey committed Oct 4, 2024
1 parent 511ecc1 commit f6322a5
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 32 deletions.
29 changes: 26 additions & 3 deletions Common/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,25 @@
],
"template": {
"title": "License expiration warning",
"bodyWarn": "Attention! Your license is about to expire on %s.\nUpon reaching this date, you will no longer be entitled to receive personal technical support and install new Docs versions released after this date.",
"bodyError": "Attention! Your license expired on %s.\nYou are no longer entitled to receive personal technical support and install new Docs versions released after this date.\nPlease contact [email protected] to discuss license renewal."
"body": "Attention! Your license is about to expire on %s.\nUpon reaching this date, you will no longer be entitled to receive personal technical support and install new Docs versions released after this date."
},
"policies": {
"repeatInterval": "1d"
}
},
"licenseLimit": {
"licenseExpirationError": {
"transportType": [
"email"
],
"template": {
"title": "License expiration warning",
"body": "Attention! Your license expired on %s.\nYou are no longer entitled to receive personal technical support and install new Docs versions released after this date.\nPlease contact [email protected] to discuss license renewal."
},
"policies": {
"repeatInterval": "1d"
}
},
"licenseLimitEdit": {
"transportType": [
"email"
],
Expand All @@ -61,6 +72,18 @@
"policies": {
"repeatInterval": "1h"
}
},
"licenseLimitLiveViewer": {
"transportType": [
"email"
],
"template": {
"title": "License connection limit warning",
"body": "Attention! You have reached %s%% of the live viewer %s limit set by your license."
},
"policies": {
"repeatInterval": "1h"
}
}
}
},
Expand Down
12 changes: 7 additions & 5 deletions Common/sources/notificationService.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ const editorStatStorage = require('./../../DocService/sources/' + (cfgEditorStat
const editorStat = editorStatStorage.EditorStat ? new editorStatStorage.EditorStat() : new editorStatStorage();
const notificationTypes = {
LICENSE_EXPIRATION_WARNING: 'licenseExpirationWarning',
LICENSE_LIMIT: 'licenseLimit'
LICENSE_EXPIRATION_ERROR: 'licenseExpirationError',
LICENSE_LIMIT_EDIT: 'licenseLimitEdit',
LICENSE_LIMIT_LIVE_VIEWER: 'licenseLimitLiveViewer'
};

class TransportInterface {
Expand Down Expand Up @@ -105,7 +107,7 @@ class Transport {
}
}

async function notify(ctx, notificationType, message) {
async function notify(ctx, notificationType, message, opt_cacheKey = undefined) {
const tenNotificationEnable = ctx.getCfg('notification.enable', cfgNotificationEnable);
if (!tenNotificationEnable) {
return;
Expand All @@ -114,21 +116,21 @@ async function notify(ctx, notificationType, message) {

const tenRule = ctx.getCfg(`notification.rules.${notificationType}`, config.get(`notification.rules.${notificationType}`));
if (tenRule) {
let checkRes = await checkRulePolicies(ctx, notificationType, tenRule);
let checkRes = await checkRulePolicies(ctx, notificationType, tenRule, opt_cacheKey);
if (checkRes) {
await notifyRule(ctx, tenRule, message);
}
}
}

async function checkRulePolicies(ctx, notificationType, tenRule) {
async function checkRulePolicies(ctx, notificationType, tenRule, opt_cacheKey) {
const { repeatInterval } = tenRule.policies;
//decrease repeatInterval by 1% to avoid race condition if timeout=repeatInterval
let ttl = Math.floor(ms(repeatInterval) * 0.99 / 1000);
let isLock = false;
//todo for compatibility remove if after 8.2
if (editorStat?.lockNotification) {
isLock = await editorStat.lockNotification(ctx, notificationType, ttl);
isLock = await editorStat.lockNotification(ctx, opt_cacheKey || notificationType, ttl);
}
if (!isLock) {
ctx.logger.debug(`Notification service: skip rule "%s" due to repeat interval = %s`, notificationType, repeatInterval);
Expand Down
34 changes: 19 additions & 15 deletions DocService/sources/DocsCoServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ const cfgForgottenFiles = config.get('services.CoAuthoring.server.forgottenfiles
const cfgForgottenFilesName = config.get('services.CoAuthoring.server.forgottenfilesname');
const cfgMaxRequestChanges = config.get('services.CoAuthoring.server.maxRequestChanges');
const cfgWarningLimitPercents = config.get('license.warning_limit_percents');
const cfgNotificationRuleLicenseLimit = config.get('notification.rules.licenseLimit.template.body');
const cfgNotificationRuleLicenseLimitEdit = config.get('notification.rules.licenseLimitEdit.template.body');
const cfgNotificationRuleLicenseLimitLiveViewer = config.get('notification.rules.licenseLimitLiveViewer.template.body');
const cfgErrorFiles = config.get('FileConverter.converter.errorfiles');
const cfgOpenProtectedFile = config.get('services.CoAuthoring.server.openProtectedFile');
const cfgIsAnonymousSupport = config.get('services.CoAuthoring.server.isAnonymousSupport');
Expand Down Expand Up @@ -3478,41 +3479,47 @@ exports.install = function(server, callbackFunction) {

function* _checkLicenseAuth(ctx, licenseInfo, userId, isLiveViewer) {
const tenWarningLimitPercents = ctx.getCfg('license.warning_limit_percents', cfgWarningLimitPercents) / 100;
const tenNotificationRuleLicenseLimit = ctx.getCfg(`notification.rules.licenseLimit.template.body`, cfgNotificationRuleLicenseLimit);
const tenNotificationRuleLicenseLimitEdit = ctx.getCfg(`notification.rules.licenseLimitEdit.template.body`, cfgNotificationRuleLicenseLimitEdit);
const tenNotificationRuleLicenseLimitLiveViewer = ctx.getCfg(`notification.rules.licenseLimitLiveViewer.template.body`, cfgNotificationRuleLicenseLimitLiveViewer);
const c_LR = constants.LICENSE_RESULT;
let licenseType = licenseInfo.type;
if (c_LR.Success === licenseType || c_LR.SuccessLimit === licenseType) {
let notificationLimit;
let notificationPercent = 0;
let notificationTemplate = tenNotificationRuleLicenseLimitEdit;
let notificationType = notificationTypes.LICENSE_LIMIT_EDIT;
let notificationPercent = 100;
if (licenseInfo.usersCount) {
const nowUTC = getLicenseNowUtc();
notificationLimit = 'users';
if(isLiveViewer) {
notificationTemplate = tenNotificationRuleLicenseLimitLiveViewer;
notificationType = notificationTypes.LICENSE_LIMIT_LIVE_VIEWER;
const arrUsers = yield editorStat.getPresenceUniqueViewUser(ctx, nowUTC);
if (arrUsers.length >= licenseInfo.usersViewCount && (-1 === arrUsers.findIndex((element) => {return element.userid === userId}))) {
licenseType = licenseInfo.hasLicense ? c_LR.UsersViewCount : c_LR.UsersViewCountOS;
} else if (licenseInfo.usersViewCount * tenWarningLimitPercents <= arrUsers.length) {
notificationPercent = tenWarningLimitPercents * 100;
}
notificationLimit = 'live viewer users';
} else {
const arrUsers = yield editorStat.getPresenceUniqueUser(ctx, nowUTC);
if (arrUsers.length >= licenseInfo.usersCount && (-1 === arrUsers.findIndex((element) => {return element.userid === userId}))) {
licenseType = licenseInfo.hasLicense ? c_LR.UsersCount : c_LR.UsersCountOS;
} else if(licenseInfo.usersCount * tenWarningLimitPercents <= arrUsers.length) {
notificationPercent = tenWarningLimitPercents * 100;
}
notificationLimit = 'users';
}
} else {
notificationLimit = 'connections';
if (isLiveViewer) {
notificationTemplate = tenNotificationRuleLicenseLimitLiveViewer;
notificationType = notificationTypes.LICENSE_LIMIT_LIVE_VIEWER;
const connectionsLiveCount = licenseInfo.connectionsView;
const liveViewerConnectionsCount = yield editorStat.getLiveViewerConnectionsCount(ctx, connections);
if (liveViewerConnectionsCount >= connectionsLiveCount) {
licenseType = licenseInfo.hasLicense ? c_LR.ConnectionsLive : c_LR.ConnectionsLiveOS;
} else if(connectionsLiveCount * tenWarningLimitPercents <= liveViewerConnectionsCount){
notificationPercent = tenWarningLimitPercents * 100;
}
notificationLimit = 'live viewer connections';
} else {
const connectionsCount = licenseInfo.connections;
const editConnectionsCount = yield editorStat.getEditorConnectionsCount(ctx, connections);
Expand All @@ -3521,20 +3528,17 @@ exports.install = function(server, callbackFunction) {
} else if (connectionsCount * tenWarningLimitPercents <= editConnectionsCount) {
notificationPercent = tenWarningLimitPercents * 100;
}
notificationLimit = 'connections';
}
}
if ((c_LR.Success !== licenseType && c_LR.SuccessLimit !== licenseType) || notificationPercent > 0) {
let message;
if (notificationPercent > 0) {
message = util.format(tenNotificationRuleLicenseLimit, notificationPercent, notificationLimit);
ctx.logger.warn(tenNotificationRuleLicenseLimit, notificationPercent, notificationLimit);
if ((c_LR.Success !== licenseType && c_LR.SuccessLimit !== licenseType) || 100 !== notificationPercent) {
const message = util.format(notificationTemplate, notificationPercent, notificationLimit);
if (100 !== notificationPercent) {
ctx.logger.warn(message);
} else {
message = util.format(tenNotificationRuleLicenseLimit, 100, notificationLimit);
ctx.logger.error(tenNotificationRuleLicenseLimit, 100, notificationLimit);
ctx.logger.error(message);
}
//todo with yield service could throw error
void notificationService.notify(ctx, notificationTypes.LICENSE_LIMIT, message);
void notificationService.notify(ctx, notificationType, message, notificationType + notificationPercent);
}
}
return licenseType;
Expand Down
20 changes: 11 additions & 9 deletions DocService/sources/utilsDocService.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const tenantManager = require('../../Common/sources/tenantManager');
const { notificationTypes, ...notificationService } = require('../../Common/sources/notificationService');

const cfgStartNotifyFrom = ms(config.get('license.warning_license_expiration'));
const cfgNotificationRuleLicenseExpirationWarning = config.get('notification.rules.licenseExpirationWarning.template.bodyWarn');
const cfgNotificationRuleLicenseExpirationError = config.get('notification.rules.licenseExpirationWarning.template.bodyError');
const cfgNotificationRuleLicenseExpirationWarning = config.get('notification.rules.licenseExpirationWarning.template.body');
const cfgNotificationRuleLicenseExpirationError = config.get('notification.rules.licenseExpirationError.template.body');

async function fixImageExifRotation(ctx, buffer) {
if (!buffer) {
Expand Down Expand Up @@ -126,15 +126,17 @@ async function notifyLicenseExpiration(ctx, endDate) {
const currentDate = new Date();
if (currentDate.getTime() >= endDate.getTime() - cfgStartNotifyFrom) {
const formattedExpirationTime = humanFriendlyExpirationTime(endDate);
//todo one body template
let message;
if (endDate < currentDate) {
message = util.format(cfgNotificationRuleLicenseExpirationError, formattedExpirationTime);
if (endDate <= currentDate) {
const tenNotificationRuleLicenseExpirationError = ctx.getCfg('notification.rules.licenseExpirationError.template.body', cfgNotificationRuleLicenseExpirationError);
const message = util.format(tenNotificationRuleLicenseExpirationError, formattedExpirationTime);
ctx.logger.error(message);
await notificationService.notify(ctx, notificationTypes.LICENSE_EXPIRATION_ERROR, message);
} else {
message = util.format(cfgNotificationRuleLicenseExpirationWarning, formattedExpirationTime);
const tenNotificationRuleLicenseExpirationWarning = ctx.getCfg('notification.rules.licenseExpirationWarning.template.body', cfgNotificationRuleLicenseExpirationWarning);
const message = util.format(tenNotificationRuleLicenseExpirationWarning, formattedExpirationTime);
ctx.logger.warn(message);
await notificationService.notify(ctx, notificationTypes.LICENSE_EXPIRATION_WARNING, message);
}
ctx.logger.warn(message);
await notificationService.notify(ctx, notificationTypes.LICENSE_EXPIRATION_WARNING, message);
}
}

Expand Down

0 comments on commit f6322a5

Please sign in to comment.