Skip to content

Commit

Permalink
SD-20 Enhancement to OVS Conformance checks (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
preetamnpr authored Nov 13, 2024
1 parent 752b0f8 commit a687faf
Show file tree
Hide file tree
Showing 11 changed files with 900 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.dcsa.conformance.standards.tnt.party;
package org.dcsa.conformance.core.party;

import com.fasterxml.jackson.databind.JsonNode;

Expand All @@ -13,7 +13,8 @@ private CustomJsonPointer() {
// Private constructor to prevent instantiation
}

public static List<JsonNode> findMatchingNodes(JsonNode rootNode, String pathExpression, BiPredicate<JsonNode,String> condition, String paramValue) {
public static List<JsonNode> findMatchingNodes(JsonNode rootNode, String pathExpression,
BiPredicate<JsonNode,String> condition, String paramValue) {
List<JsonNode> results = new ArrayList<>();
String[] pathSegments = pathExpression.split("/");
traverse(rootNode, pathSegments, 0, results, condition, paramValue);
Expand All @@ -28,7 +29,9 @@ public static List<JsonNode> findMatchingNodes(JsonNode rootNode, String pathExp
* @param results The list to store matching JsonNodes.
* @throws IllegalArgumentException If the path expression is invalid or leads to a non-existent node.
*/
public static void traverse(JsonNode currentNode, String[] pathSegments, int segmentIndex, List<JsonNode> results, BiPredicate<JsonNode,String> condition, String paramValue) {
public static void traverse(JsonNode currentNode, String[] pathSegments,
int segmentIndex, List<JsonNode> results,
BiPredicate<JsonNode,String> condition, String paramValue) {

if (segmentIndex == pathSegments.length) {
addNodeIfConditionMatches(currentNode, results, condition, paramValue);
Expand All @@ -44,13 +47,16 @@ public static void traverse(JsonNode currentNode, String[] pathSegments, int seg
}
}

private static void addNodeIfConditionMatches(JsonNode currentNode, List<JsonNode> results, BiPredicate<JsonNode, String> condition, String paramValue) {
private static void addNodeIfConditionMatches(JsonNode currentNode, List<JsonNode> results,
BiPredicate<JsonNode, String> condition, String paramValue) {
if (condition.test(currentNode, paramValue)) {
results.add(currentNode);
}
}

private static void handleWildcardSegment(JsonNode currentNode, String[] pathSegments, int segmentIndex, List<JsonNode> results, BiPredicate<JsonNode, String> condition, String paramValue) {
private static void handleWildcardSegment(JsonNode currentNode, String[] pathSegments,
int segmentIndex, List<JsonNode> results,
BiPredicate<JsonNode, String> condition, String paramValue) {
if (currentNode.isArray()) {
for (JsonNode element : currentNode) {
traverse(element, pathSegments, segmentIndex + 1, results, condition, paramValue);
Expand All @@ -66,7 +72,9 @@ private static void handleWildcardSegment(JsonNode currentNode, String[] pathSeg
}
}

private static void handleRegularSegment(JsonNode currentNode, String[] pathSegments, int segmentIndex, List<JsonNode> results, BiPredicate<JsonNode, String> condition, String paramValue, String segment) {
private static void handleRegularSegment(JsonNode currentNode, String[] pathSegments,
int segmentIndex, List<JsonNode> results,
BiPredicate<JsonNode, String> condition, String paramValue, String segment) {
JsonNode childNode = currentNode.path(segment);
if (!childNode.isMissingNode()) {
traverse(childNode, pathSegments, segmentIndex + 1, results, condition, paramValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,40 +33,80 @@ public static LinkedHashMap<String, OvsScenarioListBuilder> createModuleScenario
"Service schedules",
noAction()
.thenEither(
scenarioWithParameters(CARRIER_SERVICE_CODE),
scenarioWithParameters(CARRIER_SERVICE_CODE, LIMIT),
scenarioWithParameters(UNIVERSAL_SERVICE_REFERENCE),
scenarioWithParameters(UNIVERSAL_SERVICE_REFERENCE, LIMIT))),
scenarioWithParameters(Map.of(CARRIER_SERVICE_NAME, "Great Lion Service")),
scenarioWithParameters(
Map.of(CARRIER_SERVICE_NAME, "Blue Whale Service", LIMIT, "1")),
scenarioWithParameters(
Map.of(
CARRIER_SERVICE_NAME,
"Red Falcon Service",
START_DATE,
"2026-01-01")),
scenarioWithParameters(
Map.of(
CARRIER_SERVICE_NAME,
"Great Lion Service",
END_DATE,
"2021-01-01")),
scenarioWithParameters(Map.of(CARRIER_SERVICE_CODE, "BW1")),
scenarioWithParameters(Map.of(CARRIER_SERVICE_CODE, "BW1", LIMIT, "1")),
scenarioWithParameters(Map.of(UNIVERSAL_SERVICE_REFERENCE, "SR12345A")),
scenarioWithParameters(
Map.of(UNIVERSAL_SERVICE_REFERENCE, "SR67890B", LIMIT, "1")))),
Map.entry(
"Vessel schedules",
noAction()
.thenEither(
scenarioWithParameters(VESSEL_IMO_NUMBER),
scenarioWithParameters(VESSEL_IMO_NUMBER, LIMIT))),
scenarioWithParameters(Map.of(VESSEL_IMO_NUMBER, "9456789")),
scenarioWithParameters(Map.of(VESSEL_IMO_NUMBER, "9876543", LIMIT, "1")))),
Map.entry(
"Location schedules",
noAction()
.thenEither(
scenarioWithParameters(UN_LOCATION_CODE),
scenarioWithParameters(UN_LOCATION_CODE, LIMIT),
scenarioWithParameters(UN_LOCATION_CODE, FACILITY_SMDG_CODE),
scenarioWithParameters(UN_LOCATION_CODE, FACILITY_SMDG_CODE, LIMIT))),
scenarioWithParameters(Map.of(UN_LOCATION_CODE, "NLAMS")),
scenarioWithParameters(Map.of(UN_LOCATION_CODE, "USNYC", LIMIT, "1")),
scenarioWithParameters(Map.of(FACILITY_SMDG_CODE, "APM")),
scenarioWithParameters(Map.of(FACILITY_SMDG_CODE, "APM", LIMIT, "1")))),
Map.entry(
"Voyage schedules",
noAction()
.thenEither(
scenarioWithParameters(CARRIER_VOYAGE_NUMBER, CARRIER_SERVICE_CODE),
scenarioWithParameters(CARRIER_VOYAGE_NUMBER, CARRIER_SERVICE_CODE, LIMIT),
scenarioWithParameters(CARRIER_VOYAGE_NUMBER, UNIVERSAL_SERVICE_REFERENCE),
scenarioWithParameters(
CARRIER_VOYAGE_NUMBER, UNIVERSAL_SERVICE_REFERENCE, LIMIT),
scenarioWithParameters(UNIVERSAL_VOYAGE_REFERENCE, CARRIER_SERVICE_CODE),
Map.of(
CARRIER_VOYAGE_NUMBER, "2104N",
CARRIER_SERVICE_CODE, "BW1")),
scenarioWithParameters(
Map.of(
CARRIER_VOYAGE_NUMBER, "2104S",
CARRIER_SERVICE_CODE, "BW1",
LIMIT, "1")),
scenarioWithParameters(
UNIVERSAL_VOYAGE_REFERENCE, CARRIER_SERVICE_CODE, LIMIT),
Map.of(
CARRIER_VOYAGE_NUMBER, "2103N",
UNIVERSAL_SERVICE_REFERENCE, "SR12345A")),
scenarioWithParameters(
UNIVERSAL_VOYAGE_REFERENCE, UNIVERSAL_SERVICE_REFERENCE),
Map.of(
CARRIER_VOYAGE_NUMBER, "2103S",
UNIVERSAL_SERVICE_REFERENCE, "SR12345A",
LIMIT, "1")),
scenarioWithParameters(
UNIVERSAL_VOYAGE_REFERENCE, UNIVERSAL_SERVICE_REFERENCE, LIMIT))))
Map.of(
UNIVERSAL_VOYAGE_REFERENCE, "2103N",
CARRIER_SERVICE_CODE, "FE1")),
scenarioWithParameters(
Map.of(
UNIVERSAL_VOYAGE_REFERENCE, "2103S",
CARRIER_SERVICE_CODE, "FE1",
LIMIT, "1")),
scenarioWithParameters(
Map.of(
UNIVERSAL_VOYAGE_REFERENCE, "2105N",
UNIVERSAL_SERVICE_REFERENCE, "SR54321C")),
scenarioWithParameters(
Map.of(
UNIVERSAL_VOYAGE_REFERENCE, "2105S",
UNIVERSAL_SERVICE_REFERENCE, "SR54321C",
LIMIT, "1")))))
.collect(
Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Expand All @@ -81,16 +121,15 @@ private static OvsScenarioListBuilder noAction() {
}

private static OvsScenarioListBuilder scenarioWithParameters(
OvsFilterParameter... ovsFilterParameters) {
return supplyScenarioParameters(ovsFilterParameters).then(getSchedules());
Map<OvsFilterParameter, String> parameters) {
return supplyScenarioParameters(parameters).then(getSchedules());
}

private static OvsScenarioListBuilder supplyScenarioParameters(
OvsFilterParameter... ovsFilterParameters) {
Map<OvsFilterParameter, String> parameters) {
String publisherPartyName = threadLocalPublisherPartyName.get();
return new OvsScenarioListBuilder(
previousAction ->
new SupplyScenarioParametersAction(publisherPartyName, ovsFilterParameters));
previousAction -> new SupplyScenarioParametersAction(publisherPartyName, parameters));
}

