From 9d20cbb1fa078b9ec99160750294e4cdcde00ff0 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Thu, 11 Jan 2024 12:54:37 +0100 Subject: [PATCH] Avoid creating the eBL scenario list all the time Signed-off-by: Niels Thykier --- .../standards/ebl/EblComponentFactory.java | 43 ++++++-- .../standards/ebl/EblScenarioListBuilder.java | 103 +++++++++--------- 2 files changed, 83 insertions(+), 63 deletions(-) diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblComponentFactory.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblComponentFactory.java index 8176605e..1480014a 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblComponentFactory.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblComponentFactory.java @@ -2,15 +2,17 @@ import com.fasterxml.jackson.databind.JsonNode; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import lombok.SneakyThrows; import org.dcsa.conformance.core.AbstractComponentFactory; -import org.dcsa.conformance.core.check.JsonSchemaValidator; import org.dcsa.conformance.core.party.ConformanceParty; import org.dcsa.conformance.core.party.CounterpartConfiguration; import org.dcsa.conformance.core.party.PartyConfiguration; import org.dcsa.conformance.core.party.PartyWebClient; +import org.dcsa.conformance.core.scenario.ConformanceScenario; import org.dcsa.conformance.core.scenario.ScenarioListBuilder; import org.dcsa.conformance.core.state.JsonNodeMap; import org.dcsa.conformance.core.toolkit.JsonToolkit; @@ -25,6 +27,8 @@ public class EblComponentFactory extends AbstractComponentFactory { private static final String CARRIER_AUTH_HEADER_VALUE = UUID.randomUUID().toString(); private static final String SHIPPER_AUTH_HEADER_VALUE = UUID.randomUUID().toString(); + private static final ConcurrentHashMap> SCENARIO_CACHE = new ConcurrentHashMap<>(); + private final String standardVersion; public EblComponentFactory(String standardVersion) { @@ -82,12 +86,36 @@ public List createParties( public ScenarioListBuilder createScenarioListBuilder( PartyConfiguration[] partyConfigurations, CounterpartConfiguration[] counterpartConfigurations) { - return EblScenarioListBuilder.buildTree( - this, + return new CachedEblScenarioListBuilder<>(standardVersion, () -> EblScenarioListBuilder.buildTree( + this.standardVersion, _findPartyOrCounterpartName( partyConfigurations, counterpartConfigurations, EblRole::isCarrier), _findPartyOrCounterpartName( - partyConfigurations, counterpartConfigurations, EblRole::isShipper)); + partyConfigurations, counterpartConfigurations, EblRole::isShipper))); + } + + + private static class CachedEblScenarioListBuilder> extends ScenarioListBuilder { + + private final Supplier realScenarioBuilder; + private final String standardVersion; + + protected CachedEblScenarioListBuilder(String standardVersion, Supplier realScenarioBuilder) { + super(Function.identity()); + this.standardVersion = standardVersion; + this.realScenarioBuilder = realScenarioBuilder; + } + + @Override + protected List _buildScenarioList() { + var scenarioList = SCENARIO_CACHE.get(standardVersion); + if (scenarioList != null) { + return scenarioList; + } + scenarioList = Collections.unmodifiableList(realScenarioBuilder.get().buildScenarioList()); + SCENARIO_CACHE.put(standardVersion, scenarioList); + return scenarioList; + } } @Override @@ -112,13 +140,6 @@ public Set getReportRoleNames( .collect(Collectors.toSet()); } - public JsonSchemaValidator getMessageSchemaValidator(String apiName, String jsonSchema) { - String schemaFilePath = "/standards/ebl/schemas/ebl-%s-v%s0.json" - .formatted(apiName, standardVersion.charAt(0)); - - return JsonSchemaValidator.getInstance(schemaFilePath, jsonSchema); - } - @SneakyThrows public JsonNode getJsonSandboxConfigurationTemplate( String testedPartyRole, boolean isManual, boolean isTestingCounterpartsConfig) { diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java index 0d6fa6a8..f5d120c3 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java @@ -3,8 +3,10 @@ import static org.dcsa.conformance.standards.ebl.party.ShippingInstructionsStatus.*; import static org.dcsa.conformance.standards.ebl.party.TransportDocumentStatus.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import lombok.extern.slf4j.Slf4j; +import org.dcsa.conformance.core.check.JsonSchemaValidator; import org.dcsa.conformance.core.scenario.ConformanceAction; import org.dcsa.conformance.core.scenario.ScenarioListBuilder; import org.dcsa.conformance.standards.ebl.action.*; @@ -15,8 +17,7 @@ @Slf4j public class EblScenarioListBuilder extends ScenarioListBuilder { - private static final ThreadLocal threadLocalComponentFactory = - new ThreadLocal<>(); + private static final ThreadLocal STANDARD_VERSION = new ThreadLocal<>(); private static final ThreadLocal threadLocalCarrierPartyName = new ThreadLocal<>(); private static final ThreadLocal threadLocalShipperPartyName = new ThreadLocal<>(); @@ -34,9 +35,11 @@ public class EblScenarioListBuilder extends ScenarioListBuilder SCHEMA_CACHE = new ConcurrentHashMap<>(); + public static EblScenarioListBuilder buildTree( - EblComponentFactory componentFactory, String carrierPartyName, String shipperPartyName) { - threadLocalComponentFactory.set(componentFactory); + String standardVersion, String carrierPartyName, String shipperPartyName) { + STANDARD_VERSION.set(standardVersion); threadLocalCarrierPartyName.set(carrierPartyName); threadLocalShipperPartyName.set(shipperPartyName); return noAction().thenEither( @@ -354,7 +357,6 @@ private static EblScenarioListBuilder shipper_GetShippingInstructions( boolean requestAmendedSI, boolean recordTDR, boolean useTDRef) { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -365,7 +367,7 @@ private static EblScenarioListBuilder shipper_GetShippingInstructions( (EblAction) previousAction, expectedSiStatus, expectedUpdatedSiStatus, - componentFactory.getMessageSchemaValidator(EBL_API, GET_EBL_SCHEMA_NAME), + resolveMessageSchemaValidator(EBL_API, GET_EBL_SCHEMA_NAME), requestAmendedSI, recordTDR, useTDRef)); @@ -373,7 +375,6 @@ private static EblScenarioListBuilder shipper_GetShippingInstructions( private static EblScenarioListBuilder shipper_GetTransportDocument( TransportDocumentStatus expectedTdStatus) { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -383,11 +384,10 @@ private static EblScenarioListBuilder shipper_GetTransportDocument( shipperPartyName, (EblAction) previousAction, expectedTdStatus, - componentFactory.getMessageSchemaValidator(EBL_API, GET_TD_SCHEMA_NAME))); + resolveMessageSchemaValidator(EBL_API, GET_TD_SCHEMA_NAME))); } private static EblScenarioListBuilder uc1_shipper_submitShippingInstructions() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -396,13 +396,12 @@ private static EblScenarioListBuilder uc1_shipper_submitShippingInstructions() { carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator(EBL_API, POST_EBL_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator(EBL_API, EBL_REF_STATUS_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator(EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); + resolveMessageSchemaValidator(EBL_API, POST_EBL_SCHEMA_NAME), + resolveMessageSchemaValidator(EBL_API, EBL_REF_STATUS_SCHEMA_NAME), + resolveMessageSchemaValidator(EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc3_shipper_submitUpdatedShippingInstructions(boolean useTDRef) { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -412,14 +411,13 @@ private static EblScenarioListBuilder uc3_shipper_submitUpdatedShippingInstructi shipperPartyName, (EblAction) previousAction, useTDRef, - componentFactory.getMessageSchemaValidator(EBL_API, PUT_EBL_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator(EBL_API, EBL_REF_STATUS_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator(EBL_API, PUT_EBL_SCHEMA_NAME), + resolveMessageSchemaValidator(EBL_API, EBL_REF_STATUS_SCHEMA_NAME), + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc2_carrier_requestUpdateToShippingInstruction() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -428,12 +426,11 @@ private static EblScenarioListBuilder uc2_carrier_requestUpdateToShippingInstruc carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc4a_carrier_acceptUpdatedShippingInstructions() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -442,13 +439,12 @@ private static EblScenarioListBuilder uc4a_carrier_acceptUpdatedShippingInstruct carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME), true)); } private static EblScenarioListBuilder uc4d_carrier_declineUpdatedShippingInstructions() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -457,13 +453,12 @@ private static EblScenarioListBuilder uc4d_carrier_declineUpdatedShippingInstruc carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME), false)); } private static EblScenarioListBuilder uc5_shipper_cancelUpdateToShippingInstructions() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -472,16 +467,15 @@ private static EblScenarioListBuilder uc5_shipper_cancelUpdateToShippingInstruct carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_API, PATCH_SI_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_API, EBL_REF_STATUS_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc6_carrier_publishDraftTransportDocument() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -490,12 +484,11 @@ private static EblScenarioListBuilder uc6_carrier_publishDraftTransportDocument( carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc7_shipper_approveDraftTransportDocument() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -504,16 +497,15 @@ private static EblScenarioListBuilder uc7_shipper_approveDraftTransportDocument( carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_API, PATCH_TD_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_API, TD_REF_STATUS_SCHEMA_NAME), - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc8_carrier_issueTransportDocument() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -522,12 +514,11 @@ private static EblScenarioListBuilder uc8_carrier_issueTransportDocument() { carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc9_carrier_awaitSurrenderRequestForAmendment() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -536,12 +527,11 @@ private static EblScenarioListBuilder uc9_carrier_awaitSurrenderRequestForAmendm carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc10a_carrier_acceptSurrenderRequestForAmendment() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -550,13 +540,12 @@ private static EblScenarioListBuilder uc10a_carrier_acceptSurrenderRequestForAme carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME), true)); } private static EblScenarioListBuilder uc10r_carrier_rejectSurrenderRequestForAmendment() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -565,13 +554,12 @@ private static EblScenarioListBuilder uc10r_carrier_rejectSurrenderRequestForAme carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME), false)); } private static EblScenarioListBuilder uc11_carrier_voidTransportDocument() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -580,12 +568,11 @@ private static EblScenarioListBuilder uc11_carrier_voidTransportDocument() { carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc11i_carrier_issueAmendedTransportDocument() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -594,14 +581,13 @@ private static EblScenarioListBuilder uc11i_carrier_issueAmendedTransportDocumen carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc12_carrier_awaitSurrenderRequestForDelivery() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -610,12 +596,11 @@ private static EblScenarioListBuilder uc12_carrier_awaitSurrenderRequestForDeliv carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME))); } private static EblScenarioListBuilder uc13a_carrier_acceptSurrenderRequestForDelivery() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -624,13 +609,12 @@ private static EblScenarioListBuilder uc13a_carrier_acceptSurrenderRequestForDel carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME), true)); } private static EblScenarioListBuilder uc13r_carrier_rejectSurrenderRequestForDelivery() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -639,14 +623,13 @@ private static EblScenarioListBuilder uc13r_carrier_rejectSurrenderRequestForDel carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_TD_NOTIFICATION_SCHEMA_NAME), false)); } private static EblScenarioListBuilder uc14_carrier_confirmShippingInstructionsComplete() { - EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new EblScenarioListBuilder( @@ -655,7 +638,23 @@ private static EblScenarioListBuilder uc14_carrier_confirmShippingInstructionsCo carrierPartyName, shipperPartyName, (EblAction) previousAction, - componentFactory.getMessageSchemaValidator( + resolveMessageSchemaValidator( EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); } + + private static JsonSchemaValidator resolveMessageSchemaValidator(String apiName, String schema) { + var standardVersion = STANDARD_VERSION.get(); + var schemaKey = standardVersion + Character.toString(0x1f) + apiName + Character.toString(0x1f) + schema; + var schemaValidator = SCHEMA_CACHE.get(schemaKey); + if (schemaValidator != null) { + return schemaValidator; + } + String schemaFilePath = "/standards/ebl/schemas/ebl-%s-v%s0.json" + .formatted(apiName, standardVersion.charAt(0)); + + schemaValidator = JsonSchemaValidator.getInstance(schemaFilePath, schema); + SCHEMA_CACHE.put(schemaKey, schemaValidator); + return schemaValidator; + } + }