diff --git a/ocpp-1-5-core/src/main/kotlin/com/izivia/ocpp/core15/model/common/enumeration/Actions.kt b/ocpp-1-5-core/src/main/kotlin/com/izivia/ocpp/core15/model/common/enumeration/Actions.kt index 312f15c5..3ef346ab 100644 --- a/ocpp-1-5-core/src/main/kotlin/com/izivia/ocpp/core15/model/common/enumeration/Actions.kt +++ b/ocpp-1-5-core/src/main/kotlin/com/izivia/ocpp/core15/model/common/enumeration/Actions.kt @@ -1,73 +1,182 @@ package com.izivia.ocpp.core15.model.common.enumeration import com.izivia.ocpp.core15.model.authorize.AuthorizeReq +import com.izivia.ocpp.core15.model.authorize.AuthorizeResp import com.izivia.ocpp.core15.model.bootnotification.BootNotificationReq +import com.izivia.ocpp.core15.model.bootnotification.BootNotificationResp import com.izivia.ocpp.core15.model.cancelreservation.CancelReservationReq +import com.izivia.ocpp.core15.model.cancelreservation.CancelReservationResp import com.izivia.ocpp.core15.model.changeavailability.ChangeAvailabilityReq +import com.izivia.ocpp.core15.model.changeavailability.ChangeAvailabilityResp import com.izivia.ocpp.core15.model.changeconfiguration.ChangeConfigurationReq +import com.izivia.ocpp.core15.model.changeconfiguration.ChangeConfigurationResp import com.izivia.ocpp.core15.model.clearcache.ClearCacheReq +import com.izivia.ocpp.core15.model.clearcache.ClearCacheResp import com.izivia.ocpp.core15.model.datatransfer.DataTransferReq +import com.izivia.ocpp.core15.model.datatransfer.DataTransferResp import com.izivia.ocpp.core15.model.diagnosticsstatusnotification.DiagnosticsStatusNotificationReq +import com.izivia.ocpp.core15.model.diagnosticsstatusnotification.DiagnosticsStatusNotificationResp import com.izivia.ocpp.core15.model.firmwarestatusnotification.FirmwareStatusNotificationReq +import com.izivia.ocpp.core15.model.firmwarestatusnotification.FirmwareStatusNotificationResp import com.izivia.ocpp.core15.model.getconfiguration.GetConfigurationReq +import com.izivia.ocpp.core15.model.getconfiguration.GetConfigurationResp import com.izivia.ocpp.core15.model.getdiagnostics.GetDiagnosticsReq +import com.izivia.ocpp.core15.model.getdiagnostics.GetDiagnosticsResp import com.izivia.ocpp.core15.model.getlocallistversion.GetLocalListVersionReq +import com.izivia.ocpp.core15.model.getlocallistversion.GetLocalListVersionResp import com.izivia.ocpp.core15.model.heartbeat.HeartbeatReq +import com.izivia.ocpp.core15.model.heartbeat.HeartbeatResp import com.izivia.ocpp.core15.model.metervalues.MeterValuesReq +import com.izivia.ocpp.core15.model.metervalues.MeterValuesResp import com.izivia.ocpp.core15.model.remotestart.RemoteStartTransactionReq +import com.izivia.ocpp.core15.model.remotestart.RemoteStartTransactionResp import com.izivia.ocpp.core15.model.remotestop.RemoteStopTransactionReq +import com.izivia.ocpp.core15.model.remotestop.RemoteStopTransactionResp import com.izivia.ocpp.core15.model.reservenow.ReserveNowReq +import com.izivia.ocpp.core15.model.reservenow.ReserveNowResp import com.izivia.ocpp.core15.model.reset.ResetReq +import com.izivia.ocpp.core15.model.reset.ResetResp import com.izivia.ocpp.core15.model.sendlocallist.SendLocalListReq +import com.izivia.ocpp.core15.model.sendlocallist.SendLocalListResp import com.izivia.ocpp.core15.model.starttransaction.StartTransactionReq +import com.izivia.ocpp.core15.model.starttransaction.StartTransactionResp import com.izivia.ocpp.core15.model.statusnotification.StatusNotificationReq +import com.izivia.ocpp.core15.model.statusnotification.StatusNotificationResp import com.izivia.ocpp.core15.model.stoptransaction.StopTransactionReq +import com.izivia.ocpp.core15.model.stoptransaction.StopTransactionResp import com.izivia.ocpp.core15.model.unlockconnector.UnlockConnectorReq +import com.izivia.ocpp.core15.model.unlockconnector.UnlockConnectorResp import com.izivia.ocpp.core15.model.updatefirmware.UpdateFirmwareReq +import com.izivia.ocpp.core15.model.updatefirmware.UpdateFirmwareResp import com.izivia.ocpp.utils.IActions import com.izivia.ocpp.utils.OcppInitiator enum class Actions( - override val value: String, override val classRequest: Class<*>, + override val value: String, + override val classRequest: Class<*>, + override val classResponse: Class<*>, override val initiatedBy: OcppInitiator ) : IActions { - AUTHORIZE("authorize", AuthorizeReq::class.java, OcppInitiator.CHARGING_STATION), - BOOTNOTIFICATION("bootNotification", BootNotificationReq::class.java, OcppInitiator.CHARGING_STATION), - CANCELRESERVATION("cancelReservation", CancelReservationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CHANGEAVAILABILITY("changeAvailability", ChangeAvailabilityReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CHANGECONFIGURATION("changeConfiguration", ChangeConfigurationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CLEARCACHE("clearCache", ClearCacheReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - DATATRANSFER("dataTransfer", DataTransferReq::class.java, OcppInitiator.ALL), + AUTHORIZE("authorize", AuthorizeReq::class.java, AuthorizeResp::class.java, OcppInitiator.CHARGING_STATION), + BOOTNOTIFICATION( + "bootNotification", + BootNotificationReq::class.java, + BootNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + CANCELRESERVATION( + "cancelReservation", + CancelReservationReq::class.java, + CancelReservationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CHANGEAVAILABILITY( + "changeAvailability", + ChangeAvailabilityReq::class.java, + ChangeAvailabilityResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CHANGECONFIGURATION( + "changeConfiguration", + ChangeConfigurationReq::class.java, + ChangeConfigurationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CLEARCACHE("clearCache", ClearCacheReq::class.java, ClearCacheResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + DATATRANSFER("dataTransfer", DataTransferReq::class.java, DataTransferResp::class.java, OcppInitiator.ALL), DIAGNOSTICSSTATUSNOTIFICATION( "diagnosticsStatusNotification", DiagnosticsStatusNotificationReq::class.java, + DiagnosticsStatusNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), FIRMWARESTATUSNOTIFICATION( "firmwareStatusNotification", FirmwareStatusNotificationReq::class.java, + FirmwareStatusNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + GETCONFIGURATION( + "getConfiguration", + GetConfigurationReq::class.java, + GetConfigurationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETDIAGNOSTICS( + "getDiagnostics", + GetDiagnosticsReq::class.java, + GetDiagnosticsResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETLOCALLISTVERSION( + "getLocalListVersion", + GetLocalListVersionReq::class.java, + GetLocalListVersionResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + HEARTBEAT( + "heartbeat", + HeartbeatReq::class.java, + HeartbeatResp::class.java, + OcppInitiator.CHARGING_STATION + ), + METERVALUES( + "meterValues", + MeterValuesReq::class.java, + MeterValuesResp::class.java, OcppInitiator.CHARGING_STATION ), - GETCONFIGURATION("getConfiguration", GetConfigurationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETDIAGNOSTICS("getDiagnostics", GetDiagnosticsReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETLOCALLISTVERSION("getLocalListVersion", GetLocalListVersionReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - HEARTBEAT("heartbeat", HeartbeatReq::class.java, OcppInitiator.CHARGING_STATION), - METERVALUES("meterValues", MeterValuesReq::class.java, OcppInitiator.CHARGING_STATION), REMOTESTARTTRANSACTION( "remoteStartTransaction", RemoteStartTransactionReq::class.java, + RemoteStartTransactionResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + REMOTESTOPTRANSACTION( + "remoteStopTransaction", + RemoteStopTransactionReq::class.java, + RemoteStopTransactionResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + RESERVENOW("reserveNow", ReserveNowReq::class.java, ReserveNowResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + RESET("reset", ResetReq::class.java, ResetResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + SENDLOCALLIST( + "sendLocalList", + SendLocalListReq::class.java, + SendLocalListResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + STARTTRANSACTION( + "startTransaction", + StartTransactionReq::class.java, + StartTransactionResp::class.java, + OcppInitiator.CHARGING_STATION + ), + STATUSNOTIFICATION( + "statusNotification", + StatusNotificationReq::class.java, + StatusNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + STOPTRANSACTION( + "stopTransaction", + StopTransactionReq::class.java, + StopTransactionResp::class.java, + OcppInitiator.CHARGING_STATION + ), + UNLOCKCONNECTOR( + "unlockConnector", + UnlockConnectorReq::class.java, + UnlockConnectorResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - REMOTESTOPTRANSACTION("remoteStopTransaction", RemoteStopTransactionReq::class.java, - OcppInitiator.CENTRAL_SYSTEM), - RESERVENOW("reserveNow", ReserveNowReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - RESET("reset", ResetReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SENDLOCALLIST("sendLocalList", SendLocalListReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - STARTTRANSACTION("startTransaction", StartTransactionReq::class.java, OcppInitiator.CHARGING_STATION), - STATUSNOTIFICATION("statusNotification", StatusNotificationReq::class.java, OcppInitiator.CHARGING_STATION), - STOPTRANSACTION("stopTransaction", StopTransactionReq::class.java, OcppInitiator.CHARGING_STATION), - UNLOCKCONNECTOR("unlockConnector", UnlockConnectorReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - UPDATEFIRMWARE("updateFirmware", UpdateFirmwareReq::class.java, OcppInitiator.CENTRAL_SYSTEM); + UPDATEFIRMWARE( + "updateFirmware", + UpdateFirmwareReq::class.java, + UpdateFirmwareResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ); + fun lowercase() = value.lowercase() diff --git a/ocpp-1-5-json/src/main/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParser.kt b/ocpp-1-5-json/src/main/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParser.kt index 4d229500..6a4c73a1 100644 --- a/ocpp-1-5-json/src/main/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParser.kt +++ b/ocpp-1-5-json/src/main/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParser.kt @@ -34,6 +34,13 @@ class Ocpp15JsonParser( throw errorHandler(e) } + override fun getResponsePayloadClass(action: String, errorHandler: (e: Exception) -> Throwable): Class = + try { + Actions.valueOf(action.uppercase()).classResponse + } catch (e: Exception) { + throw errorHandler(e) + } + override fun getActionFromClass(className: String): String = Actions.valueOf(getActionFromClassName(className)).value diff --git a/ocpp-1-5-json/src/test/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParserErrorTest.kt b/ocpp-1-5-json/src/test/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParserErrorTest.kt index fdcb1cec..55b6e5c8 100644 --- a/ocpp-1-5-json/src/test/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParserErrorTest.kt +++ b/ocpp-1-5-json/src/test/kotlin/com/izivia/ocpp/json15/Ocpp15JsonParserErrorTest.kt @@ -310,6 +310,36 @@ class Ocpp15JsonParserErrorTest { // expectThat(percent).isGreaterThan(0.0) } + @Test + fun `should parse to Fault missing usedClazz`() { + val response = """[3,"messageId",{}]""" + + val res = parser.parseAnyFromString(response) + expectThat(res) + .and { + get { action }.isEqualTo("Fault") + get { errorCode }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED) + get { payload }.isA() + .and { + get { errorCode }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED.errorCode) + get { errorDescription }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED.description) + get { errorDetails }.hasSize(2) + .and { + get { get(0) } + .and { + get { code }.isEqualTo(ErrorDetailCode.ACTION.value) + get { detail }.contains("Cannot parse message, class used to retrieve the response action is not defined") + } + get { get(1) } + .and { + get { code }.isEqualTo(ErrorDetailCode.PAYLOAD.value) + get { detail }.isEqualTo(response) + } + } + } + } + } + @OptIn(ExperimentalTime::class) fun timeit(requestList: List, parser: Ocpp15JsonParser): Duration { return measureTime { diff --git a/ocpp-1-6-core/src/main/kotlin/com/izivia/ocpp/core16/model/common/enumeration/Actions.kt b/ocpp-1-6-core/src/main/kotlin/com/izivia/ocpp/core16/model/common/enumeration/Actions.kt index b8ab353c..cbb58a31 100644 --- a/ocpp-1-6-core/src/main/kotlin/com/izivia/ocpp/core16/model/common/enumeration/Actions.kt +++ b/ocpp-1-6-core/src/main/kotlin/com/izivia/ocpp/core16/model/common/enumeration/Actions.kt @@ -1,131 +1,292 @@ package com.izivia.ocpp.core16.model.common.enumeration import com.izivia.ocpp.core16.model.authorize.AuthorizeReq +import com.izivia.ocpp.core16.model.authorize.AuthorizeResp import com.izivia.ocpp.core16.model.bootnotification.BootNotificationReq +import com.izivia.ocpp.core16.model.bootnotification.BootNotificationResp import com.izivia.ocpp.core16.model.cancelreservation.CancelReservationReq +import com.izivia.ocpp.core16.model.cancelreservation.CancelReservationResp import com.izivia.ocpp.core16.model.certificatesigned.CertificateSignedReq +import com.izivia.ocpp.core16.model.certificatesigned.CertificateSignedResp +import com.izivia.ocpp.core16.model.certificatesigned.DeleteCertificateResp import com.izivia.ocpp.core16.model.changeavailability.ChangeAvailabilityReq +import com.izivia.ocpp.core16.model.changeavailability.ChangeAvailabilityResp import com.izivia.ocpp.core16.model.changeconfiguration.ChangeConfigurationReq +import com.izivia.ocpp.core16.model.changeconfiguration.ChangeConfigurationResp import com.izivia.ocpp.core16.model.clearcache.ClearCacheReq +import com.izivia.ocpp.core16.model.clearcache.ClearCacheResp import com.izivia.ocpp.core16.model.clearchargingprofile.ClearChargingProfileReq +import com.izivia.ocpp.core16.model.clearchargingprofile.ClearChargingProfileResp import com.izivia.ocpp.core16.model.datatransfer.DataTransferReq +import com.izivia.ocpp.core16.model.datatransfer.DataTransferResp import com.izivia.ocpp.core16.model.deletecertificate.DeleteCertificateReq import com.izivia.ocpp.core16.model.diagnosticsstatusnotification.DiagnosticsStatusNotificationReq +import com.izivia.ocpp.core16.model.diagnosticsstatusnotification.DiagnosticsStatusNotificationResp import com.izivia.ocpp.core16.model.firmwarestatusnotification.FirmwareStatusNotificationReq +import com.izivia.ocpp.core16.model.firmwarestatusnotification.FirmwareStatusNotificationResp import com.izivia.ocpp.core16.model.firmwarestatusnotification.SignedFirmwareStatusNotificationReq +import com.izivia.ocpp.core16.model.firmwarestatusnotification.SignedFirmwareStatusNotificationResp import com.izivia.ocpp.core16.model.getcompositeschedule.GetCompositeScheduleReq +import com.izivia.ocpp.core16.model.getcompositeschedule.GetCompositeScheduleResp import com.izivia.ocpp.core16.model.getconfiguration.GetConfigurationReq +import com.izivia.ocpp.core16.model.getconfiguration.GetConfigurationResp import com.izivia.ocpp.core16.model.getdiagnostics.GetDiagnosticsReq +import com.izivia.ocpp.core16.model.getdiagnostics.GetDiagnosticsResp import com.izivia.ocpp.core16.model.getinstalledcertificateids.GetInstalledCertificateIdsReq +import com.izivia.ocpp.core16.model.getinstalledcertificateids.GetInstalledCertificateIdsResp import com.izivia.ocpp.core16.model.getlocallistversion.GetLocalListVersionReq +import com.izivia.ocpp.core16.model.getlocallistversion.GetLocalListVersionResp import com.izivia.ocpp.core16.model.getlog.GetLogReq +import com.izivia.ocpp.core16.model.getlog.GetLogResp import com.izivia.ocpp.core16.model.heartbeat.HeartbeatReq +import com.izivia.ocpp.core16.model.heartbeat.HeartbeatResp import com.izivia.ocpp.core16.model.installcertificate.InstallCertificateReq +import com.izivia.ocpp.core16.model.installcertificate.InstallCertificateResp import com.izivia.ocpp.core16.model.logstatusnotification.LogStatusNotificationReq +import com.izivia.ocpp.core16.model.logstatusnotification.LogStatusNotificationResp import com.izivia.ocpp.core16.model.metervalues.MeterValuesReq +import com.izivia.ocpp.core16.model.metervalues.MeterValuesResp import com.izivia.ocpp.core16.model.remotestart.RemoteStartTransactionReq +import com.izivia.ocpp.core16.model.remotestart.RemoteStartTransactionResp import com.izivia.ocpp.core16.model.remotestop.RemoteStopTransactionReq +import com.izivia.ocpp.core16.model.remotestop.RemoteStopTransactionResp import com.izivia.ocpp.core16.model.reservenow.ReserveNowReq +import com.izivia.ocpp.core16.model.reservenow.ReserveNowResp import com.izivia.ocpp.core16.model.reset.ResetReq +import com.izivia.ocpp.core16.model.reset.ResetResp import com.izivia.ocpp.core16.model.securityeventnotification.SecurityEventNotificationReq +import com.izivia.ocpp.core16.model.securityeventnotification.SecurityEventNotificationResp import com.izivia.ocpp.core16.model.sendlocallist.SendLocalListReq +import com.izivia.ocpp.core16.model.sendlocallist.SendLocalListResp import com.izivia.ocpp.core16.model.setchargingprofile.SetChargingProfileReq +import com.izivia.ocpp.core16.model.setchargingprofile.SetChargingProfileResp import com.izivia.ocpp.core16.model.signcertificate.SignCertificateReq +import com.izivia.ocpp.core16.model.signcertificate.SignCertificateResp import com.izivia.ocpp.core16.model.starttransaction.StartTransactionReq +import com.izivia.ocpp.core16.model.starttransaction.StartTransactionResp import com.izivia.ocpp.core16.model.statusnotification.StatusNotificationReq +import com.izivia.ocpp.core16.model.statusnotification.StatusNotificationResp import com.izivia.ocpp.core16.model.stoptransaction.StopTransactionReq +import com.izivia.ocpp.core16.model.stoptransaction.StopTransactionResp import com.izivia.ocpp.core16.model.triggermessage.ExtendedTriggerMessageReq +import com.izivia.ocpp.core16.model.triggermessage.ExtendedTriggerMessageResp import com.izivia.ocpp.core16.model.triggermessage.TriggerMessageReq +import com.izivia.ocpp.core16.model.triggermessage.TriggerMessageResp import com.izivia.ocpp.core16.model.unlockconnector.UnlockConnectorReq +import com.izivia.ocpp.core16.model.unlockconnector.UnlockConnectorResp import com.izivia.ocpp.core16.model.updatefirmware.SignedUpdateFirmwareReq +import com.izivia.ocpp.core16.model.updatefirmware.SignedUpdateFirmwareResp import com.izivia.ocpp.core16.model.updatefirmware.UpdateFirmwareReq +import com.izivia.ocpp.core16.model.updatefirmware.UpdateFirmwareResp import com.izivia.ocpp.utils.IActions import com.izivia.ocpp.utils.OcppInitiator enum class Actions( - override val value: String, override val classRequest: Class<*>, + override val value: String, + override val classRequest: Class<*>, + override val classResponse: Class<*>, override val initiatedBy: OcppInitiator ) : IActions { - AUTHORIZE("authorize", AuthorizeReq::class.java, OcppInitiator.CHARGING_STATION), - BOOTNOTIFICATION("bootNotification", BootNotificationReq::class.java, OcppInitiator.CHARGING_STATION), - CANCELRESERVATION("cancelReservation", CancelReservationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CHANGEAVAILABILITY("changeAvailability", ChangeAvailabilityReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CHANGECONFIGURATION("changeConfiguration", ChangeConfigurationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CLEARCACHE("clearCache", ClearCacheReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + AUTHORIZE("authorize", AuthorizeReq::class.java, AuthorizeResp::class.java, OcppInitiator.CHARGING_STATION), + BOOTNOTIFICATION( + "bootNotification", + BootNotificationReq::class.java, + BootNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + CANCELRESERVATION( + "cancelReservation", + CancelReservationReq::class.java, + CancelReservationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CHANGEAVAILABILITY( + "changeAvailability", + ChangeAvailabilityReq::class.java, + ChangeAvailabilityResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CHANGECONFIGURATION( + "changeConfiguration", + ChangeConfigurationReq::class.java, + ChangeConfigurationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CLEARCACHE("clearCache", ClearCacheReq::class.java, ClearCacheResp::class.java, OcppInitiator.CENTRAL_SYSTEM), CLEARCHARGINGPROFILE( - "clearChargingProfile", ClearChargingProfileReq::class.java, + "clearChargingProfile", + ClearChargingProfileReq::class.java, + ClearChargingProfileResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - DATATRANSFER("dataTransfer", DataTransferReq::class.java, OcppInitiator.ALL), + DATATRANSFER("dataTransfer", DataTransferReq::class.java, DataTransferResp::class.java, OcppInitiator.ALL), DIAGNOSTICSSTATUSNOTIFICATION( "diagnosticsStatusNotification", DiagnosticsStatusNotificationReq::class.java, + DiagnosticsStatusNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), FIRMWARESTATUSNOTIFICATION( "firmwareStatusNotification", FirmwareStatusNotificationReq::class.java, + FirmwareStatusNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), GETCOMPOSITESCHEDULE( - "getCompositeSchedule", GetCompositeScheduleReq::class.java, + "getCompositeSchedule", + GetCompositeScheduleReq::class.java, + GetCompositeScheduleResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETCONFIGURATION( + "getConfiguration", + GetConfigurationReq::class.java, + GetConfigurationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETDIAGNOSTICS( + "getDiagnostics", + GetDiagnosticsReq::class.java, + GetDiagnosticsResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - GETCONFIGURATION("getConfiguration", GetConfigurationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETDIAGNOSTICS("getDiagnostics", GetDiagnosticsReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETLOCALLISTVERSION("getLocalListVersion", GetLocalListVersionReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - HEARTBEAT("heartbeat", HeartbeatReq::class.java, OcppInitiator.CHARGING_STATION), - METERVALUES("meterValues", MeterValuesReq::class.java, OcppInitiator.CHARGING_STATION), + GETLOCALLISTVERSION( + "getLocalListVersion", + GetLocalListVersionReq::class.java, + GetLocalListVersionResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + HEARTBEAT("heartbeat", HeartbeatReq::class.java, HeartbeatResp::class.java, OcppInitiator.CHARGING_STATION), + METERVALUES( + "meterValues", + MeterValuesReq::class.java, + MeterValuesResp::class.java, + OcppInitiator.CHARGING_STATION + ), REMOTESTARTTRANSACTION( "remoteStartTransaction", RemoteStartTransactionReq::class.java, + RemoteStartTransactionResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), REMOTESTOPTRANSACTION( - "remoteStopTransaction", RemoteStopTransactionReq::class.java, - OcppInitiator.CENTRAL_SYSTEM - ), - RESERVENOW("reserveNow", ReserveNowReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - RESET("reset", ResetReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SENDLOCALLIST("sendLocalList", SendLocalListReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SETCHARGINGPROFILE("setChargingProfile", SetChargingProfileReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - STARTTRANSACTION("startTransaction", StartTransactionReq::class.java, OcppInitiator.CHARGING_STATION), - STATUSNOTIFICATION("statusNotification", StatusNotificationReq::class.java, OcppInitiator.CHARGING_STATION), - STOPTRANSACTION("stopTransaction", StopTransactionReq::class.java, OcppInitiator.CHARGING_STATION), - TRIGGERMESSAGE("triggerMessage", TriggerMessageReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - UNLOCKCONNECTOR("unlockConnector", UnlockConnectorReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - UPDATEFIRMWARE("updateFirmware", UpdateFirmwareReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - - CERTIFICATESIGNED("certificateSigned", CertificateSignedReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - DELETECERTIFICATE("deleteCertificate", DeleteCertificateReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + "remoteStopTransaction", + RemoteStopTransactionReq::class.java, + RemoteStopTransactionResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + RESERVENOW("reserveNow", ReserveNowReq::class.java, ReserveNowResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + RESET("reset", ResetReq::class.java, ResetResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + SENDLOCALLIST( + "sendLocalList", + SendLocalListReq::class.java, + SendLocalListResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SETCHARGINGPROFILE( + "setChargingProfile", + SetChargingProfileReq::class.java, + SetChargingProfileResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + STARTTRANSACTION( + "startTransaction", + StartTransactionReq::class.java, + StartTransactionResp::class.java, + OcppInitiator.CHARGING_STATION + ), + STATUSNOTIFICATION( + "statusNotification", + StatusNotificationReq::class.java, + StatusNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + STOPTRANSACTION( + "stopTransaction", + StopTransactionReq::class.java, + StopTransactionResp::class.java, + OcppInitiator.CHARGING_STATION + ), + TRIGGERMESSAGE( + "triggerMessage", + TriggerMessageReq::class.java, + TriggerMessageResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + UNLOCKCONNECTOR( + "unlockConnector", + UnlockConnectorReq::class.java, + UnlockConnectorResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + UPDATEFIRMWARE( + "updateFirmware", + UpdateFirmwareReq::class.java, + UpdateFirmwareResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CERTIFICATESIGNED( + "certificateSigned", + CertificateSignedReq::class.java, + CertificateSignedResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + DELETECERTIFICATE( + "deleteCertificate", + DeleteCertificateReq::class.java, + DeleteCertificateResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), EXTENDEDTRIGGERMESSAGE( "extendedTriggerMessage", ExtendedTriggerMessageReq::class.java, + ExtendedTriggerMessageResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), GETINSTALLEDCERTIFICATEIDS( "getInstalledCertificateIds", GetInstalledCertificateIdsReq::class.java, + GetInstalledCertificateIdsResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETLOG("getLog", GetLogReq::class.java, GetLogResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + INSTALLCERTIFICATE( + "installCertificate", + InstallCertificateReq::class.java, + InstallCertificateResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - GETLOG("getLog", GetLogReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - INSTALLCERTIFICATE("installCertificate", InstallCertificateReq::class.java, OcppInitiator.CENTRAL_SYSTEM), LOGSTATUSNOTIFICATION( "logStatusNotification", LogStatusNotificationReq::class.java, + LogStatusNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), SECURITYEVENTNOTIFICATION( "securityEventNotification", SecurityEventNotificationReq::class.java, + SecurityEventNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + SIGNCERTIFICATE( + "signCertificate", + SignCertificateReq::class.java, + SignCertificateResp::class.java, OcppInitiator.CHARGING_STATION ), - SIGNCERTIFICATE("signCertificate", SignCertificateReq::class.java, OcppInitiator.CHARGING_STATION), SIGNEDFIRMWARESTATUSNOTIFICATION( "signedFirmwareStatusNotification", - SignedFirmwareStatusNotificationReq::class.java, OcppInitiator.CHARGING_STATION + SignedFirmwareStatusNotificationReq::class.java, + SignedFirmwareStatusNotificationResp::class.java, + OcppInitiator.CHARGING_STATION ), - SIGNEDUPDATEFIRMWARE("signedUpdateFirmware", SignedUpdateFirmwareReq::class.java, OcppInitiator.CENTRAL_SYSTEM); + SIGNEDUPDATEFIRMWARE( + "signedUpdateFirmware", + SignedUpdateFirmwareReq::class.java, + SignedUpdateFirmwareResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ); + fun lowercase() = value.lowercase() diff --git a/ocpp-1-6-json/src/main/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParser.kt b/ocpp-1-6-json/src/main/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParser.kt index 2f77dd77..8361b4c2 100644 --- a/ocpp-1-6-json/src/main/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParser.kt +++ b/ocpp-1-6-json/src/main/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParser.kt @@ -34,6 +34,13 @@ class Ocpp16JsonParser( throw errorHandler(e) } + override fun getResponsePayloadClass(action: String, errorHandler: (e: Exception) -> Throwable): Class = + try { + Actions.valueOf(action.uppercase()).classResponse + } catch (e: Exception) { + throw errorHandler(e) + } + override fun getActionFromClass(className: String): String = Actions.valueOf(getActionFromClassName(className)).value diff --git a/ocpp-1-6-json/src/test/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParserErrorTest.kt b/ocpp-1-6-json/src/test/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParserErrorTest.kt index 57207dd1..81a29e20 100644 --- a/ocpp-1-6-json/src/test/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParserErrorTest.kt +++ b/ocpp-1-6-json/src/test/kotlin/com/izivia/ocpp/json16/Ocpp16JsonParserErrorTest.kt @@ -462,6 +462,36 @@ class Ocpp16JsonParserErrorTest { // expectThat(percent).isGreaterThan(0.0) } + @Test + fun `should parse to Fault missing usedClazz`() { + val response = """[3,"messageId",{}]""" + + val res = parser.parseAnyFromString(response) + expectThat(res) + .and { + get { action }.isEqualTo("Fault") + get { errorCode }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED) + get { payload }.isA() + .and { + get { errorCode }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED.errorCode) + get { errorDescription }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED.description) + get { errorDetails }.hasSize(2) + .and { + get { get(0) } + .and { + get { code }.isEqualTo(ErrorDetailCode.ACTION.value) + get { detail }.contains("Cannot parse message, class used to retrieve the response action is not defined") + } + get { get(1) } + .and { + get { code }.isEqualTo(ErrorDetailCode.PAYLOAD.value) + get { detail }.isEqualTo(response) + } + } + } + } + } + @OptIn(ExperimentalTime::class) fun timeit(requestList: List, parser: Ocpp16JsonParser): Duration { return measureTime { diff --git a/ocpp-2-0-core/src/main/kotlin/com/izivia/ocpp/core20/model/common/enumeration/Actions.kt b/ocpp-2-0-core/src/main/kotlin/com/izivia/ocpp/core20/model/common/enumeration/Actions.kt index c40e0b35..7519206c 100644 --- a/ocpp-2-0-core/src/main/kotlin/com/izivia/ocpp/core20/model/common/enumeration/Actions.kt +++ b/ocpp-2-0-core/src/main/kotlin/com/izivia/ocpp/core20/model/common/enumeration/Actions.kt @@ -1,218 +1,474 @@ package com.izivia.ocpp.core20.model.common.enumeration import com.izivia.ocpp.core20.model.authorize.AuthorizeReq +import com.izivia.ocpp.core20.model.authorize.AuthorizeResp import com.izivia.ocpp.core20.model.bootnotification.BootNotificationReq +import com.izivia.ocpp.core20.model.bootnotification.BootNotificationResp import com.izivia.ocpp.core20.model.cancelreservation.CancelReservationReq +import com.izivia.ocpp.core20.model.cancelreservation.CancelReservationResp import com.izivia.ocpp.core20.model.certificateSigned.CertificateSignedReq +import com.izivia.ocpp.core20.model.certificateSigned.CertificateSignedResp import com.izivia.ocpp.core20.model.changeavailability.ChangeAvailabilityReq +import com.izivia.ocpp.core20.model.changeavailability.ChangeAvailabilityResp import com.izivia.ocpp.core20.model.clearcache.ClearCacheReq +import com.izivia.ocpp.core20.model.clearcache.ClearCacheResp import com.izivia.ocpp.core20.model.clearchargingprofile.ClearChargingProfileReq +import com.izivia.ocpp.core20.model.clearchargingprofile.ClearChargingProfileResp import com.izivia.ocpp.core20.model.cleardisplaymessage.ClearDisplayMessageReq +import com.izivia.ocpp.core20.model.cleardisplaymessage.ClearDisplayMessageResp import com.izivia.ocpp.core20.model.clearedcharginglimit.ClearedChargingLimitReq +import com.izivia.ocpp.core20.model.clearedcharginglimit.ClearedChargingLimitResp import com.izivia.ocpp.core20.model.clearvariablemonitoring.ClearVariableMonitoringReq +import com.izivia.ocpp.core20.model.clearvariablemonitoring.ClearVariableMonitoringResp import com.izivia.ocpp.core20.model.costupdated.CostUpdatedReq +import com.izivia.ocpp.core20.model.costupdated.CostUpdatedResp import com.izivia.ocpp.core20.model.customerinformation.CustomerInformationReq +import com.izivia.ocpp.core20.model.customerinformation.CustomerInformationResp import com.izivia.ocpp.core20.model.datatransfer.DataTransferReq +import com.izivia.ocpp.core20.model.datatransfer.DataTransferResp import com.izivia.ocpp.core20.model.deletecertificate.DeleteCertificateReq +import com.izivia.ocpp.core20.model.deletecertificate.DeleteCertificateResp import com.izivia.ocpp.core20.model.firmwarestatusnotification.FirmwareStatusNotificationReq +import com.izivia.ocpp.core20.model.firmwarestatusnotification.FirmwareStatusNotificationResp import com.izivia.ocpp.core20.model.get15118evcertificate.Get15118EVCertificateReq +import com.izivia.ocpp.core20.model.get15118evcertificate.Get15118EVCertificateResp import com.izivia.ocpp.core20.model.getbasereport.GetBaseReportReq +import com.izivia.ocpp.core20.model.getbasereport.GetBaseReportResp import com.izivia.ocpp.core20.model.getcertificatestatus.GetCertificateStatusReq +import com.izivia.ocpp.core20.model.getcertificatestatus.GetCertificateStatusResp import com.izivia.ocpp.core20.model.getchargingprofiles.GetChargingProfilesReq +import com.izivia.ocpp.core20.model.getchargingprofiles.GetChargingProfilesResp import com.izivia.ocpp.core20.model.getcompositeschedule.GetCompositeScheduleReq +import com.izivia.ocpp.core20.model.getcompositeschedule.GetCompositeScheduleResp import com.izivia.ocpp.core20.model.getdisplaymessages.GetDisplayMessagesReq +import com.izivia.ocpp.core20.model.getdisplaymessages.GetDisplayMessagesResp import com.izivia.ocpp.core20.model.getinstalledcertificateids.GetInstalledCertificateIdsReq +import com.izivia.ocpp.core20.model.getinstalledcertificateids.GetInstalledCertificateIdsResp import com.izivia.ocpp.core20.model.getlocallistversion.GetLocalListVersionReq +import com.izivia.ocpp.core20.model.getlocallistversion.GetLocalListVersionResp import com.izivia.ocpp.core20.model.getlog.GetLogReq +import com.izivia.ocpp.core20.model.getlog.GetLogResp import com.izivia.ocpp.core20.model.getmonitoringreport.GetMonitoringReportReq +import com.izivia.ocpp.core20.model.getmonitoringreport.GetMonitoringReportResp import com.izivia.ocpp.core20.model.getreport.GetReportReq +import com.izivia.ocpp.core20.model.getreport.GetReportResp import com.izivia.ocpp.core20.model.gettransactionstatus.GetTransactionStatusReq +import com.izivia.ocpp.core20.model.gettransactionstatus.GetTransactionStatusResp import com.izivia.ocpp.core20.model.getvariables.GetVariablesReq +import com.izivia.ocpp.core20.model.getvariables.GetVariablesResp import com.izivia.ocpp.core20.model.heartbeat.HeartbeatReq +import com.izivia.ocpp.core20.model.heartbeat.HeartbeatResp import com.izivia.ocpp.core20.model.installcertificate.InstallCertificateReq +import com.izivia.ocpp.core20.model.installcertificate.InstallCertificateResp import com.izivia.ocpp.core20.model.logstatusnotification.LogStatusNotificationReq +import com.izivia.ocpp.core20.model.logstatusnotification.LogStatusNotificationResp import com.izivia.ocpp.core20.model.metervalues.MeterValuesReq +import com.izivia.ocpp.core20.model.metervalues.MeterValuesResp import com.izivia.ocpp.core20.model.notifycharginglimit.NotifyChargingLimitReq +import com.izivia.ocpp.core20.model.notifycharginglimit.NotifyChargingLimitResp import com.izivia.ocpp.core20.model.notifycustomerinformation.NotifyCustomerInformationReq +import com.izivia.ocpp.core20.model.notifycustomerinformation.NotifyCustomerInformationResp import com.izivia.ocpp.core20.model.notifydisplaymessages.NotifyDisplayMessagesReq +import com.izivia.ocpp.core20.model.notifydisplaymessages.NotifyDisplayMessagesResp import com.izivia.ocpp.core20.model.notifyevchargingneeds.NotifyEVChargingNeedsReq +import com.izivia.ocpp.core20.model.notifyevchargingneeds.NotifyEVChargingNeedsResp import com.izivia.ocpp.core20.model.notifyevchargingschedule.NotifyEVChargingScheduleReq +import com.izivia.ocpp.core20.model.notifyevchargingschedule.NotifyEVChargingScheduleResp import com.izivia.ocpp.core20.model.notifyevent.NotifyEventReq +import com.izivia.ocpp.core20.model.notifyevent.NotifyEventResp import com.izivia.ocpp.core20.model.notifymonitoringreport.NotifyMonitoringReportReq +import com.izivia.ocpp.core20.model.notifymonitoringreport.NotifyMonitoringReportResp import com.izivia.ocpp.core20.model.notifyreport.NotifyReportReq +import com.izivia.ocpp.core20.model.notifyreport.NotifyReportResp import com.izivia.ocpp.core20.model.publishfirmware.PublishFirmwareReq +import com.izivia.ocpp.core20.model.publishfirmware.PublishFirmwareResp import com.izivia.ocpp.core20.model.publishfirmwarestatusnotification.PublishFirmwareStatusNotificationReq +import com.izivia.ocpp.core20.model.publishfirmwarestatusnotification.PublishFirmwareStatusNotificationResp import com.izivia.ocpp.core20.model.remotestart.RequestStartTransactionReq +import com.izivia.ocpp.core20.model.remotestart.RequestStartTransactionResp import com.izivia.ocpp.core20.model.remotestop.RequestStopTransactionReq +import com.izivia.ocpp.core20.model.remotestop.RequestStopTransactionResp import com.izivia.ocpp.core20.model.reportchargingprofiles.ReportChargingProfilesReq +import com.izivia.ocpp.core20.model.reportchargingprofiles.ReportChargingProfilesResp import com.izivia.ocpp.core20.model.reservationstatusupdate.ReservationStatusUpdateReq +import com.izivia.ocpp.core20.model.reservationstatusupdate.ReservationStatusUpdateResp import com.izivia.ocpp.core20.model.reservenow.ReserveNowReq +import com.izivia.ocpp.core20.model.reservenow.ReserveNowResp import com.izivia.ocpp.core20.model.reset.ResetReq +import com.izivia.ocpp.core20.model.reset.ResetResp import com.izivia.ocpp.core20.model.securityeventnotification.SecurityEventNotificationReq +import com.izivia.ocpp.core20.model.securityeventnotification.SecurityEventNotificationResp import com.izivia.ocpp.core20.model.sendlocallist.SendLocalListReq +import com.izivia.ocpp.core20.model.sendlocallist.SendLocalListResp import com.izivia.ocpp.core20.model.setchargingprofile.SetChargingProfileReq +import com.izivia.ocpp.core20.model.setchargingprofile.SetChargingProfileResp import com.izivia.ocpp.core20.model.setdisplaymessage.SetDisplayMessageReq +import com.izivia.ocpp.core20.model.setdisplaymessage.SetDisplayMessageResp import com.izivia.ocpp.core20.model.setmonitoringbase.SetMonitoringBaseReq +import com.izivia.ocpp.core20.model.setmonitoringbase.SetMonitoringBaseResp import com.izivia.ocpp.core20.model.setmonitoringlevel.SetMonitoringLevelReq +import com.izivia.ocpp.core20.model.setmonitoringlevel.SetMonitoringLevelResp import com.izivia.ocpp.core20.model.setnetworkprofile.SetNetworkProfileReq +import com.izivia.ocpp.core20.model.setnetworkprofile.SetNetworkProfileResp import com.izivia.ocpp.core20.model.setvariablemonitoring.SetVariableMonitoringReq +import com.izivia.ocpp.core20.model.setvariablemonitoring.SetVariableMonitoringResp import com.izivia.ocpp.core20.model.setvariables.SetVariablesReq +import com.izivia.ocpp.core20.model.setvariables.SetVariablesResp import com.izivia.ocpp.core20.model.signcertificate.SignCertificateReq +import com.izivia.ocpp.core20.model.signcertificate.SignCertificateResp import com.izivia.ocpp.core20.model.statusnotification.StatusNotificationReq +import com.izivia.ocpp.core20.model.statusnotification.StatusNotificationResp import com.izivia.ocpp.core20.model.transactionevent.TransactionEventReq +import com.izivia.ocpp.core20.model.transactionevent.TransactionEventResp import com.izivia.ocpp.core20.model.triggermessage.TriggerMessageReq +import com.izivia.ocpp.core20.model.triggermessage.TriggerMessageResp import com.izivia.ocpp.core20.model.unlockconnector.UnlockConnectorReq +import com.izivia.ocpp.core20.model.unlockconnector.UnlockConnectorResp import com.izivia.ocpp.core20.model.unpublishfirmware.UnpublishFirmwareReq +import com.izivia.ocpp.core20.model.unpublishfirmware.UnpublishFirmwareResp import com.izivia.ocpp.core20.model.updatefirmware.UpdateFirmwareReq +import com.izivia.ocpp.core20.model.updatefirmware.UpdateFirmwareResp import com.izivia.ocpp.utils.IActions import com.izivia.ocpp.utils.OcppInitiator enum class Actions( - override val value: String, override val classRequest: Class<*>, + override val value: String, + override val classRequest: Class<*>, + override val classResponse: Class<*>, override val initiatedBy: OcppInitiator ) : IActions { - AUTHORIZE("authorize", AuthorizeReq::class.java, OcppInitiator.CHARGING_STATION), - BOOTNOTIFICATION("bootNotification", BootNotificationReq::class.java, OcppInitiator.CHARGING_STATION), - CANCELRESERVATION("cancelReservation", CancelReservationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CERTIFICATESIGNED("certificateSigned", CertificateSignedReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CHANGEAVAILABILITY("changeAvailability", ChangeAvailabilityReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CLEARCACHE("clearCache", ClearCacheReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CLEARCHARGINGPROFILE("clearChargingProfile", ClearChargingProfileReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CLEARDISPLAYMESSAGE("clearDisplayMessage", ClearDisplayMessageReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CLEAREDCHARGINGLIMIT("clearedChargingLimit", ClearedChargingLimitReq::class.java, OcppInitiator.CHARGING_STATION), + AUTHORIZE( + "authorize", AuthorizeReq::class.java, AuthorizeResp::class.java, OcppInitiator.CHARGING_STATION + ), + BOOTNOTIFICATION( + "bootNotification", + BootNotificationReq::class.java, + BootNotificationResp::class.java, + OcppInitiator.CHARGING_STATION + ), + CANCELRESERVATION( + "cancelReservation", + CancelReservationReq::class.java, + CancelReservationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CERTIFICATESIGNED( + "certificateSigned", + CertificateSignedReq::class.java, + CertificateSignedResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CHANGEAVAILABILITY( + "changeAvailability", + ChangeAvailabilityReq::class.java, + ChangeAvailabilityResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CLEARCACHE("clearCache", ClearCacheReq::class.java, ClearCacheResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + CLEARCHARGINGPROFILE( + "clearChargingProfile", + ClearChargingProfileReq::class.java, + ClearChargingProfileResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CLEARDISPLAYMESSAGE( + "clearDisplayMessage", + ClearDisplayMessageReq::class.java, + ClearDisplayMessageResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + CLEAREDCHARGINGLIMIT( + "clearedChargingLimit", + ClearedChargingLimitReq::class.java, + ClearedChargingLimitResp::class.java, + OcppInitiator.CHARGING_STATION + ), CLEARVARIABLEMONITORING( "clearVariableMonitoring", ClearVariableMonitoringReq::class.java, + ClearVariableMonitoringResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + COSTUPDATED("costUpdated", CostUpdatedReq::class.java, CostUpdatedResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + CUSTOMERINFORMATION( + "customerInformation", + CustomerInformationReq::class.java, + CustomerInformationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + DATATRANSFER("dataTransfer", DataTransferReq::class.java, DataTransferResp::class.java, OcppInitiator.ALL), + DELETECERTIFICATE( + "deleteCertificate", + DeleteCertificateReq::class.java, + DeleteCertificateResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - COSTUPDATED("costUpdated", CostUpdatedReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - CUSTOMERINFORMATION("customerInformation", CustomerInformationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - DATATRANSFER("dataTransfer", DataTransferReq::class.java, OcppInitiator.ALL), - DELETECERTIFICATE("deleteCertificate", DeleteCertificateReq::class.java, OcppInitiator.CENTRAL_SYSTEM), FIRMWARESTATUSNOTIFICATION( "firmwareStatusNotification", FirmwareStatusNotificationReq::class.java, + FirmwareStatusNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), GET15118EVCERTIFICATE( "get15118EVCertificate", Get15118EVCertificateReq::class.java, + Get15118EVCertificateResp::class.java, OcppInitiator.CHARGING_STATION ), - GETBASEREPORT("getBaseReport", GetBaseReportReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + GETBASEREPORT( + "getBaseReport", + GetBaseReportReq::class.java, + GetBaseReportResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), GETCERTIFICATESTATUS( - "getCertificateStatus", GetCertificateStatusReq::class.java, + "getCertificateStatus", + GetCertificateStatusReq::class.java, + GetCertificateStatusResp::class.java, OcppInitiator.CHARGING_STATION ), - GETCHARGINGPROFILES("getChargingProfiles", GetChargingProfilesReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + GETCHARGINGPROFILES( + "getChargingProfiles", + GetChargingProfilesReq::class.java, + GetChargingProfilesResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), GETCOMPOSITESCHEDULE( - "getCompositeSchedule", GetCompositeScheduleReq::class.java, + "getCompositeSchedule", + GetCompositeScheduleReq::class.java, + GetCompositeScheduleResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETDISPLAYMESSAGES( + "getDisplayMessages", + GetDisplayMessagesReq::class.java, + GetDisplayMessagesResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - GETDISPLAYMESSAGES("getDisplayMessages", GetDisplayMessagesReq::class.java, OcppInitiator.CENTRAL_SYSTEM), GETINSTALLEDCERTIFICATEIDS( "getInstalledCertificateIds", GetInstalledCertificateIdsReq::class.java, + GetInstalledCertificateIdsResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - GETLOCALLISTVERSION("getLocalListVersion", GetLocalListVersionReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETLOG("getLog", GetLogReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETMONITORINGREPORT("getMonitoringReport", GetMonitoringReportReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - GETREPORT("getReport", GetReportReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + GETLOCALLISTVERSION( + "getLocalListVersion", + GetLocalListVersionReq::class.java, + GetLocalListVersionResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETLOG("getLog", GetLogReq::class.java, GetLogResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + GETMONITORINGREPORT( + "getMonitoringReport", + GetMonitoringReportReq::class.java, + GetMonitoringReportResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETREPORT("getReport", GetReportReq::class.java, GetReportResp::class.java, OcppInitiator.CENTRAL_SYSTEM), GETTRANSACTIONSTATUS( - "getTransactionStatus", GetTransactionStatusReq::class.java, + "getTransactionStatus", + GetTransactionStatusReq::class.java, + GetTransactionStatusResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + GETVARIABLES( + "getVariables", + GetVariablesReq::class.java, + GetVariablesResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + HEARTBEAT("heartbeat", HeartbeatReq::class.java, HeartbeatResp::class.java, OcppInitiator.CHARGING_STATION), + INSTALLCERTIFICATE( + "installCertificate", + InstallCertificateReq::class.java, + InstallCertificateResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - GETVARIABLES("getVariables", GetVariablesReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - HEARTBEAT("heartbeat", HeartbeatReq::class.java, OcppInitiator.CHARGING_STATION), - INSTALLCERTIFICATE("installCertificate", InstallCertificateReq::class.java, OcppInitiator.CENTRAL_SYSTEM), LOGSTATUSNOTIFICATION( "logStatusNotification", LogStatusNotificationReq::class.java, + LogStatusNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), - METERVALUES("meterValues", MeterValuesReq::class.java, OcppInitiator.CHARGING_STATION), + METERVALUES("meterValues", MeterValuesReq::class.java, MeterValuesResp::class.java, OcppInitiator.CHARGING_STATION), NOTIFYCHARGINGLIMIT( - "notifyChargingLimit", NotifyChargingLimitReq::class.java, + "notifyChargingLimit", + NotifyChargingLimitReq::class.java, + NotifyChargingLimitResp::class.java, OcppInitiator.CHARGING_STATION ), NOTIFYCUSTOMERINFORMATION( "notifyCustomerInformation", NotifyCustomerInformationReq::class.java, + NotifyCustomerInformationResp::class.java, OcppInitiator.CHARGING_STATION ), NOTIFYDISPLAYMESSAGES( "notifyDisplayMessages", NotifyDisplayMessagesReq::class.java, + NotifyDisplayMessagesResp::class.java, OcppInitiator.CHARGING_STATION ), NOTIFYEVCHARGINGNEEDS( "notifyEVChargingNeeds", NotifyEVChargingNeedsReq::class.java, + NotifyEVChargingNeedsResp::class.java, OcppInitiator.CHARGING_STATION ), NOTIFYEVCHARGINGSCHEDULE( "notifyEVChargingSchedule", NotifyEVChargingScheduleReq::class.java, + NotifyEVChargingScheduleResp::class.java, OcppInitiator.CHARGING_STATION ), - NOTIFYEVENT("notifyEvent", NotifyEventReq::class.java, OcppInitiator.CHARGING_STATION), + NOTIFYEVENT("notifyEvent", NotifyEventReq::class.java, NotifyEventResp::class.java, OcppInitiator.CHARGING_STATION), NOTIFYMONITORINGREPORT( "notifyMonitoringReport", NotifyMonitoringReportReq::class.java, + NotifyMonitoringReportResp::class.java, OcppInitiator.CHARGING_STATION ), - NOTIFYREPORT("notifyReport", NotifyReportReq::class.java, OcppInitiator.CHARGING_STATION), - PUBLISHFIRMWARE("publishFirmware", PublishFirmwareReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + NOTIFYREPORT( + "notifyReport", + NotifyReportReq::class.java, + NotifyReportResp::class.java, + OcppInitiator.CHARGING_STATION + ), + PUBLISHFIRMWARE( + "publishFirmware", + PublishFirmwareReq::class.java, + PublishFirmwareResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), PUBLISHFIRMWARESTATUSNOTIFICATION( "publishFirmwareStatusNotification", - PublishFirmwareStatusNotificationReq::class.java, OcppInitiator.CHARGING_STATION + PublishFirmwareStatusNotificationReq::class.java, + PublishFirmwareStatusNotificationResp::class.java, + OcppInitiator.CHARGING_STATION ), REPORTCHARGINGPROFILES( "reportChargingProfiles", ReportChargingProfilesReq::class.java, + ReportChargingProfilesResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), REQUESTSTARTTRANSACTION( "requestStartTransaction", RequestStartTransactionReq::class.java, + RequestStartTransactionResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), REQUESTSTOPTRANSACTION( "requestStopTransaction", RequestStopTransactionReq::class.java, + RequestStopTransactionResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), RESERVATIONSTATUSUPDATE( "reservationStatusUpdate", ReservationStatusUpdateReq::class.java, + ReservationStatusUpdateResp::class.java, OcppInitiator.CHARGING_STATION ), - RESERVENOW("reserveNow", ReserveNowReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - RESET("reset", ResetReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + RESERVENOW("reserveNow", ReserveNowReq::class.java, ReserveNowResp::class.java, OcppInitiator.CENTRAL_SYSTEM), + RESET("reset", ResetReq::class.java, ResetResp::class.java, OcppInitiator.CENTRAL_SYSTEM), SECURITYEVENTNOTIFICATION( "securityEventNotification", SecurityEventNotificationReq::class.java, + SecurityEventNotificationResp::class.java, OcppInitiator.CHARGING_STATION ), - SENDLOCALLIST("sendLocalList", SendLocalListReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SETCHARGINGPROFILE("setChargingProfile", SetChargingProfileReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SETDISPLAYMESSAGE("setDisplayMessage", SetDisplayMessageReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SETMONITORINGBASE("setMonitoringBase", SetMonitoringBaseReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SETMONITORINGLEVEL("setMonitoringLevel", SetMonitoringLevelReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SETNETWORKPROFILE("setNetworkProfile", SetNetworkProfileReq::class.java, OcppInitiator.CENTRAL_SYSTEM), + SENDLOCALLIST( + "sendLocalList", + SendLocalListReq::class.java, + SendLocalListResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SETCHARGINGPROFILE( + "setChargingProfile", + SetChargingProfileReq::class.java, + SetChargingProfileResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SETDISPLAYMESSAGE( + "setDisplayMessage", + SetDisplayMessageReq::class.java, + SetDisplayMessageResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SETMONITORINGBASE( + "setMonitoringBase", + SetMonitoringBaseReq::class.java, + SetMonitoringBaseResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SETMONITORINGLEVEL( + "setMonitoringLevel", + SetMonitoringLevelReq::class.java, + SetMonitoringLevelResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SETNETWORKPROFILE( + "setNetworkProfile", + SetNetworkProfileReq::class.java, + SetNetworkProfileResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), SETVARIABLEMONITORING( - "setVariableMonitoring", SetVariableMonitoringReq::class.java, + "setVariableMonitoring", + SetVariableMonitoringReq::class.java, + SetVariableMonitoringResp::class.java, OcppInitiator.CENTRAL_SYSTEM ), - SETVARIABLES("setVariables", SetVariablesReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - SIGNCERTIFICATE("signCertificate", SignCertificateReq::class.java, OcppInitiator.CHARGING_STATION), - STATUSNOTIFICATION("statusNotification", StatusNotificationReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - TRANSACTIONEVENT("transactionEvent", TransactionEventReq::class.java, OcppInitiator.CHARGING_STATION), - TRIGGERMESSAGE("triggerMessage", TriggerMessageReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - UNLOCKCONNECTOR("unlockConnector", UnlockConnectorReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - UNPUBLISHFIRMWARE("unpublishFirmware", UnpublishFirmwareReq::class.java, OcppInitiator.CENTRAL_SYSTEM), - UPDATEFIRMWARE("updateFirmware", UpdateFirmwareReq::class.java, OcppInitiator.CENTRAL_SYSTEM); + SETVARIABLES( + "setVariables", + SetVariablesReq::class.java, + SetVariablesResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + SIGNCERTIFICATE( + "signCertificate", + SignCertificateReq::class.java, + SignCertificateResp::class.java, + OcppInitiator.CHARGING_STATION + ), + STATUSNOTIFICATION( + "statusNotification", + StatusNotificationReq::class.java, + StatusNotificationResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + TRANSACTIONEVENT( + "transactionEvent", + TransactionEventReq::class.java, + TransactionEventResp::class.java, + OcppInitiator.CHARGING_STATION + ), + TRIGGERMESSAGE( + "triggerMessage", + TriggerMessageReq::class.java, + TriggerMessageResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + UNLOCKCONNECTOR( + "unlockConnector", + UnlockConnectorReq::class.java, + UnlockConnectorResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + UNPUBLISHFIRMWARE( + "unpublishFirmware", + UnpublishFirmwareReq::class.java, + UnpublishFirmwareResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ), + UPDATEFIRMWARE( + "updateFirmware", + UpdateFirmwareReq::class.java, + UpdateFirmwareResp::class.java, + OcppInitiator.CENTRAL_SYSTEM + ); + fun lowercase() = value.lowercase() diff --git a/ocpp-2-0-json/src/main/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParser.kt b/ocpp-2-0-json/src/main/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParser.kt index 3aeeb200..20267698 100644 --- a/ocpp-2-0-json/src/main/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParser.kt +++ b/ocpp-2-0-json/src/main/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParser.kt @@ -34,6 +34,13 @@ class Ocpp20JsonParser( throw errorHandler(e) } + override fun getResponsePayloadClass(action: String, errorHandler: (e: Exception) -> Throwable): Class = + try { + Actions.valueOf(action.uppercase()).classResponse + } catch (e: Exception) { + throw errorHandler(e) + } + override fun getActionFromClass(className: String): String = Actions.valueOf(getActionFromClassName(className)).value diff --git a/ocpp-2-0-json/src/test/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParserTest.kt b/ocpp-2-0-json/src/test/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParserTest.kt index 0f870351..1272ac59 100644 --- a/ocpp-2-0-json/src/test/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParserTest.kt +++ b/ocpp-2-0-json/src/test/kotlin/com/izivia/ocpp/json20/Ocpp20JsonParserTest.kt @@ -416,6 +416,36 @@ class Ocpp20JsonParserTest { // expectThat(percent).isGreaterThan(0.0) } + @Test + fun `should parse to Fault missing usedClazz`() { + val response = """[3,"messageId",{}]""" + + val res = parser.parseAnyFromString(response) + expectThat(res) + .and { + get { action }.isEqualTo("Fault") + get { errorCode }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED) + get { payload }.isA() + .and { + get { errorCode }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED.errorCode) + get { errorDescription }.isEqualTo(MessageErrorCode.NOT_IMPLEMENTED.description) + get { errorDetails }.hasSize(2) + .and { + get { get(0) } + .and { + get { code }.isEqualTo(ErrorDetailCode.ACTION.value) + get { detail }.contains("Cannot parse message, class used to retrieve the response action is not defined") + } + get { get(1) } + .and { + get { code }.isEqualTo(ErrorDetailCode.PAYLOAD.value) + get { detail }.isEqualTo(response) + } + } + } + } + } + @OptIn(ExperimentalTime::class) fun timeit(requestList: List, parser: Ocpp20JsonParser): Duration { return measureTime { diff --git a/ocpp-json/src/main/kotlin/com/izivia/ocpp/json/OcppJsonParser.kt b/ocpp-json/src/main/kotlin/com/izivia/ocpp/json/OcppJsonParser.kt index 4f60096e..c4f8cc7e 100644 --- a/ocpp-json/src/main/kotlin/com/izivia/ocpp/json/OcppJsonParser.kt +++ b/ocpp-json/src/main/kotlin/com/izivia/ocpp/json/OcppJsonParser.kt @@ -4,7 +4,8 @@ import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.izivia.ocpp.json.JsonMessageType.* import com.izivia.ocpp.utils.* -import com.izivia.ocpp.utils.fault.* +import com.izivia.ocpp.utils.fault.FAULT +import com.izivia.ocpp.utils.fault.Fault import com.networknt.schema.ValidationMessage import com.networknt.schema.ValidatorTypeCode import kotlin.reflect.KClass @@ -26,6 +27,11 @@ abstract class OcppJsonParser( errorHandler: (e: Exception) -> Throwable ): Class + protected abstract fun getResponsePayloadClass( + action: String, + errorHandler: (e: Exception) -> Throwable + ): Class + protected abstract fun getActionFromClass(className: String): String protected abstract fun validateJson( @@ -33,6 +39,15 @@ abstract class OcppJsonParser( errorsHandler: (errors: List) -> Unit ) + /** + * Parses a JSON message from a string. + * + * @param messageStr The string representation of the message. + * @param useClazz In the case of a CALL_RESULT type message, useClazz is the class used to parse the message + * (as it cannot always be deduced from the message itself) + * + * @return A JsonMessage object containing the parsed data. + */ fun parseAnyFromString(messageStr: String, useClazz: Class? = null): JsonMessage { try { val warnings = mutableListOf() @@ -61,7 +76,20 @@ abstract class OcppJsonParser( CALL_RESULT -> useClazz?.let { parsed = parsed.copy(action = getActionFromClass(it.simpleName)) clazz = useClazz - } + } ?: throw ActionResponseNotSpecifiedException( + message = "Action class not defined", + messageId = parsed.msgId, + errorDetails = listOf( + ErrorDetail( + code = ErrorDetailCode.ACTION.value, + detail = "Cannot parse message, class used to retrieve the response action is not defined" + ), + ErrorDetail( + code = ErrorDetailCode.PAYLOAD.value, + detail = messageStr + ) + ) + ) else -> { parsed = parsed.copy( diff --git a/utils/src/main/kotlin/com/izivia/ocpp/utils/Commons.kt b/utils/src/main/kotlin/com/izivia/ocpp/utils/Commons.kt index b09b202e..46159a26 100644 --- a/utils/src/main/kotlin/com/izivia/ocpp/utils/Commons.kt +++ b/utils/src/main/kotlin/com/izivia/ocpp/utils/Commons.kt @@ -9,6 +9,7 @@ inline fun Any.isA(function: (T) -> Any = { it -> it }): Any = interface IActions { val value: String val classRequest: Class<*> + val classResponse: Class<*> val initiatedBy: OcppInitiator } diff --git a/utils/src/main/kotlin/com/izivia/ocpp/utils/Exceptions.kt b/utils/src/main/kotlin/com/izivia/ocpp/utils/Exceptions.kt index 03303a5b..1fbdd66e 100644 --- a/utils/src/main/kotlin/com/izivia/ocpp/utils/Exceptions.kt +++ b/utils/src/main/kotlin/com/izivia/ocpp/utils/Exceptions.kt @@ -124,3 +124,20 @@ class MissingRelatesToHeaderException( ) ).plus(errorDetails) ) + +class ActionResponseNotSpecifiedException( + override val message: String, + override val messageId: String?, + override val errorDetails: List = emptyList() +) : + OcppParserException( + message = message, + messageId = messageId, + errorCode = MessageErrorCode.NOT_IMPLEMENTED, + errorDetails = listOf( + ErrorDetail( + code = MessageErrorCode.NOT_IMPLEMENTED.errorCode, + detail = MessageErrorCode.NOT_IMPLEMENTED.description + ) + ).plus(errorDetails) + )