private static OvsScenarioListBuilder getSchedules() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ private OvsStandard() {

@Override
public SortedMap<String, SortedSet<String>> getScenarioSuitesByStandardVersion() {
return new TreeMap<>(
Map.ofEntries(
Map.entry("3.0.0", new TreeSet<>(Set.of("Conformance")))));
return new TreeMap<>(Map.ofEntries(Map.entry("3.0.0", new TreeSet<>(Set.of("Conformance")))));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.dcsa.conformance.core.check.*;
import org.dcsa.conformance.core.scenario.ConformanceAction;
import org.dcsa.conformance.core.traffic.HttpMessageType;
import org.dcsa.conformance.standards.ovs.checks.OvsChecks;
import org.dcsa.conformance.standards.ovs.checks.QueryParameterSchemaCheck;
import org.dcsa.conformance.standards.ovs.party.OvsRole;

@Getter
Expand Down Expand Up @@ -37,16 +39,35 @@ public ConformanceCheck createCheck(String expectedApiVersion) {
protected Stream<? extends ConformanceCheck> createSubChecks() {
return Stream.of(
new UrlPathCheck(OvsRole::isSubscriber, getMatchedExchangeUuid(), "/service-schedules"),
new ApiHeaderCheck(
OvsRole::isSubscriber,
getMatchedExchangeUuid(),
HttpMessageType.REQUEST,
expectedApiVersion),
new ApiHeaderCheck(
OvsRole::isPublisher,
getMatchedExchangeUuid(),
HttpMessageType.RESPONSE,
expectedApiVersion),
new ResponseStatusCheck(OvsRole::isPublisher, getMatchedExchangeUuid(), expectedStatus),
new QueryParameterSchemaCheck(
"",
"The query parameters of the HTTP request are correct",
OvsRole::isSubscriber,
getMatchedExchangeUuid(),
"/standards/ovs/schemas/OVS_v3.0.0.yaml"),
new JsonSchemaCheck(
OvsRole::isPublisher,
getMatchedExchangeUuid(),
HttpMessageType.RESPONSE,
responseSchemaValidator));
responseSchemaValidator),
OvsChecks.responseContentChecks(
getMatchedExchangeUuid(), expectedApiVersion, sspSupplier));
}
};
}

