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 e9b91dd5..79eb225a 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 @@ -20,7 +20,7 @@ public class EblScenarioListBuilder extends ScenarioListBuilder threadLocalShipperPartyName = new ThreadLocal<>(); private static final String EBL_API = "api"; - private static final String GET_EBL_SCHEMA_NAME = "getShippingInstructions"; + private static final String GET_EBL_SCHEMA_NAME = "ShippingInstructions"; public static EblScenarioListBuilder buildTree( EblComponentFactory componentFactory, String carrierPartyName, String shipperPartyName) { diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java index 48275f87..46dd56e9 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java @@ -32,14 +32,14 @@ public Shipper_GetShippingInstructionsAction( @Override public ObjectNode asJsonNode() { ObjectNode jsonNode = super.asJsonNode(); - jsonNode.put("cbrr", getDspSupplier().get().shippingInstructionsReference()); + jsonNode.put("sir", getDspSupplier().get().shippingInstructionsReference()); return jsonNode; } @Override public String getHumanReadablePrompt() { - return "GET the ebl with CBR '%s'" - .formatted(getDspSupplier().get().transportDocumentReference()); + return "GET the SI with reference '%s'" + .formatted(getDspSupplier().get().shippingInstructionsReference()); } @Override @@ -51,7 +51,7 @@ protected Stream createSubChecks() { new UrlPathCheck( EblRole::isShipper, getMatchedExchangeUuid(), - "/v2/ebls/" + getDspSupplier().get().shippingInstructionsReference()), + "/v2/shipping-instructions/" + getDspSupplier().get().shippingInstructionsReference()), new ResponseStatusCheck( EblRole::isCarrier, getMatchedExchangeUuid(), expectedStatus), new ApiHeaderCheck( diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/CarrierScenarioParameters.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/CarrierScenarioParameters.java index 9305147f..1d941275 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/CarrierScenarioParameters.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/CarrierScenarioParameters.java @@ -4,17 +4,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -public record CarrierScenarioParameters(String carrierServiceName, String vesselIMONumber) { +public record CarrierScenarioParameters(String carrierBookingReference, String commoditySubreference) { public ObjectNode toJson() { return new ObjectMapper() .createObjectNode() - .put("carrierServiceName", carrierServiceName()) - .put("vesselIMONumber", vesselIMONumber()); + .put("carrierBookingReference", carrierBookingReference()) + .put("commoditySubreference", commoditySubreference()); } public static CarrierScenarioParameters fromJson(JsonNode jsonNode) { - ObjectNode cspNode = (ObjectNode) jsonNode; return new CarrierScenarioParameters( - cspNode.get("carrierServiceName").asText(), cspNode.get("vesselIMONumber").asText()); + jsonNode.path("carrierBookingReference").asText(), + jsonNode.path("commoditySubreference").asText() + ); } } diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java index 34e24b2c..7ec9c0fa 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java @@ -15,11 +15,11 @@ import org.dcsa.conformance.core.traffic.ConformanceMessageBody; import org.dcsa.conformance.core.traffic.ConformanceRequest; import org.dcsa.conformance.core.traffic.ConformanceResponse; -import org.dcsa.conformance.standards.ebl.action.*; +import org.dcsa.conformance.standards.ebl.action.Carrier_SupplyScenarioParametersAction; @Slf4j public class EblCarrier extends ConformanceParty { - private final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); public EblCarrier( String apiVersion, @@ -48,7 +48,24 @@ protected void doReset() {} @Override protected Map, Consumer> getActionPromptHandlers() { - return Map.ofEntries(); + return Map.ofEntries( + Map.entry(Carrier_SupplyScenarioParametersAction.class, this::supplyScenarioParameters) + ); + } + + private void supplyScenarioParameters(JsonNode actionPrompt) { + log.info("Carrier.supplyScenarioParameters(%s)".formatted(actionPrompt.toPrettyString())); + CarrierScenarioParameters carrierScenarioParameters = + new CarrierScenarioParameters( + "CARRIER_BOOKING_REFX", + "COMMODITY_SUBREFERENCE_FOR_REFX"); + asyncOrchestratorPostPartyInput( + OBJECT_MAPPER + .createObjectNode() + .put("actionId", actionPrompt.get("actionId").asText()) + .set("input", carrierScenarioParameters.toJson())); + addOperatorLogEntry( + "Provided CarrierScenarioParameters: %s".formatted(carrierScenarioParameters)); } @Override @@ -57,7 +74,7 @@ public ConformanceResponse handleRequest(ConformanceRequest request) { 404, Map.of("Api-Version", List.of(apiVersion)), new ConformanceMessageBody( - objectMapper + OBJECT_MAPPER .createObjectNode() .put("message", "Returning 404 since the request did not match any known URL"))); } diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java index 50c9f3fa..206d792c 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java @@ -15,6 +15,7 @@ import org.dcsa.conformance.core.traffic.ConformanceMessageBody; import org.dcsa.conformance.core.traffic.ConformanceRequest; import org.dcsa.conformance.core.traffic.ConformanceResponse; +import org.dcsa.conformance.standards.ebl.action.Shipper_GetShippingInstructionsAction; @Slf4j public class EblShipper extends ConformanceParty { @@ -52,9 +53,25 @@ protected void doReset() { @Override protected Map, Consumer> getActionPromptHandlers() { - return Map.ofEntries(); + return Map.ofEntries( + Map.entry(Shipper_GetShippingInstructionsAction.class, this::getShippingInstructionsRequest) + ); } + private void getShippingInstructionsRequest(JsonNode actionPrompt) { + log.info("Shipper.getShippingInstructionsRequest(%s)".formatted(actionPrompt.toPrettyString())); + String sir = actionPrompt.get("sir").asText(); + boolean requestAmendment = actionPrompt.path("amendedContent").asBoolean(false); + Map> queryParams = requestAmendment + ? Map.of("amendedContent", List.of("true")) + : Collections.emptyMap(); + + asyncCounterpartGet("/v2/shipping-instructions/" + sir, queryParams); + + addOperatorLogEntry("Sent a GET request for shipping instructions with SIR: %s".formatted(sir)); + } + + @Override public ConformanceResponse handleRequest(ConformanceRequest request) { log.info("Shipper.handleRequest(%s)".formatted(request)); diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/ShippingInstructionsStatus.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/ShippingInstructionsStatus.java index 5bcfcb69..8c98ea80 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/ShippingInstructionsStatus.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/ShippingInstructionsStatus.java @@ -1,31 +1,45 @@ package org.dcsa.conformance.standards.ebl.party; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@RequiredArgsConstructor public enum ShippingInstructionsStatus { - SI_ANY, - SI_START, - SI_RECEIVED, - SI_PENDING_UPDATE, - SI_UPDATE_RECEIVED, - SI_CANCELLED, - SI_DECLINED, - SI_COMPLETED, + SI_ANY(null), + SI_START(null), + SI_RECEIVED("RECEIVED"), + SI_PENDING_UPDATE("PENDING UDPATE"), + SI_UPDATE_RECEIVED("UPDATE RECEIVED"), + SI_CANCELLED("CANCELLED"), + SI_DECLINED("DECLINED"), + SI_COMPLETED("COMPLETED"), ; + private final String wireName; + + private static final Map WIRENAME2STATUS = Arrays.stream(values()) + .filter(ShippingInstructionsStatus::hasWireName) + .collect(Collectors.toMap(ShippingInstructionsStatus::wireName, Function.identity())); + public String wireName() { if (!hasWireName()) { - throw new IllegalArgumentException("State does not have a name visible in any transmission"); + throw new IllegalArgumentException("State " + this.name() + " does not have a name visible in any transmission"); } - return this.name().replace("_", " "); + return wireName; } private boolean hasWireName() { - return this != SI_START; + return wireName != null; } public static ShippingInstructionsStatus fromWireName(String wireName) { - var v = ShippingInstructionsStatus.valueOf(wireName.replace(" ", "_")); - if (!v.hasWireName()) { - throw new IllegalArgumentException("The State does not have a wire name"); + var v = WIRENAME2STATUS.get(wireName); + if (v == null) { + throw new IllegalArgumentException("Unknown SI status or the status does not have a wireName"); } return v; } diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/TransportDocumentStatus.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/TransportDocumentStatus.java index 06b48c60..985d34c7 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/TransportDocumentStatus.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/TransportDocumentStatus.java @@ -1,33 +1,47 @@ package org.dcsa.conformance.standards.ebl.party; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@RequiredArgsConstructor public enum TransportDocumentStatus { - TD_ANY, - TD_START, - TD_DRAFT, - TD_APPROVED, - TD_ISSUED, - TD_PENDING_SURRENDER_FOR_AMENDMENT, - TD_SURRENDERED_FOR_AMENDMENT, - TD_PENDING_SURRENDER_FOR_DELIVERY, - TD_SURRENDERED_FOR_DELIVERY, - TD_VOIDED, + TD_ANY(null), + TD_START(null), + TD_DRAFT("DRAFT"), + TD_APPROVED("APPROVED"), + TD_ISSUED("ISSUED"), + TD_PENDING_SURRENDER_FOR_AMENDMENT("PENDING SURRENDER FOR AMENDMENT"), + TD_SURRENDERED_FOR_AMENDMENT("SURRENDERED FOR AMENDMENT"), + TD_PENDING_SURRENDER_FOR_DELIVERY("PENDING SURRENDER FOR DELIVERY"), + TD_SURRENDERED_FOR_DELIVERY("SURRENDERED FOR DELIVERY"), + TD_VOIDED("VOID"), ; + private final String wireName; + + private static final Map WIRENAME2STATUS = Arrays.stream(values()) + .filter(TransportDocumentStatus::hasWireName) + .collect(Collectors.toMap(TransportDocumentStatus::wireName, Function.identity())); + public String wireName() { if (!hasWireName()) { throw new IllegalArgumentException("State does not have a name visible in any transmission"); } - return this.name().replace("_", " "); + return wireName; } private boolean hasWireName() { - return this != TD_START; + return wireName != null; } public static TransportDocumentStatus fromWireName(String wireName) { - var v = TransportDocumentStatus.valueOf(wireName.replace(" ", "_")); - if (!v.hasWireName()) { - throw new IllegalArgumentException("The State does not have a wire name"); + var v = WIRENAME2STATUS.get(wireName); + if (v == null) { + throw new IllegalArgumentException("Unknown TD status or the status does not have a wireName"); } return v; }