UNPKG

@citrineos/data

Version:

The OCPP data module which includes all persistence layer implementation.

192 lines 10.3 kB
import { CrudRepository, OCPP2_0_1 } from '@citrineos/base'; import { Sequelize } from 'sequelize-typescript'; import { Logger } from 'tslog'; import { AuthorizationMapper } from '../mapper/2.0.1/index.js'; import { Authorization, LocalListAuthorization, LocalListVersion, LocalListVersionAuthorization, SendLocalList, SendLocalListAuthorization, } from '../model/index.js'; import { SequelizeAuthorizationRepository } from './Authorization.js'; import { SequelizeRepository } from './Base.js'; export class SequelizeLocalAuthListRepository extends SequelizeRepository { authorization; localListAuthorization; sendLocalList; constructor(config, logger, sequelizeInstance, authorization, localListAuthorization, sendLocalList) { super(config, Authorization.MODEL_NAME, logger, sequelizeInstance); this.authorization = authorization ? authorization : new SequelizeAuthorizationRepository(config, logger); this.localListAuthorization = localListAuthorization ? localListAuthorization : new SequelizeRepository(config, LocalListAuthorization.MODEL_NAME, logger, sequelizeInstance); this.sendLocalList = sendLocalList ? sendLocalList : new SequelizeRepository(config, SendLocalList.MODEL_NAME, logger, sequelizeInstance); } async createSendLocalListFromRequestData(tenantId, stationId, correlationId, updateType, versionNumber, localAuthorizationList) { const sendLocalList = await this.sendLocalList.create(tenantId, SendLocalList.build({ tenantId, stationId, correlationId, versionNumber, updateType, })); for (const authData of localAuthorizationList ?? []) { const auth = await Authorization.findOne({ where: { idToken: authData.idToken.idToken, idTokenType: AuthorizationMapper.fromIdTokenEnumType(authData.idToken.type), }, }); if (!auth) { throw new Error(`Authorization not found for ${JSON.stringify(authData)}, invalid SendLocalListRequest (create necessary Authorizations first)`); } // If groupAuthorizationId is present, compare its id to groupAuthorizationId if (authData.idTokenInfo?.groupIdToken) { const groupAuth = await Authorization.findOne({ where: { idToken: authData.idTokenInfo.groupIdToken.idToken, idTokenType: AuthorizationMapper.fromIdTokenEnumType(authData.idTokenInfo.groupIdToken.type), }, }); const groupAuthorizationAuthId = groupAuth?.id; if (!auth.groupAuthorizationId || groupAuthorizationAuthId !== auth.groupAuthorizationId) { throw new Error(`Authorization groupIdToken in SendLocalListRequest ${JSON.stringify(authData.idTokenInfo.groupIdToken)} does not match groupAuthorizationId in database ${JSON.stringify(auth.groupAuthorizationId)} (update the groupAuthorization first)`); } if (!auth.groupAuthorizationId || groupAuthorizationAuthId !== auth.groupAuthorizationId) { throw new Error(`Authorization groupIdToken in SendLocalListRequest ${JSON.stringify(authData.idTokenInfo.groupIdToken)} does not match groupAuthorizationId in database ${JSON.stringify(auth.groupAuthorizationId)} (update the groupAuthorization first)`); } } // No longer create IdTokenInfo, just use Authorization fields const { id, ...authorizationFields } = auth; const localListAuthorization = await this.localListAuthorization.create(tenantId, LocalListAuthorization.build({ ...authorizationFields, authorizationId: id, })); await SendLocalListAuthorization.create({ tenantId, sendLocalListId: sendLocalList.id, authorizationId: localListAuthorization.id, }); } await sendLocalList.reload({ include: [LocalListAuthorization] }); this.sendLocalList.emit('created', [sendLocalList]); return sendLocalList; } async validateOrReplaceLocalListVersionForStation(tenantId, versionNumber, stationId) { await this.s.transaction(async (transaction) => { const localListVersion = await LocalListVersion.findOne({ where: { stationId }, transaction, }); if (localListVersion && localListVersion.versionNumber === versionNumber) { return; } if (localListVersion && localListVersion.versionNumber !== versionNumber) { // Remove associations await LocalListVersionAuthorization.destroy({ where: { localListVersionId: localListVersion.id }, transaction, }); } if (!localListVersion) { const newLocalListVersion = await LocalListVersion.create({ tenantId, stationId, versionNumber }, { transaction }); this.emit('created', [newLocalListVersion]); } else { await localListVersion.update({ versionNumber }, { transaction }); this.emit('updated', [localListVersion]); } }); } async getSendLocalListRequestByStationIdAndCorrelationId(tenantId, stationId, correlationId) { return this.sendLocalList.readOnlyOneByQuery(tenantId, { where: { stationId, correlationId } }); } async createOrUpdateLocalListVersionFromStationIdAndSendLocalList(tenantId, stationId, sendLocalList) { switch (sendLocalList.updateType) { case OCPP2_0_1.UpdateEnumType.Full: return this.replaceLocalListVersionFromStationIdAndSendLocalList(tenantId, stationId, sendLocalList); case OCPP2_0_1.UpdateEnumType.Differential: return this.updateLocalListVersionFromStationIdAndSendLocalListRequest(tenantId, stationId, sendLocalList); } } async replaceLocalListVersionFromStationIdAndSendLocalList(tenantId, stationId, sendLocalList) { const localListVersion = await this.s.transaction(async (transaction) => { const oldLocalListVersion = await LocalListVersion.findOne({ where: { stationId }, include: [LocalListAuthorization], transaction, }); if (oldLocalListVersion) { // Remove associations await LocalListVersionAuthorization.destroy({ where: { localListVersionId: oldLocalListVersion.id }, transaction, }); // Destroy old version await LocalListVersion.destroy({ where: { stationId }, transaction }); } const localListVersion = await LocalListVersion.create({ tenantId, stationId, versionNumber: sendLocalList.versionNumber, }, { transaction }); if (!sendLocalList.localAuthorizationList) { return localListVersion; } for (const auth of sendLocalList.localAuthorizationList) { await LocalListVersionAuthorization.create({ tenantId, localListVersionId: localListVersion.id, authorizationId: auth.id, }, { transaction }); } return localListVersion.reload({ include: [LocalListAuthorization], transaction }); }); this.emit('created', [localListVersion]); return localListVersion; } async updateLocalListVersionFromStationIdAndSendLocalListRequest(tenantId, stationId, sendLocalList) { const localListVersion = await this.s.transaction(async (transaction) => { if (!sendLocalList.localAuthorizationList) { // See D01.FR.05 const localListVersion = await this._updateAllByQuery(tenantId, { versionNumber: sendLocalList.versionNumber }, { where: { stationId }, transaction }); if (localListVersion.length !== 1) { throw new Error(`LocalListVersion not found for ${stationId} during differential version update: ${JSON.stringify(localListVersion)}`); } else { return localListVersion[0]; } } const localListVersion = await LocalListVersion.findOne({ where: { stationId }, include: [LocalListAuthorization], transaction, }); if (!localListVersion) { throw new Error(`LocalListVersion not found for ${stationId} during differential update`); } for (const sendAuth of sendLocalList.localAuthorizationList) { // If there is already an association with the same authorizationId, remove it const oldAuth = localListVersion.localAuthorizationList?.find((localAuth) => localAuth.authorizationId === sendAuth.authorizationId); if (oldAuth) { await LocalListVersionAuthorization.destroy({ where: { localListVersionId: localListVersion.id, authorizationId: oldAuth.authorizationId, }, transaction, }); } await LocalListVersionAuthorization.create({ tenantId, localListVersionId: localListVersion.id, authorizationId: sendAuth.id, }, { transaction }); } await localListVersion.update({ versionNumber: sendLocalList.versionNumber }, { transaction }); return localListVersion.reload({ include: [LocalListAuthorization], transaction }); }); this.emit('updated', [localListVersion]); return localListVersion; } } //# sourceMappingURL=LocalAuthList.js.map