@Override
public ObjectNode asJsonNode() {
return super.asJsonNode().set("suppliedScenarioParameters", sspSupplier.get().toJson());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,32 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.function.Function;

import java.util.Map;
import java.util.stream.Collectors;

import lombok.Getter;
import org.dcsa.conformance.core.scenario.ConformanceAction;
import org.dcsa.conformance.core.toolkit.JsonToolkit;
import org.dcsa.conformance.standards.ovs.party.OvsFilterParameter;
import org.dcsa.conformance.standards.ovs.party.SuppliedScenarioParameters;

@Getter
public class SupplyScenarioParametersAction extends ConformanceAction {
public class SupplyScenarioParametersAction extends OvsAction {
private SuppliedScenarioParameters suppliedScenarioParameters = null;
private final LinkedHashSet<OvsFilterParameter> ovsFilterParameters;
private final Map<OvsFilterParameter, String> ovsFilterParameterMap;

public SupplyScenarioParametersAction(
String publisherPartyName, OvsFilterParameter... ovsFilterParameters) {
String publisherPartyName, Map<OvsFilterParameter, String> parameters) {
super(
publisherPartyName,
null,
null,
"SupplyScenarioParameters(%s)"
.formatted(
Arrays.stream(ovsFilterParameters)
.map(OvsFilterParameter::getQueryParamName)
.collect(Collectors.joining(", "))));
this.ovsFilterParameters = new LinkedHashSet<>(Arrays.asList(ovsFilterParameters));
parameters.entrySet().stream()
.map(entry -> entry.getKey().getQueryParamName() + "=" + entry.getValue())
.collect(Collectors.joining(", "))),
-1);
this.ovsFilterParameterMap = parameters;
}

@Override
Expand Down Expand Up @@ -60,9 +58,13 @@ public void importJsonState(JsonNode jsonState) {
@Override
public ObjectNode asJsonNode() {
ObjectNode objectNode = super.asJsonNode();
ArrayNode jsonOvsFilterParameters = objectNode.putArray("ovsFilterParametersQueryParamNames");
ovsFilterParameters.forEach(
ovsFilterParameter -> jsonOvsFilterParameters.add(ovsFilterParameter.getQueryParamName()));
ArrayNode jsonOvsFilterParameters = objectNode.putArray("ovsFilterParametersQueryParam");
ovsFilterParameterMap.forEach(
(key, value) -> {
ObjectNode parameterNode = jsonOvsFilterParameters.addObject();
parameterNode.put("parameter", key.getQueryParamName());
parameterNode.put("value", value);
});
return objectNode;
}

Expand All @@ -75,16 +77,8 @@ public String getHumanReadablePrompt() {
@Override
public JsonNode getJsonForHumanReadablePrompt() {
return SuppliedScenarioParameters.fromMap(
ovsFilterParameters.stream()
.collect(
Collectors.toMap(
Function.identity(),
ovsFilterParameter ->
switch (ovsFilterParameter) {
case LIMIT -> "100";
case START_DATE, END_DATE -> LocalDateTime.now().format(JsonToolkit.DEFAULT_DATE_FORMAT);
default -> "TODO";
})))
ovsFilterParameterMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
.toJson();
}

Expand Down
Loading

0 comments on commit a687faf

Please sign in to comment.