Changes after merge
MODIFY
package-lock.json
package-lock.json
"resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz",
"integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8="
},
+ "https": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz",
+ "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q="
+ },
"https-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",

MODIFY
src/assets/server/rest/v1/schemas/tenant/tenant-components.json
src/assets/server/rest/v1/schemas/tenant/tenant-components.json
}
}
},
+ "oicp": {
+ "type": "object",
+ "properties": {
+ "active": {
+ "type": "boolean",
+ "sanitize": "mongo" },
+ "type": {
+ "type": "string",
+ "sanitize": "mongo" }
+ }
+ },
"refund": {
"type": "object",
"properties": {

MODIFY
src/client/oicp/OICPClient.ts
src/client/oicp/OICPClient.ts
-import AxiosFactory from '../../utils/AxiosFactory';
import { AxiosInstance, AxiosRequestConfig } from 'axios';
+
+import AxiosFactory from '../../utils/AxiosFactory';
import BackendError from '../../exception/BackendError';
+import Logging from '../../utils/Logging';
import OICPEndpoint from '../../types/oicp/OICPEndpoint';
+import { OICPJobResult } from '../../types/oicp/OICPJobResult';
+import { OICPOperatorID } from '../../types/oicp/OICPEvse';
import { OICPRole } from '../../types/oicp/OICPRole';
import { OicpSetting } from '../../types/Setting';
import { ServerAction } from '../../types/Server';
import Tenant from '../../types/Tenant';
-import { OICPJobResult } from '../../types/oicp/OICPJobResult';
-import { OICPOperatorID } from '../../types/oicp/OICPEvse';
-import Logging from '../../utils/Logging';
import https from 'https';
const MODULE_NAME = 'OICPClient';
@@ -140,10 +141,10 @@ export default abstract class OICPClient {
return httpsAgent;
}
- async abstract triggerJobs(): Promise<{
+ abstract triggerJobs(): Promise<{
evses?: OICPJobResult,
evseStatuses?: OICPJobResult;
}>;
- async abstract ping();
+ abstract ping();
}

MODIFY
src/client/oicp/OICPClientFactory.ts
src/client/oicp/OICPClientFactory.ts
@@ -7,6 +7,7 @@ import OICPEndpoint from '../../types/oicp/OICPEndpoint';
import OICPEndpointStorage from '../../storage/mongodb/OICPEndpointStorage';
import { OICPRegistrationStatus } from '../../types/oicp/OICPRegistrationStatus';
import { OICPRole } from '../../types/oicp/OICPRole';
+import { ServerAction } from '../../types/Server';
import SettingStorage from '../../storage/mongodb/SettingStorage';
import Tenant from '../../types/Tenant';
import TenantComponents from '../../types/TenantComponents';
@@ -23,6 +24,7 @@ export default class OICPClientFactory {
if (!oicpSettings && oicpSettings.oicp) {
Logging.logError({
tenantID: tenant.id,
+ action: ServerAction.OICP_SETTINGS,
module: MODULE_NAME, method: 'getOicpClient',
message: 'OICP Settings are not configured'
});
@@ -43,6 +45,7 @@ export default class OICPClientFactory {
}
Logging.logError({
tenantID: tenant.id,
+ action: ServerAction.OICP_SETTINGS,
module: MODULE_NAME, method: 'getCpoOicpClient',
message: `CPO OICP Client is not compatible with endpoint role '${oicpEndpoint.role}'`
});

MODIFY
src/locking/LockingHelper.ts
src/locking/LockingHelper.ts
@@ -71,6 +71,14 @@ export default class LockingHelper {
return lock;
}
+ public static async createOICPPushCpoCdrLock(tenantID: string, transactionID: number): Promise<Lock|null> {
+ const lock = LockingManager.createExclusiveLock(tenantID, LockEntity.TRANSACTION, `push-cdr-${transactionID}`);
+ if (!(await LockingManager.acquire(lock))) {
+ return null;
+ }
+ return lock;
+ }
+
public static async createOCPIPullEmspTokensLock(tenantID: string, ocpiEndpoint: OCPIEndpoint): Promise<Lock|null> {
return LockingHelper.createOCPIEndpointActionLock(tenantID, ocpiEndpoint, 'pull-emsp-tokens');
}

MODIFY
src/server/oicp/oicp-services-impl/AbstractEndpoint.ts
src/server/oicp/oicp-services-impl/AbstractEndpoint.ts
@@ -34,6 +34,6 @@ export default abstract class AbstractEndpoint {
}
// Abstract - Process endpoint
- abstract async process(req: Request, res: Response, next: NextFunction, tenant: Tenant): Promise<OICPAcknowledgment>;
+ abstract process(req: Request, res: Response, next: NextFunction, tenant: Tenant): Promise<OICPAcknowledgment>;
}

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -16,6 +16,7 @@ import { DataResult } from '../../../../types/DataResult';
import { HttpEndUserReportErrorRequest } from '../../../../types/requests/HttpNotificationRequest';
import Logging from '../../../../utils/Logging';
import OCPIEndpoint from '../../../../types/ocpi/OCPIEndpoint';
+import OICPEndpoint from '../../../../types/oicp/OICPEndpoint';
import { ServerAction } from '../../../../types/Server';
import Site from '../../../../types/Site';
import SiteArea from '../../../../types/SiteArea';
@@ -143,6 +144,48 @@ export default class UtilsService {
}
}
+ public static checkIfOICPEndpointValid(oicpEndpoint: Partial<OICPEndpoint>, req: Request): void {
+ if (req.method !== 'POST' && !oicpEndpoint.id) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'The OICP Endpoint ID is mandatory',
+ module: MODULE_NAME,
+ method: 'checkIfOICPEndpointValid'
+ });
+ }
+ if (!oicpEndpoint.name) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'The OICP Endpoint name is mandatory',
+ module: MODULE_NAME,
+ method: 'checkIfOICPEndpointValid',
+ user: req.user.id
+ });
+ }
+ if (!oicpEndpoint.role) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'The OICP Endpoint role is mandatory',
+ module: MODULE_NAME,
+ method: 'checkIfOICPEndpointValid',
+ user: req.user.id
+ });
+ }
+ if (!oicpEndpoint.baseUrl) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'The OICP Endpoint base URL is mandatory',
+ module: MODULE_NAME,
+ method: 'checkIfOICPEndpointValid',
+ user: req.user.id
+ });
+ }
+ }
+
public static httpSortFieldsToMongoDB(httpSortFields: string): any {
// Exist?
if (httpSortFields) {

MODIFY
src/server/restOICP/v2.3.0/service/OICPEndpointService.ts
src/server/restOICP/v2.3.0/service/OICPEndpointService.ts
@@ -35,7 +35,7 @@ export default class OICPEndpointService {
// Filter
const filteredRequest = OICPEndpointSecurity.filterOicpEndpointCreateRequest(req.body);
// Check Mandatory fields
- Utils.checkIfOICPEndpointValid(filteredRequest, req);
+ UtilsService.checkIfOICPEndpointValid(filteredRequest, req);
const oicpEndpoint: OICPEndpoint = {
...filteredRequest,
createdBy: { id: req.user.id },
@@ -158,7 +158,7 @@ export default class OICPEndpointService {
// Filter
const filteredRequest = OICPEndpointSecurity.filterOicpEndpointPingRequest(req.body);
// Check Mandatory fields
- Utils.checkIfOICPEndpointValid(filteredRequest, req);
+ UtilsService.checkIfOICPEndpointValid(filteredRequest, req);
const tenant = await TenantStorage.getTenant(req.user.tenantID);
// Get oicpEndpoint
const oicpEndpoint = await OICPEndpointStorage.getOicpEndpoint(req.user.tenantID, filteredRequest.id);

MODIFY
src/storage/mongodb/OICPEndpointStorage.ts
src/storage/mongodb/OICPEndpointStorage.ts
@@ -27,7 +27,7 @@ export default class OICPEndpointStorage {
// Debug
const uniqueTimerID = Logging.traceStart(tenantID, MODULE_NAME, 'saveOicpEndpoint');
// Check Tenant
- await Utils.checkTenant(tenantID);
+ await DatabaseUtils.checkTenant(tenantID);
// Check if name is provided
if (!oicpEndpointToSave.name) {
// Name must be provided!
@@ -78,7 +78,7 @@ export default class OICPEndpointStorage {
// Debug
const uniqueTimerID = Logging.traceStart(tenantID, MODULE_NAME, 'getOicpEndpoints');
// Check Tenant
- await Utils.checkTenant(tenantID);
+ await DatabaseUtils.checkTenant(tenantID);
// Clone before updating the values
dbParams = Utils.cloneObject(dbParams);
// Check Limit
@@ -162,7 +162,7 @@ export default class OICPEndpointStorage {
// Debug
const uniqueTimerID = Logging.traceStart(tenantID, MODULE_NAME, 'deleteOicpEndpoint');
// Check Tenant
- await Utils.checkTenant(tenantID);
+ await DatabaseUtils.checkTenant(tenantID);
// Delete OicpEndpoint
await global.database.getCollection<any>(tenantID, 'oicpendpoints')
.findOneAndDelete({ '_id': Utils.convertToObjectID(id) });
@@ -174,7 +174,7 @@ export default class OICPEndpointStorage {
// Debug
const uniqueTimerID = Logging.traceStart(tenantID, MODULE_NAME, 'deleteOicpEndpoints');
// Check Tenant
- await Utils.checkTenant(tenantID);
+ await DatabaseUtils.checkTenant(tenantID);
// Delete OicpEndpoint
await global.database.getCollection<any>(tenantID, 'oicpendpoints').deleteMany({});
// Debug

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -150,6 +150,7 @@ export enum ServerAction {
OCPI_ENDPOINT_UNREGISTER = 'OcpiEndpointUnregister',
OCPI_ENDPOINT_DELETE = 'OcpiEndpointDelete',
+ OICP_SETTINGS = 'OicpSettings',
OICP_ENPOINT_CREATE = 'OicpEndpointCreate',
OICP_ENPOINT_PING = 'OicpEndpointPing',
OICP_ENPOINT_TRIGGER_JOBS = 'OicpEndpointTriggerJobs',

Changes after merge