Skip to content

Commit

Permalink
Add extra validation for the confirmed booking
Browse files Browse the repository at this point in the history
Signed-off-by: Niels Thykier <[email protected]>
  • Loading branch information
nt-gt committed Nov 15, 2023
1 parent 822cea0 commit e17d4d6
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
import org.dcsa.conformance.core.toolkit.JsonToolkit;
import org.dcsa.conformance.core.traffic.ConformanceExchange;
import org.dcsa.conformance.core.traffic.HttpMessageType;
import org.dcsa.conformance.standards.booking.checks.BookingPayloadResponseConformanceCheck;
import org.dcsa.conformance.standards.booking.party.BookingRole;
import org.dcsa.conformance.standards.booking.party.BookingState;

public class Shipper_GetBookingAction extends BookingAction {

private final BookingState expectedState;
private final JsonSchemaValidator responseSchemaValidator;

Expand Down Expand Up @@ -67,6 +69,10 @@ protected Stream<? extends ConformanceCheck> createSubChecks() {
getMatchedExchangeUuid(),
HttpMessageType.REQUEST,
responseSchemaValidator),
new BookingPayloadResponseConformanceCheck(
getMatchedExchangeUuid(),
expectedState
),
new ActionCheck(
"GET returns the expected Booking data",
BookingRole::isCarrier,
Expand All @@ -77,20 +83,7 @@ protected Set<String> checkConformance(
Function<UUID, ConformanceExchange> getExchangeByUuid) {
ConformanceExchange getExchange = getExchangeByUuid.apply(getMatchedExchangeUuid());
if (getExchange == null) return Set.of();
String exchangeState =
getExchange
.getResponse()
.message()
.body()
.getJsonBody()
.get("bookingStatus")
.asText();
Set<String> conformanceErrors = new HashSet<>();
if (!Objects.equals(exchangeState, expectedState.wireName())) {
conformanceErrors.add(
"Expected bookingStatus '%s' but found '%s'"
.formatted(expectedState.wireName(), exchangeState));
}
if (previousAction
instanceof UC1_Shipper_SubmitBookingRequestAction submitBookingRequestAction) {
ConformanceExchange submitBookingRequestExchange =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.dcsa.conformance.standards.booking.checks;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.TextNode;
import org.dcsa.conformance.core.check.ActionCheck;
import org.dcsa.conformance.core.traffic.ConformanceExchange;
import org.dcsa.conformance.core.traffic.HttpMessageType;
import org.dcsa.conformance.standards.booking.party.BookingRole;
import org.dcsa.conformance.standards.booking.party.BookingState;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;

public class BookingPayloadResponseConformanceCheck extends ActionCheck {

private static final Set<BookingState> CONFIRMED_BOOKING_STATES = Set.of(
BookingState.CONFIRMED,
BookingState.COMPLETED
);

private final BookingState expectedState;

public BookingPayloadResponseConformanceCheck(UUID matchedExchangeUuid, BookingState bookingState) {
super(
"Validate the carrier response",
BookingRole::isCarrier,
matchedExchangeUuid,
HttpMessageType.RESPONSE
);
this.expectedState = bookingState;
}

@Override
protected Set<String> checkConformance(Function<UUID, ConformanceExchange> getExchangeByUuid) {
ConformanceExchange exchange = getExchangeByUuid.apply(matchedExchangeUuid);
if (exchange == null) return Collections.emptySet();
var responsePayload =
exchange
.getResponse()
.message()
.body()
.getJsonBody();
if (responsePayload == null) {
return Collections.emptySet();
}
var conformanceIssues = new LinkedHashSet<String>();
ensureBookingStateIsCorrect(responsePayload, conformanceIssues::add);
if (CONFIRMED_BOOKING_STATES.contains(this.expectedState)) {
nonEmptyList(responsePayload, "transportPlan", conformanceIssues::add);
nonEmptyList(responsePayload, "shipmentCutOffTimes", conformanceIssues::add);
}
return Set.copyOf(conformanceIssues);
}

private void ensureBookingStateIsCorrect(JsonNode responsePayload, Consumer<String> setAdd) {
String actualState = null;
if (responsePayload.get("bookingStatus") instanceof TextNode statusNode) {
actualState = statusNode.asText();
if (actualState.equals(this.expectedState.wireName())) {
return;
}
}
setAdd.accept("Expected bookingStatus '%s' but found '%s'"
.formatted(expectedState.wireName(), actualState));
}

private void nonEmptyList(JsonNode responsePayload, String key, Consumer<String> setAdd) {
var field = responsePayload.get(key);
if (field instanceof ArrayNode array && !array.isEmpty()) {
return;
}
setAdd.accept("The field " + key + " must be a present and a non-empty list for a confirmed booking");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,13 @@ private void processAndEmitNotificationForStateTransition(
}

if (isCorrect) {
var booking = (ObjectNode)persistentMap.load(cbrr);
bookingStatesByCbrr.put(cbrr, targetState);

if (booking != null) {
booking.put("bookingStatus", targetState.wireName());
persistentMap.save(cbrr, booking);
}
switch (cbrHandling) {
case MUST_EXIST -> {
if (cbr == null) {
Expand Down

0 comments on commit e17d4d6

Please sign in to comment.