diff --git a/ebl/pom.xml b/ebl/pom.xml index 957e302f..b80fc027 100644 --- a/ebl/pom.xml +++ b/ebl/pom.xml @@ -38,5 +38,11 @@ opencsv 5.9 + + commons-codec + commons-codec + 1.17.1 + compile + diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC6_Carrier_PublishDraftTransportDocumentAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC6_Carrier_PublishDraftTransportDocumentAction.java index c36c48cf..f65dcc17 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC6_Carrier_PublishDraftTransportDocumentAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC6_Carrier_PublishDraftTransportDocumentAction.java @@ -69,6 +69,9 @@ public void handlePartyInput(JsonNode partyInput) throws UserFacingException { @Override public JsonNode getJsonForHumanReadablePrompt() { + if (!skipSI) { + return null; + } return OBJECT_MAPPER.createObjectNode() .put("transportDocumentReference", "Insert TDR here"); } 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 2e3e46e4..ac726bb8 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 @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.net.URI; import java.time.Instant; import java.util.*; import java.util.function.Consumer; @@ -13,6 +14,7 @@ import lombok.SneakyThrows; import lombok.experimental.SuperBuilder; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.dcsa.conformance.core.party.ConformanceParty; import org.dcsa.conformance.core.party.CounterpartConfiguration; import org.dcsa.conformance.core.party.PartyConfiguration; @@ -199,10 +201,11 @@ private void supplyScenarioParameters(JsonNode actionPrompt) { "Fibreboard boxes" ); }; + var json = carrierScenarioParameters.toJson(); asyncOrchestratorPostPartyInput( - actionPrompt.required("actionId").asText(), carrierScenarioParameters.toJson()); + actionPrompt.required("actionId").asText(), json); addOperatorLogEntry( - "Provided CarrierScenarioParameters: %s".formatted(carrierScenarioParameters)); + "Prompt answer for supplyScenarioParameters: %s".formatted(json.toString())); } private void requestUpdateToShippingInstructions(JsonNode actionPrompt) { @@ -283,6 +286,10 @@ private void publishDraftTransportDocument(JsonNode actionPrompt) { si.publishDraftTransportDocument(documentReference, scenarioType); si.save(persistentMap); tdrToSir.put(si.getTransportDocumentReference(), si.getShippingInstructionsReference()); + if (skipSI) { + var json = OBJECT_MAPPER.createObjectNode().put("transportDocumentReference", si.getTransportDocumentReference()); + addOperatorLogEntry("Prompt answer for publishDraftTransportDocument: %s".formatted(json.toString())); + } generateAndEmitNotificationFromTransportDocument(actionPrompt, si, true); addOperatorLogEntry("Published draft transport document '%s'".formatted(si.getTransportDocumentReference())); @@ -700,7 +707,7 @@ private ConformanceResponse _handlePostShippingInstructions(ConformanceRequest r @SneakyThrows private ConformanceResponse _handlePutShippingInstructions(ConformanceRequest request) { - var url = request.url(); + var url = uriContextPath(request.url()); var documentReference = lastUrlSegment(url); var sir = tdrToSir.getOrDefault(documentReference, documentReference); var siData = persistentMap.load(sir); @@ -730,14 +737,19 @@ private ConformanceResponse _handlePutShippingInstructions(ConformanceRequest re ); } + @SneakyThrows + private String uriContextPath(String uri) { + return StringUtils.stripEnd(new URI(uri).getPath(), "/"); + } + @Override public ConformanceResponse handleRequest(ConformanceRequest request) { log.info("Carrier.handleRequest(%s)".formatted(request)); + var url = uriContextPath(request.url()); try { var result = switch (request.method()) { case "GET" -> { - var url = request.url().replaceAll("/++$", ""); var lastSegment = lastUrlSegment(url); var urlStem = url.substring(0, url.length() - lastSegment.length()).replaceAll("/++$", ""); if (urlStem.endsWith("/v3/shipping-instructions")) { @@ -749,14 +761,12 @@ public ConformanceResponse handleRequest(ConformanceRequest request) { yield return404(request); } case "POST" -> { - var url = request.url(); - if (url.endsWith("/v3/shipping-instructions") || url.endsWith("/v3/shipping-instructions/")) { + if (url.endsWith("/v3/shipping-instructions")) { yield _handlePostShippingInstructions(request); } yield return404(request); } case "PATCH" -> { - var url = request.url().replaceAll("/++$", ""); var lastSegment = lastUrlSegment(url); var urlStem = url.substring(0, url.length() - lastSegment.length()).replaceAll("/++$", ""); if (urlStem.endsWith("/v3/shipping-instructions")) { 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 64c918e3..573c7573 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 @@ -4,6 +4,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; @@ -151,7 +154,9 @@ private ObjectNode sendUpdatedShippingInstructions(String sir, String documentRe var siWithoutStatus = si.deepCopy(); siWithoutStatus.remove("shippingInstructionsStatus"); - ConformanceResponse conformanceResponse = syncCounterpartPut("/v3/shipping-instructions/%s".formatted(documentReference), siWithoutStatus); + ConformanceResponse conformanceResponse = syncCounterpartPut("/v3/shipping-instructions/%s".formatted( + URLEncoder.encode(documentReference, StandardCharsets.UTF_8) + ), siWithoutStatus); JsonNode jsonBody = conformanceResponse.message().body().getJsonBody(); String shippingInstructionsStatus = jsonBody.path("shippingInstructionsStatus").asText(); @@ -174,7 +179,7 @@ private void sendCancellationToUpdatedShippingInstructions(String documentRefere .put("updatedShippingInstructionsStatus", ShippingInstructionsStatus.SI_UPDATE_CANCELLED.wireName()); syncCounterpartPatch( - "/v3/shipping-instructions/%s".formatted(documentReference), + "/v3/shipping-instructions/%s".formatted(URLEncoder.encode(documentReference, StandardCharsets.UTF_8)), Collections.emptyMap(), approvePayload); @@ -209,7 +214,7 @@ private void sendApproveDraftTransportDocument(String documentReference) { .put("transportDocumentStatus", TransportDocumentStatus.TD_APPROVED.wireName()); syncCounterpartPatch( - "/v3/transport-documents/%s".formatted(documentReference), + "/v3/transport-documents/%s".formatted(URLEncoder.encode(documentReference, StandardCharsets.UTF_8)), Collections.emptyMap(), approvePayload); } @@ -234,7 +239,7 @@ private void getShippingInstructionsRequest(JsonNode actionPrompt) { ? Map.of("updatedContent", List.of("true")) : Collections.emptyMap(); - syncCounterpartGet("/v3/shipping-instructions/" + documentReference, queryParams); + syncCounterpartGet("/v3/shipping-instructions/" + URLEncoder.encode(documentReference, StandardCharsets.UTF_8), queryParams); addOperatorLogEntry("Sent a GET request for shipping instructions with documentReference: %s".formatted(documentReference)); } @@ -243,7 +248,7 @@ private void getTransportDocument(JsonNode actionPrompt) { log.info("Shipper.getTransportDocument(%s)".formatted(actionPrompt.toPrettyString())); String tdr = actionPrompt.required("tdr").asText(); - syncCounterpartGet("/v3/transport-documents/" + tdr, Collections.emptyMap()); + syncCounterpartGet("/v3/transport-documents/" + URLEncoder.encode(tdr, StandardCharsets.UTF_8), Collections.emptyMap()); addOperatorLogEntry("Sent a GET request for transport document with TDR: %s".formatted(tdr)); }