Global task settings implementation
Global task kill switch based on environement
Handle full disable or partial env diabled
Add logs
Fix typo + eslint
MODIFY
src/async-task/TenantAsyncTask.ts
src/async-task/TenantAsyncTask.ts
@@ -2,6 +2,7 @@ import AbstractAsyncTask from './AsyncTask';
import Constants from '../utils/Constants';
import Logging from '../utils/Logging';
import { ServerAction } from '../types/Server';
+import SettingStorage from '../storage/mongodb/SettingStorage';
import Tenant from '../types/Tenant';
import TenantStorage from '../storage/mongodb/TenantStorage';
import Utils from '../utils/Utils';
@@ -12,8 +13,25 @@ const MODULE_NAME = 'TenantAsyncTask';
export default abstract class TenantAsyncTask extends AbstractAsyncTask {
protected async executeAsyncTask(): Promise<void> {
- // Current task environement
- const currentTaskEnv = process.env.TASK_ENV || 'FARGATE_ALL_PRD'; // Environement is not set in Fargate
+ // Current task environment
+ const currentTaskEnv = process.env.TASK_ENV || 'FARGATE_ALL_PRD'; // Environment is not set in Fargate
+ // Get global task settings
+ let isTaskExecutionDisabled = false;
+ const taskSettings = await SettingStorage.getTaskSettings(Constants.DEFAULT_TENANT_OBJECT);
+ // Check if tasks are disabled for this environment
+ if (taskSettings && taskSettings.task &&
+ (taskSettings.task.disableAllTasks || !Utils.isEmptyArray(taskSettings.task.disableTasksInEnv) && taskSettings.task.disableTasksInEnv.includes(currentTaskEnv))) {
+ // Tasks are disabled for this environment
+ isTaskExecutionDisabled = true;
+ await Logging.logDebug({
+ tenantID: Constants.DEFAULT_TENANT_ID,
+ action: ServerAction.ASYNC_TASK,
+ module: MODULE_NAME, method: 'executeAsyncTask',
+ message: `Tasks on envirnoment: '${currentTaskEnv}' are disabled, '${this.getAsyncTask().name}~${this.getCorrelationID()}' will not run...`
+ });
+ }
+ // Execute tasks only when settings allows it
+ if (!isTaskExecutionDisabled) {
// Get the Tenants
const tenants = await TenantStorage.getTenants({}, Constants.DB_PARAMS_MAX_LIMIT);
// Process them
@@ -25,7 +43,13 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask {
}
// Check if tenant task needs to run on a specific env
if (tenant.taskExecutionEnv && tenant.taskExecutionEnv !== currentTaskEnv) {
- // Ignore execution on this environement
+ await Logging.logDebug({
+ tenantID: Constants.DEFAULT_TENANT_ID,
+ action: ServerAction.ASYNC_TASK,
+ module: MODULE_NAME, method: 'executeAsyncTask',
+ message: `The Task '${this.getAsyncTask().name}~${this.getCorrelationID()}' is skipped for Tenant ${Utils.buildTenantName(tenant)}...`
+ });
+ // Ignore execution on this environment
continue;
}
const tenantCorrelationID = Utils.generateShortNonUniqueID();
@@ -81,6 +105,7 @@ export default abstract class TenantAsyncTask extends AbstractAsyncTask {
});
}
}
+ }
protected async beforeExecuteTenantAsyncTask(tenant: Tenant): Promise<void> {
}

MODIFY
src/scheduler/TenantSchedulerTask.ts
src/scheduler/TenantSchedulerTask.ts
@@ -2,6 +2,7 @@ import Constants from '../utils/Constants';
import Logging from '../utils/Logging';
import SchedulerTask from './SchedulerTask';
import { ServerAction } from '../types/Server';
+import SettingStorage from '../storage/mongodb/SettingStorage';
import { TaskConfig } from '../types/TaskConfig';
import Tenant from '../types/Tenant';
import TenantStorage from '../storage/mongodb/TenantStorage';
@@ -12,8 +13,25 @@ const MODULE_NAME = 'TenantSchedulerTask';
export default abstract class TenantSchedulerTask extends SchedulerTask {
public async processTask(config: TaskConfig): Promise<void> {
- // Current task environement
- const currentTaskEnv = process.env.TASK_ENV || 'FARGATE_ALL_PRD'; // Environement is not set in Fargate
+ // Current task environment
+ const currentTaskEnv = process.env.TASK_ENV || 'FARGATE_ALL_PRD'; // Environment is not set in Fargate
+ // Get global task settings
+ let isTaskExecutionDisabled = false;
+ const taskSettings = await SettingStorage.getTaskSettings(Constants.DEFAULT_TENANT_OBJECT);
+ // Check if tasks are disabled for this environment
+ if (taskSettings && taskSettings.task &&
+ (taskSettings.task.disableAllTasks || !Utils.isEmptyArray(taskSettings.task.disableTasksInEnv) && taskSettings.task.disableTasksInEnv.includes(currentTaskEnv))) {
+ // Tasks are disabled for this environment
+ isTaskExecutionDisabled = true;
+ await Logging.logDebug({
+ tenantID: Constants.DEFAULT_TENANT_ID,
+ action: ServerAction.SCHEDULER,
+ module: MODULE_NAME, method: 'processTask',
+ message: `Tasks on envirnoment: '${currentTaskEnv}' are disabled, '${this.getName()}~${this.getCorrelationID()}' will not run...`
+ });
+ }
+ // Execute tasks only when settings allows it
+ if (!isTaskExecutionDisabled) {
// Get the Tenants
const tenants = await TenantStorage.getTenants({}, Constants.DB_PARAMS_MAX_LIMIT);
// Process them
@@ -23,9 +41,15 @@ export default abstract class TenantSchedulerTask extends SchedulerTask {
// Ignore this tenant
continue;
}
- // Check if tenant task needs to run on a specific environement
+ // Check if tenant task needs to run on a specific environment
if (tenant.taskExecutionEnv && tenant.taskExecutionEnv !== currentTaskEnv) {
- // Ignore execution on this environement
+ await Logging.logDebug({
+ tenantID: Constants.DEFAULT_TENANT_ID,
+ action: ServerAction.SCHEDULER,
+ module: MODULE_NAME, method: 'processTask',
+ message: `The Task '${this.getName()}~${this.getCorrelationID()}' is skipped for Tenant ${Utils.buildTenantName(tenant)}...`
+ });
+ // Ignore execution on this environment
continue;
}
const tenantCorrelationID = Utils.generateShortNonUniqueID();
@@ -81,6 +105,7 @@ export default abstract class TenantSchedulerTask extends SchedulerTask {
});
}
}
+ }
protected async beforeProcessTenant(tenant: Tenant, config: TaskConfig): Promise<void> {
}

