Optimized pull of tokens with 100 tags -> one DB call
MODIFY
src/client/ocpi/CpoOCPIClient.ts
src/client/ocpi/CpoOCPIClient.ts
@@ -98,9 +98,15 @@ export default class CpoOCPIClient extends OCPIClient {
message: `${numberOfTags.toString()} Tokens retrieved from ${tokensUrl}`,
module: MODULE_NAME, method: 'pullTokens'
});
+ // Get all Tags at once from the DB
+ const tagIDs: string[] = [];
+ for (const token of response.data.data as OCPIToken[]) {
+ tagIDs.push(token.uid);
+ }
+ const tags = (await UserStorage.getTags(this.tenant.id, { tagIDs: tagIDs }, Constants.DB_PARAMS_MAX_LIMIT)).result;
for (const token of response.data.data as OCPIToken[]) {
try {
- // Build user email
+ // Get eMSP user
const email = OCPIUtils.buildEmspEmailFromOCPIToken(token, this.ocpiEndpoint.countryCode, this.ocpiEndpoint.partyId);
// Check cache
let emspUser = emspUsers.get(email);
@@ -111,7 +117,9 @@ export default class CpoOCPIClient extends OCPIClient {
emspUsers.set(email, emspUser);
}
}
- await OCPITokensService.updateToken(this.tenant.id, this.ocpiEndpoint, token, emspUser);
+ // Get the Tag
+ const emspTag = tags.find((tag) => tag.id === token.uid);
+ await OCPITokensService.updateToken(this.tenant.id, this.ocpiEndpoint, token, emspTag, emspUser);
result.success++;
} catch (error) {
result.failure++;

MODIFY
src/scheduler/SchedulerManager.ts
src/scheduler/SchedulerManager.ts
@@ -24,6 +24,7 @@ import SynchronizeBillingInvoicesTask from './tasks/SynchronizeBillingInvoicesTa
import SynchronizeBillingUsersTask from './tasks/SynchronizeBillingUsersTask';
import SynchronizeCarsTask from './tasks/SynchronizeCarsTask';
import SynchronizeRefundTransactionsTask from './tasks/SynchronizeRefundTransactionsTask';
+import Utils from '../utils/Utils';
import cron from 'node-cron';
const MODULE_NAME = 'SchedulerManager';
@@ -31,7 +32,7 @@ const MODULE_NAME = 'SchedulerManager';
export default class SchedulerManager {
private static schedulerConfig = Configuration.getSchedulerConfig();
- static init() {
+ public static init() {
// Active?
if (SchedulerManager.schedulerConfig.active) {
// Log
@@ -130,7 +131,15 @@ export default class SchedulerManager {
});
}
if (schedulerTask) {
+ // Handle number of instances
+ let numberOfInstance = 1;
+ if (Utils.objectHasProperty(task, 'numberOfInstance')) {
+ numberOfInstance = task.numberOfInstance;
+ }
+ // Register
+ for (let i = 0; i < numberOfInstance; i++) {
cron.schedule(task.periodicity, async (): Promise<void> => await schedulerTask.run(task.name, task.config));
+ }
Logging.logInfo({
tenantID: Constants.DEFAULT_TENANT,
action: ServerAction.SCHEDULER,

MODIFY
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/CPOTokensEndpoint.ts
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/CPOTokensEndpoint.ts
@@ -120,7 +120,7 @@ export default class CPOTokensEndpoint extends AbstractEndpoint {
});
}
}
- await OCPITokensService.updateToken(tenant.id, ocpiEndpoint, updatedToken, tag.user);
+ await OCPITokensService.updateToken(tenant.id, ocpiEndpoint, updatedToken, tag, tag.user);
return OCPIUtils.success();
}

MODIFY
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPITokensService.ts
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPITokensService.ts
@@ -15,7 +15,7 @@ const MODULE_NAME = 'OCPITokensService';
export default class OCPITokensService {
- public static async updateToken(tenantId: string, ocpiEndpoint: OCPIEndpoint, token: OCPIToken, emspUser: User): Promise<void> {
+ public static async updateToken(tenantId: string, ocpiEndpoint: OCPIEndpoint, token: OCPIToken, tag: Tag, emspUser: User): Promise<void> {
if (!OCPITokensService.validateToken(token)) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
@@ -40,7 +40,16 @@ export default class OCPITokensService {
});
}
// Check the tag
- const tag = await this.checkExistingTag(tenantId, token);
+ if (tag && tag.issuer) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ module: MODULE_NAME, method: 'checkExistingTag',
+ errorCode: StatusCodes.CONFLICT,
+ message: 'Token already exists in the current organization',
+ detailedMessages: token,
+ ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
+ });
+ }
const tagToSave = {
id: token.uid,
issuer: false,
@@ -57,7 +66,16 @@ export default class OCPITokensService {
} else {
// Unknown User
// Check the Tag
- const tag = await this.checkExistingTag(tenantId, token);
+ if (tag && tag.issuer) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ module: MODULE_NAME, method: 'checkExistingTag',
+ errorCode: StatusCodes.CONFLICT,
+ message: 'Token already exists in the current organization',
+ detailedMessages: token,
+ ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
+ });
+ }
// Create User
emspUser = {
issuer: false,
@@ -99,19 +117,4 @@ export default class OCPITokensService {
}
return true;
}
-
- private static async checkExistingTag(tenantId: string, token: OCPIToken): Promise<Tag> {
- const tag = await UserStorage.getTag(tenantId, token.uid);
- if (tag && tag.issuer) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- module: MODULE_NAME, method: 'checkExistingTag',
- errorCode: StatusCodes.CONFLICT,
- message: 'Token already exists in the current organization',
- detailedMessages: token,
- ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
- });
- }
- return tag;
- }
}

MODIFY
src/types/configuration/SchedulerConfiguration.ts
src/types/configuration/SchedulerConfiguration.ts
@@ -7,5 +7,6 @@ interface SchedulerTask {
name: string;
active: boolean;
periodicity: string;
+ numberOfInstance?: number;
config: any;
}

Optimized pull of tokens with 100 tags -> one DB call