From 9831c53b2aa624132fb8449b3dfc782d5df9e385 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Fri, 17 Nov 2023 12:20:22 +0100 Subject: [PATCH 1/3] DT-622: Add UC10 Decline entire booking Signed-off-by: Niels Thykier --- .../booking/BookingScenarioListBuilder.java | 18 ++++- .../UC10_Carrier_RejectBookingAction.java | 66 +++++++++++++++++++ ...ookingPayloadResponseConformanceCheck.java | 4 +- .../standards/booking/party/Carrier.java | 19 ++++++ 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 booking/src/main/java/org/dcsa/conformance/standards/booking/action/UC10_Carrier_RejectBookingAction.java diff --git a/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java b/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java index 72f5bb3e..3eb4b92f 100644 --- a/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java +++ b/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java @@ -32,9 +32,11 @@ public static BookingScenarioListBuilder buildTree( uc5_carrier_confirmBookingRequest() .then( shipper_GetBooking(CONFIRMED) - .then( + .thenEither( uc11_carrier_confirmBookingCompleted() - .then(shipper_GetBooking(COMPLETED)))), + .then(shipper_GetBooking(COMPLETED)), + uc10_carrier_declineBooking() + .then(shipper_GetBooking(DECLINED)))), uc4_carrier_rejectBookingRequest() .then(shipper_GetBooking(REJECTED)), uc2_carrier_requestUpdateToBookingRequest() @@ -235,7 +237,17 @@ private static BookingScenarioListBuilder uc9_shipper_cancelBookingAmendment() { } private static BookingScenarioListBuilder uc10_carrier_declineBooking() { - return tbdCarrierAction(); + BookingComponentFactory componentFactory = threadLocalComponentFactory.get(); + String carrierPartyName = threadLocalCarrierPartyName.get(); + String shipperPartyName = threadLocalShipperPartyName.get(); + return new BookingScenarioListBuilder( + previousAction -> + new UC10_Carrier_RejectBookingAction( + carrierPartyName, + shipperPartyName, + (BookingAction) previousAction, + componentFactory.getMessageSchemaValidator( + BookingRole.CARRIER.getConfigName(), true))); } private static BookingScenarioListBuilder uc11_carrier_confirmBookingCompleted() { diff --git a/booking/src/main/java/org/dcsa/conformance/standards/booking/action/UC10_Carrier_RejectBookingAction.java b/booking/src/main/java/org/dcsa/conformance/standards/booking/action/UC10_Carrier_RejectBookingAction.java new file mode 100644 index 00000000..c3c9c98f --- /dev/null +++ b/booking/src/main/java/org/dcsa/conformance/standards/booking/action/UC10_Carrier_RejectBookingAction.java @@ -0,0 +1,66 @@ +package org.dcsa.conformance.standards.booking.action; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.Getter; +import org.dcsa.conformance.core.check.*; +import org.dcsa.conformance.core.traffic.HttpMessageType; +import org.dcsa.conformance.standards.booking.party.BookingRole; + +import java.util.stream.Stream; + +@Getter +public class UC10_Carrier_RejectBookingAction extends BookingAction { + private final JsonSchemaValidator requestSchemaValidator; + + public UC10_Carrier_RejectBookingAction( + String carrierPartyName, + String shipperPartyName, + BookingAction previousAction, + JsonSchemaValidator requestSchemaValidator) { + super(carrierPartyName, shipperPartyName, previousAction, "UC10", 204); + this.requestSchemaValidator = requestSchemaValidator; + } + + @Override + public String getHumanReadablePrompt() { + return ("UC10: Reject the booking request with CBR %s" + .formatted(getDspSupplier().get().carrierBookingReference())); + } + + @Override + public ObjectNode asJsonNode() { + ObjectNode jsonNode = super.asJsonNode(); + var dsp = getDspSupplier().get(); + return jsonNode.put("cbr", dsp.carrierBookingReference()) + .put("cbrr", dsp.carrierBookingRequestReference() ); + } + + @Override + public ConformanceCheck createCheck(String expectedApiVersion) { + return new ConformanceCheck(getActionTitle()) { + @Override + protected Stream createSubChecks() { + return Stream.of( + new UrlPathCheck( + BookingRole::isCarrier, getMatchedExchangeUuid(), "/v2/booking-notifications"), + new ResponseStatusCheck( + BookingRole::isShipper, getMatchedExchangeUuid(), expectedStatus), + new ApiHeaderCheck( + BookingRole::isCarrier, + getMatchedExchangeUuid(), + HttpMessageType.REQUEST, + expectedApiVersion), + new ApiHeaderCheck( + BookingRole::isShipper, + getMatchedExchangeUuid(), + HttpMessageType.RESPONSE, + expectedApiVersion), + new JsonSchemaCheck( + BookingRole::isCarrier, + getMatchedExchangeUuid(), + HttpMessageType.REQUEST, + requestSchemaValidator)); + } + }; + } +} diff --git a/booking/src/main/java/org/dcsa/conformance/standards/booking/checks/CarrierGetBookingPayloadResponseConformanceCheck.java b/booking/src/main/java/org/dcsa/conformance/standards/booking/checks/CarrierGetBookingPayloadResponseConformanceCheck.java index 9bf15883..74889ac6 100644 --- a/booking/src/main/java/org/dcsa/conformance/standards/booking/checks/CarrierGetBookingPayloadResponseConformanceCheck.java +++ b/booking/src/main/java/org/dcsa/conformance/standards/booking/checks/CarrierGetBookingPayloadResponseConformanceCheck.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; -import com.fasterxml.jackson.databind.node.ValueNode; import org.dcsa.conformance.core.check.ActionCheck; import org.dcsa.conformance.core.check.ConformanceCheck; import org.dcsa.conformance.core.traffic.ConformanceExchange; @@ -25,7 +24,8 @@ public class CarrierGetBookingPayloadResponseConformanceCheck extends ActionChec private static final Set CONFIRMED_BOOKING_STATES = Set.of( BookingState.CONFIRMED, - BookingState.COMPLETED + BookingState.COMPLETED, + BookingState.DECLINED ); private static final Set MANDATORY_ON_CONFIRMED_BOOKING = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList( diff --git a/booking/src/main/java/org/dcsa/conformance/standards/booking/party/Carrier.java b/booking/src/main/java/org/dcsa/conformance/standards/booking/party/Carrier.java index aaaa7ee3..2fa632ba 100644 --- a/booking/src/main/java/org/dcsa/conformance/standards/booking/party/Carrier.java +++ b/booking/src/main/java/org/dcsa/conformance/standards/booking/party/Carrier.java @@ -71,6 +71,7 @@ protected Map, Consumer> getActionP Map.entry(UC2_Carrier_RequestUpdateToBookingRequestAction.class, this::requestUpdateToBookingRequest), Map.entry(UC4_Carrier_RejectBookingRequestAction.class, this::rejectBookingRequest), Map.entry(UC5_Carrier_ConfirmBookingRequestAction.class, this::confirmBookingRequest), + Map.entry(UC10_Carrier_RejectBookingAction.class, this::declineBooking), Map.entry(UC11_Carrier_ConfirmBookingCompletedAction.class, this::confirmBookingCompleted)); } @@ -157,6 +158,23 @@ private void rejectBookingRequest(JsonNode actionPrompt) { addOperatorLogEntry("Rejected the booking request with CBRR '%s'".formatted(cbrr)); } + private void declineBooking(JsonNode actionPrompt) { + log.info("Carrier.declineBooking(%s)".formatted(actionPrompt.toPrettyString())); + + String cbr = actionPrompt.get("cbr").asText(); + + processAndEmitNotificationForStateTransition( + actionPrompt, + BookingState.DECLINED, + Set.of( + BookingState.CONFIRMED, + BookingState.PENDING_AMENDMENT, + BookingState.PENDING_AMENDMENT_APPROVAL), + ReferenceState.PROVIDE_IF_EXIST, + false); + addOperatorLogEntry("Declined the booking with CBR '%s'".formatted(cbr)); + } + private void requestUpdateToBookingRequest(JsonNode actionPrompt) { log.info("Carrier.rejectBookingRequest(%s)".formatted(actionPrompt.toPrettyString())); @@ -204,6 +222,7 @@ private void processAndEmitNotificationForStateTransition( null ); } + private void processAndEmitNotificationForStateTransition( JsonNode actionPrompt, BookingState targetState, From e2cf68e3bbf24838272ed907406edc07d0492d03 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Fri, 17 Nov 2023 12:27:32 +0100 Subject: [PATCH 2/3] BookingScenarioListBuilder: Refactor some code for carrier use cases Signed-off-by: Niels Thykier --- .../booking/BookingScenarioListBuilder.java | 69 ++++++------------- 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java b/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java index 3eb4b92f..00124106 100644 --- a/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java +++ b/booking/src/main/java/org/dcsa/conformance/standards/booking/BookingScenarioListBuilder.java @@ -4,6 +4,7 @@ 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.booking.action.*; @@ -170,18 +171,23 @@ private static BookingScenarioListBuilder uc1_shipper_SubmitBookingRequest() { BookingRole.SHIPPER.getConfigName(), true))); } - private static BookingScenarioListBuilder uc2_carrier_requestUpdateToBookingRequest() { + private static BookingScenarioListBuilder carrierStateChange(CarrierNotificationUseCase constructor) { BookingComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); return new BookingScenarioListBuilder( previousAction -> - new UC2_Carrier_RequestUpdateToBookingRequestAction( + constructor.newInstance( carrierPartyName, shipperPartyName, (BookingAction) previousAction, componentFactory.getMessageSchemaValidator( - BookingRole.CARRIER.getConfigName(), true))); + BookingRole.CARRIER.getConfigName(), true)) + ); + } + + private static BookingScenarioListBuilder uc2_carrier_requestUpdateToBookingRequest() { + return carrierStateChange(UC2_Carrier_RequestUpdateToBookingRequestAction::new); } private static BookingScenarioListBuilder uc3_shipper_submitUpdatedBookingRequest() { @@ -189,31 +195,11 @@ private static BookingScenarioListBuilder uc3_shipper_submitUpdatedBookingReques } private static BookingScenarioListBuilder uc4_carrier_rejectBookingRequest() { - BookingComponentFactory componentFactory = threadLocalComponentFactory.get(); - String carrierPartyName = threadLocalCarrierPartyName.get(); - String shipperPartyName = threadLocalShipperPartyName.get(); - return new BookingScenarioListBuilder( - previousAction -> - new UC4_Carrier_RejectBookingRequestAction( - carrierPartyName, - shipperPartyName, - (BookingAction) previousAction, - componentFactory.getMessageSchemaValidator( - BookingRole.CARRIER.getConfigName(), true))); + return carrierStateChange(UC4_Carrier_RejectBookingRequestAction::new); } private static BookingScenarioListBuilder uc5_carrier_confirmBookingRequest() { - BookingComponentFactory componentFactory = threadLocalComponentFactory.get(); - String carrierPartyName = threadLocalCarrierPartyName.get(); - String shipperPartyName = threadLocalShipperPartyName.get(); - return new BookingScenarioListBuilder( - previousAction -> - new UC5_Carrier_ConfirmBookingRequestAction( - carrierPartyName, - shipperPartyName, - (BookingAction) previousAction, - componentFactory.getMessageSchemaValidator( - BookingRole.CARRIER.getConfigName(), true))); + return carrierStateChange(UC5_Carrier_ConfirmBookingRequestAction::new); } private static BookingScenarioListBuilder uc6_carrier_requestBookingAmendment() { @@ -237,31 +223,11 @@ private static BookingScenarioListBuilder uc9_shipper_cancelBookingAmendment() { } private static BookingScenarioListBuilder uc10_carrier_declineBooking() { - BookingComponentFactory componentFactory = threadLocalComponentFactory.get(); - String carrierPartyName = threadLocalCarrierPartyName.get(); - String shipperPartyName = threadLocalShipperPartyName.get(); - return new BookingScenarioListBuilder( - previousAction -> - new UC10_Carrier_RejectBookingAction( - carrierPartyName, - shipperPartyName, - (BookingAction) previousAction, - componentFactory.getMessageSchemaValidator( - BookingRole.CARRIER.getConfigName(), true))); + return carrierStateChange(UC10_Carrier_RejectBookingAction::new); } private static BookingScenarioListBuilder uc11_carrier_confirmBookingCompleted() { - BookingComponentFactory componentFactory = threadLocalComponentFactory.get(); - String carrierPartyName = threadLocalCarrierPartyName.get(); - String shipperPartyName = threadLocalShipperPartyName.get(); - return new BookingScenarioListBuilder( - previousAction -> - new UC11_Carrier_ConfirmBookingCompletedAction( - carrierPartyName, - shipperPartyName, - (BookingAction) previousAction, - componentFactory.getMessageSchemaValidator( - BookingRole.CARRIER.getConfigName(), true))); + return carrierStateChange(UC11_Carrier_ConfirmBookingCompletedAction::new); } private static BookingScenarioListBuilder uc12_shipper_cancelBooking() { @@ -303,4 +269,13 @@ public String getHumanReadablePrompt() { } }) {}; } + + private interface CarrierNotificationUseCase { + BookingAction newInstance( + String carrierPartyName, + String shipperPartyName, + BookingAction previousAction, + JsonSchemaValidator requestSchemaValidator + ); + } } From 524d620c1701154eb994482005d0f333a6fa7be1 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Fri, 17 Nov 2023 12:31:01 +0100 Subject: [PATCH 3/3] Run CI for dev, test and master Signed-off-by: Niels Thykier --- .github/workflows/master.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index d4bb9cca..c6c06198 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -5,8 +5,13 @@ on: push: branches: - dev + - test + - master pull_request: - branches: [ "dev" ] + branches: + - dev + - test + - master jobs: build: