OCPI Optimizations
MODIFY
src/client/ocpi/CpoOCPIClient.ts
src/client/ocpi/CpoOCPIClient.ts
@@ -28,6 +28,8 @@ import Tenant from '../../types/Tenant';
import TenantStorage from '../../storage/mongodb/TenantStorage';
import Transaction from '../../types/Transaction';
import TransactionStorage from '../../storage/mongodb/TransactionStorage';
+import User from '../../types/User';
+import UserStorage from '../../storage/mongodb/UserStorage';
import Utils from '../../utils/Utils';
import _ from 'lodash';
import moment from 'moment';
@@ -53,6 +55,8 @@ export default class CpoOCPIClient extends OCPIClient {
total: 0,
logs: []
};
+ // EMSP Users
+ const emspUsers = new Map<string, User>();
// Perfs trace
const startTime = new Date().getTime();
// Get tokens endpoint url
@@ -94,7 +98,18 @@ export default class CpoOCPIClient extends OCPIClient {
});
for (const token of response.data.data as OCPIToken[]) {
try {
- await OCPITokensService.updateToken(this.tenant.id, this.ocpiEndpoint, token);
+ // Build user email
+ const email = OCPIUtils.buildEmspEmailFromOCPIToken(token, this.ocpiEndpoint.countryCode, this.ocpiEndpoint.partyId);
+ // Check cache
+ let emspUser = emspUsers.get(email);
+ if (!emspUser) {
+ // Get User from DB
+ emspUser = await UserStorage.getUserByEmail(this.tenant.id, email);
+ if (emspUser) {
+ emspUsers.set(email, emspUser);
+ }
+ }
+ await OCPITokensService.updateToken(this.tenant.id, this.ocpiEndpoint, token, emspUser);
result.success++;
} catch (error) {
result.failure++;

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
@@ -121,7 +121,7 @@ export default class CPOTokensEndpoint extends AbstractEndpoint {
});
}
}
- await OCPITokensService.updateToken(tenant.id, ocpiEndpoint, updatedToken);
+ await OCPITokensService.updateToken(tenant.id, ocpiEndpoint, updatedToken, 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): Promise<void> {
+ public static async updateToken(tenantId: string, ocpiEndpoint: OCPIEndpoint, token: OCPIToken, emspUser: User): Promise<void> {
if (!OCPITokensService.validateToken(token)) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
@@ -26,62 +26,65 @@ export default class OCPITokensService {
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
- // Build user email
- const email = OCPIUtils.buildEmspEmailFromOCPIToken(token, ocpiEndpoint.countryCode, ocpiEndpoint.partyId);
- // Get User
- let user = await UserStorage.getUserByEmail(tenantId, email);
- if (user) {
+ if (emspUser) {
// Existing User: Check local organization
- if (user.issuer) {
+ if (emspUser.issuer) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
module: MODULE_NAME, method: 'updateToken',
errorCode: StatusCodes.CONFLICT,
message: 'Token already assigned to an internal user',
- actionOnUser: user,
+ actionOnUser: emspUser,
detailedMessages: { token },
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
// Check the tag
- await this.checkExistingTag(tenantId, token);
- await UserStorage.saveTag(tenantId, {
+ const tag = await this.checkExistingTag(tenantId, token);
+ const tagToSave = {
id: token.uid,
issuer: false,
- userID: user.id,
+ userID: emspUser.id,
active: token.valid === true ? true : false,
description: token.visual_number,
lastChangedOn: token.last_updated,
ocpiToken: token
- });
+ };
+ // Save Tag
+ if (!tag || JSON.stringify(tagToSave.ocpiToken) !== JSON.stringify(tag.ocpiToken)) {
+ await UserStorage.saveTag(tenantId, tagToSave);
+ }
} else {
// Unknown User
// Check the Tag
- await this.checkExistingTag(tenantId, token);
+ const tag = await this.checkExistingTag(tenantId, token);
// Create User
- user = {
+ emspUser = {
issuer: false,
createdOn: token.last_updated,
lastChangedOn: token.last_updated,
name: token.issuer,
firstName: OCPIUtils.buildOperatorName(ocpiEndpoint.countryCode, ocpiEndpoint.partyId),
- email: email,
+ email: OCPIUtils.buildEmspEmailFromOCPIToken(token, ocpiEndpoint.countryCode, ocpiEndpoint.partyId),
locale: Utils.getLocaleFromLanguage(token.language),
} as User;
// Save User
- user.id = await UserStorage.saveUser(tenantId, user);
- await UserStorage.saveUserRole(tenantId, user.id, UserRole.BASIC);
- await UserStorage.saveUserStatus(tenantId, user.id, UserStatus.ACTIVE);
- // Save Tag
- await UserStorage.saveTag(tenantId, {
+ emspUser.id = await UserStorage.saveUser(tenantId, emspUser);
+ await UserStorage.saveUserRole(tenantId, emspUser.id, UserRole.BASIC);
+ await UserStorage.saveUserStatus(tenantId, emspUser.id, UserStatus.ACTIVE);
+ const tagToSave = {
id: token.uid,
issuer: false,
- userID: user.id,
+ userID: emspUser.id,
active: token.valid === true ? true : false,
description: token.visual_number,
lastChangedOn: token.last_updated,
ocpiToken: token
- });
+ };
+ // Save Tag
+ if (!tag || JSON.stringify(tagToSave.ocpiToken) !== JSON.stringify(tag.ocpiToken)) {
+ await UserStorage.saveTag(tenantId, tagToSave);
+ }
}
}
@@ -97,7 +100,7 @@ export default class OCPITokensService {
return true;
}
- private static async checkExistingTag(tenantId: string, token: OCPIToken): Promise<void> {
+ 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({
@@ -109,5 +112,6 @@ export default class OCPITokensService {
ocpiError: OCPIStatusCode.CODE_2001_INVALID_PARAMETER_ERROR
});
}
+ return tag;
}
}

OCPI Optimizations