MODIFY
src/storage/mongodb/SettingStorage.ts
src/storage/mongodb/SettingStorage.ts
-import { AnalyticsSettings, AnalyticsSettingsType, AssetSettings, AssetSettingsType, BillingSetting, BillingSettings, BillingSettingsType, CarConnectorSetting, CarConnectorSettings, CarConnectorSettingsType, CryptoSetting, CryptoSettings, CryptoSettingsType, PricingSettings, PricingSettingsType, RefundSettings, RefundSettingsType, RoamingSettings, SettingDB, SmartChargingSettings, SmartChargingSettingsType, TechnicalSettings, UserSettings, UserSettingsType } from '../../types/Setting';
+import { AnalyticsSettings, AnalyticsSettingsType, AssetSettings, AssetSettingsType, BillingSetting, BillingSettings, BillingSettingsType, CarConnectorSettings, CarConnectorSettingsType, CryptoSetting, CryptoSettings, CryptoSettingsType, PricingSettings, PricingSettingsType, RefundSettings, RefundSettingsType, RoamingSettings, SettingDB, SmartChargingSettings, SmartChargingSettingsType, TaskSettings, TaskSettingsType, TechnicalSettings, UserSettings, UserSettingsType } from '../../types/Setting';
import Tenant, { TenantComponents } from '../../types/Tenant';
import global, { DatabaseCount, FilterParams } from '../../types/GlobalType';
@@ -500,4 +500,20 @@ export default class SettingStorage {
}
return SettingStorage.saveSettings(tenant, setting);
}
+
+ public static async getTaskSettings(tenant: Tenant): Promise<TaskSettings> {
+ let taskSettings: TaskSettings;
+ // Get task settings
+ const settings = await SettingStorage.getSettings(tenant, { identifier: TechnicalSettings.TASK }, Constants.DB_PARAMS_SINGLE_RECORD);
+ if (settings.count > 0) {
+ taskSettings = {
+ id: settings.result[0].id,
+ identifier: TechnicalSettings.TASK,
+ type: TaskSettingsType.TASK,
+ task: settings.result[0].content.task,
+ };
+ }
+ return taskSettings;
+ }
+
}

MODIFY
src/types/Setting.ts
src/types/Setting.ts
@@ -5,6 +5,7 @@ import { TenantComponents } from './Tenant';
export enum TechnicalSettings {
CRYPTO = 'crypto',
USER = 'user',
+ TASK = 'task',
}
export enum IntegrationSettings {
@@ -55,7 +56,8 @@ export interface SettingDBContent {
| SmartChargingContentType
| CryptoSettingsType
| UserSettingsType
- | CarConnectorSettingsType;
+ | CarConnectorSettingsType
+ | TaskSettingsType;
ocpi?: OcpiSetting;
oicp?: OicpSetting;
// pricing?: PricingSetting; // TODO - reorg pricing similar to billing
@@ -70,6 +72,7 @@ export interface SettingDBContent {
carConnector?: CarConnectorSetting;
crypto?: CryptoSetting;
user?: UserSetting;
+ task?: TaskSetting;
}
export enum PricingSettingsType {
@@ -419,3 +422,18 @@ export interface UserSettings extends Setting {
export interface UserSetting {
autoActivateAccountAfterValidation: boolean;
}
+
+export enum TaskSettingsType {
+ TASK = 'task',
+}
+
+export interface TaskSettings extends Setting {
+ identifier: TechnicalSettings.TASK;
+ type: TaskSettingsType;
+ task?: TaskSetting;
+}
+
+export interface TaskSetting {
+ disableAllTasks?: boolean;
+ disableTasksInEnv?: string[];
+}

Global task settings implementation

- Global task kill switch based on environement
- Handle full disable or partial env diabled
- Add logs
- Fix typo + eslint