Skip to content

Commit

Permalink
SD-1823 reverted core changes by implementing the wrapper method.
Browse files Browse the repository at this point in the history
  • Loading branch information
preetamnpr committed Dec 4, 2024
1 parent d0ebefe commit a75e892
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
import java.util.function.Predicate;
import java.util.stream.Stream;

import lombok.Getter;
import lombok.NonNull;
import org.dcsa.conformance.core.traffic.ConformanceExchange;
import org.dcsa.conformance.core.traffic.HttpMessageType;


public class JsonAttributeBasedCheck extends ActionCheck {
class JsonAttributeBasedCheck extends ActionCheck {

private final String standardsVersion;
@Getter private final List<JsonContentCheck> validators;
private final List<JsonContentCheck> validators;

JsonAttributeBasedCheck(
String titlePrefix,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,99 +26,99 @@
@UtilityClass
public class OvsChecks {

public static ActionCheck responseContentChecks(
UUID matched, String standardVersion, Supplier<SuppliedScenarioParameters> sspSupplier) {

public List<JsonContentCheck> buildResponseContentChecks(Map<OvsFilterParameter, String> filterParametersMap) {
var checks = new ArrayList<JsonContentCheck>();

checks.add(
JsonAttribute.customValidator(
"Every response received during a conformance test must contain schedules",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
checkServiceSchedulesExist(body)
.forEach(
validationError ->
validationErrors.add(
"CheckServiceSchedules failed: %s".formatted(validationError)));
if (validationErrors.isEmpty()) {
return Set.of();
}
return validationErrors;
}));
JsonAttribute.customValidator(
"Every response received during a conformance test must contain schedules",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
checkServiceSchedulesExist(body)
.forEach(
validationError ->
validationErrors.add(
"CheckServiceSchedules failed: %s".formatted(validationError)));
if (validationErrors.isEmpty()) {
return Set.of();
}
return validationErrors;
}));

checks.add(
JsonAttribute.customValidator(
"If present, at least schedule attribute must match the corresponding query parameters",
body -> {
Map<OvsFilterParameter, String> filterParametersMap = sspSupplier.get().getMap();
Set<String> validationErrors = new LinkedHashSet<>();
checkThatScheduleValuesMatchParamValues(body, filterParametersMap)
.forEach(
validationError ->
validationErrors.add(
"Schedule Param Value Validation failed: %s"
.formatted(validationError)));
return validationErrors;
}));
JsonAttribute.customValidator(
"If present, at least one schedule attribute must match the corresponding query parameters",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
checkThatScheduleValuesMatchParamValues(body, filterParametersMap)
.forEach(
validationError ->
validationErrors.add(
"Schedule Param Value Validation failed: %s"
.formatted(validationError)));
return validationErrors;
}));

checks.add(
JsonAttribute.customValidator(
"Check eventDateTime is greater than startDate filter parameter if present",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
Map<OvsFilterParameter, String> filterParametersMap = sspSupplier.get().getMap();
validateDate(
body, filterParametersMap, OvsFilterParameter.START_DATE, LocalDate::isBefore)
.forEach(
validationError ->
validationErrors.add(
"Start Date EventDateTime validation failed: %s"
.formatted(validationError)));
return validationErrors;
}));
JsonAttribute.customValidator(
"Check eventDateTime is greater than startDate filter parameter if present",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
validateDate(
body, filterParametersMap, OvsFilterParameter.START_DATE, LocalDate::isBefore)
.forEach(
validationError ->
validationErrors.add(
"Start Date EventDateTime validation failed: %s"
.formatted(validationError)));
return validationErrors;
}));

checks.add(
JsonAttribute.customValidator(
"Check eventDateTime is less than endDate filter parameter if present",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
Map<OvsFilterParameter, String> filterParametersMap = sspSupplier.get().getMap();
validateDate(
body, filterParametersMap, OvsFilterParameter.END_DATE, LocalDate::isAfter)
.forEach(
validationError ->
validationErrors.add(
"EndDate EventDateTime validation failed: %s"
.formatted(validationError)));
return validationErrors;
}));
JsonAttribute.customValidator(
"Check eventDateTime is less than endDate filter parameter if present",
body -> {
Set<String> validationErrors = new LinkedHashSet<>();
validateDate(
body, filterParametersMap, OvsFilterParameter.END_DATE, LocalDate::isAfter)
.forEach(
validationError ->
validationErrors.add(
"EndDate EventDateTime validation failed: %s"
.formatted(validationError)));
return validationErrors;
}));

checks.add(
JsonAttribute.customValidator(
"Check transportCallReference is unique across each service schedules",
OvsChecks::validateUniqueTransportCallReference));
JsonAttribute.customValidator(
"Check transportCallReference is unique across each service schedules",
OvsChecks::validateUniqueTransportCallReference));

checks.add(
JsonAttribute.customValidator(
"Validate limit exists and the number of schedules does not exceed the limit",
body -> {
Optional<Map.Entry<OvsFilterParameter, String>> limitParam =
sspSupplier.get().getMap().entrySet().stream()
.filter(e -> e.getKey().equals(OvsFilterParameter.LIMIT))
.findFirst();
JsonAttribute.customValidator(
"Validate limit exists and the number of schedules does not exceed the limit",
body -> {
Optional<Map.Entry<OvsFilterParameter, String>> limitParam =
filterParametersMap.entrySet().stream()
.filter(e -> e.getKey().equals(OvsFilterParameter.LIMIT))
.findFirst();

if (limitParam.isPresent()) {
int expectedLimit = Integer.parseInt(limitParam.get().getValue().trim());
if (body.size() > expectedLimit) {
return Set.of(
"The number of service schedules exceeds the limit parameter: "
+ expectedLimit);
}
}
return Set.of();
}));
if (limitParam.isPresent()) {
int expectedLimit = Integer.parseInt(limitParam.get().getValue().trim());
if (body.size() > expectedLimit) {
return Set.of(
"The number of service schedules exceeds the limit parameter: "
+ expectedLimit);
}
}
return Set.of();
}));
return checks;
}

public static ActionCheck responseContentChecks(
UUID matched, String standardVersion, Supplier<SuppliedScenarioParameters> sspSupplier) {
Map<OvsFilterParameter, String> filterParametersMap = sspSupplier.get().getMap();
var checks = buildResponseContentChecks(filterParametersMap);
return JsonAttribute.contentChecks(
OvsRole::isPublisher, matched, HttpMessageType.RESPONSE, standardVersion, checks);
}
Expand Down Expand Up @@ -302,9 +302,9 @@ private Stream<Map.Entry<String, JsonNode>> findMatchingNodes(
}

public Set<String> checkServiceSchedulesExist(JsonNode body) {
Set<String> validationErrors = new LinkedHashSet<>();

if (body == null || body.isMissingNode() || body.isNull()) {
validationErrors.add("Response body is missing or null.");
return Set.of("Response body is missing or null.");
} else {
boolean hasVesselSchedules =
findMatchingNodes(body, "*/vesselSchedules")
Expand All @@ -314,9 +314,9 @@ public Set<String> checkServiceSchedulesExist(JsonNode body) {
&& node.getValue().isArray()
&& !node.getValue().isEmpty());
if (!hasVesselSchedules) {
validationErrors.add("Response doesn't have schedules.");
return Set.of("Response doesn't have schedules.");
}
}
return validationErrors;
return Set.of();
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
package org.dcsa.conformance.standards.ovs;
package org.dcsa.conformance.standards.ovs.checks;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.dcsa.conformance.core.check.ActionCheck;
import org.dcsa.conformance.core.check.JsonAttributeBasedCheck;
import org.dcsa.conformance.core.toolkit.JsonToolkit;
import org.dcsa.conformance.standards.ovs.checks.OvsChecks;
import org.dcsa.conformance.standards.ovs.party.OvsFilterParameter;
import org.dcsa.conformance.standards.ovs.party.SuppliedScenarioParameters;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;

public class OvsChecksTest {
import static org.dcsa.conformance.core.toolkit.JsonToolkit.OBJECT_MAPPER;
import static org.junit.jupiter.api.Assertions.*;

private final ObjectMapper objectMapper = new ObjectMapper();
class OvsChecksTest {

private JsonNode serviceNodes;

Expand Down Expand Up @@ -73,16 +68,9 @@ void testResponseContentChecks_withWrongStructureResponse() {

private Set<String> executeResponseChecks(
Map<OvsFilterParameter, String> ovsFilterParameterStringMap, JsonNode serviceNodes) {
UUID matchedId = UUID.randomUUID();
String standardVersion = "3.0.0";
Supplier<SuppliedScenarioParameters> sspSupplier =
() -> SuppliedScenarioParameters.fromMap(ovsFilterParameterStringMap);
Set<String> issues = new HashSet<>();

ActionCheck actionCheck =
OvsChecks.responseContentChecks(matchedId, standardVersion, sspSupplier);
((JsonAttributeBasedCheck) actionCheck)
.getValidators()
OvsChecks.buildResponseContentChecks(ovsFilterParameterStringMap)
.forEach(
validator -> {
issues.addAll(validator.validate(serviceNodes));
Expand Down Expand Up @@ -325,7 +313,7 @@ void testValidateUniqueTransportCallReference_duplicate() {
JsonNode transportCalls = vesselSchedules.get(0).get("transportCalls");

ObjectNode newTransportCall =
new ObjectMapper().createObjectNode().put("transportCallReference", "TCREF1");
OBJECT_MAPPER.createObjectNode().put("transportCallReference", "TCREF1");
((ArrayNode) transportCalls).add(newTransportCall);

Set<String> result = OvsChecks.validateUniqueTransportCallReference(serviceNodes);
Expand All @@ -342,30 +330,30 @@ void testValidateUniqueTransportCallReference_noVesselSchedules() {

@Test
void testFindMatchingNodes_rootMatch() {
JsonNode root = objectMapper.createObjectNode().put("value", "test");
JsonNode root = OBJECT_MAPPER.createObjectNode().put("value", "test");
Stream<JsonNode> result = OvsChecks.findMatchingNodes(root, "/").map(Map.Entry::getValue);
assertEquals(1, result.count());
}

@Test
void testFindMatchingNodes_arrayMatch() throws IOException {
JsonNode root = objectMapper.readTree("[{\"a\": 1}, {\"b\": 2}]");
JsonNode root = OBJECT_MAPPER.readTree("[{\"a\": 1}, {\"b\": 2}]");
Stream<JsonNode> result = OvsChecks.findMatchingNodes(root, "*").map(Map.Entry::getValue);
;
assertEquals(2, result.count());
}

@Test
void testFindMatchingNodes_emptyArrayMatch() throws IOException {
JsonNode root = objectMapper.readTree("[]");
JsonNode root = OBJECT_MAPPER.readTree("[]");
Stream<JsonNode> result = OvsChecks.findMatchingNodes(root, "*").map(Map.Entry::getValue);
;
assertEquals(0, result.count());
}

@Test
void testCheckServiceSchedulesExist_emptyServiceSchedules() {
JsonNode body = objectMapper.createArrayNode();
JsonNode body = OBJECT_MAPPER.createArrayNode();
Set<String> result = OvsChecks.checkServiceSchedulesExist(body);
assertEquals(1, result.size());
}
Expand All @@ -390,7 +378,7 @@ void testValidateDate_invalidDateFormat() {
.get("timestamps");

ObjectNode invalidTimeStamp =
new ObjectMapper().createObjectNode().put("eventDateTime", "TCREF1");
OBJECT_MAPPER.createObjectNode().put("eventDateTime", "TCREF1");
((ArrayNode) timeStamps).add(invalidTimeStamp);

Set<String> result =
Expand All @@ -405,13 +393,12 @@ private JsonNode createServiceNodes(
String carrierServiceCode,
String universalServiceReference,
JsonNode vesselSchedules) {
ObjectMapper objectMapper = new ObjectMapper();

// Create the root ArrayNode
ArrayNode rootArrayNode = objectMapper.createArrayNode();
ArrayNode rootArrayNode = OBJECT_MAPPER.createArrayNode();

// Create the first ObjectNode
ObjectNode firstObjectNode = objectMapper.createObjectNode();
ObjectNode firstObjectNode = OBJECT_MAPPER.createObjectNode();
firstObjectNode.put("carrierServiceName", carrierServiceName);
firstObjectNode.put("carrierServiceCode", carrierServiceCode);
firstObjectNode.put("universalServiceReference", universalServiceReference);
Expand All @@ -422,8 +409,8 @@ private JsonNode createServiceNodes(
}

private JsonNode createServiceVesselSchedules(String vesselIMONumber, String vesselName) {
ArrayNode vesselSchedulesArrayNode = objectMapper.createArrayNode();
ObjectNode vesselSchedule = objectMapper.createObjectNode();
ArrayNode vesselSchedulesArrayNode = OBJECT_MAPPER.createArrayNode();
ObjectNode vesselSchedule = OBJECT_MAPPER.createObjectNode();
vesselSchedule.put("vesselIMONumber", vesselIMONumber);
vesselSchedule.put("vesselName", vesselName);
vesselSchedule.set(
Expand All @@ -441,16 +428,16 @@ private JsonNode createTransportCalls(
String universalExportVoyageReference,
String UNLocationCode) {
// Create the transportCalls ArrayNode for the vesselSchedule
ArrayNode transportCallsArrayNode = objectMapper.createArrayNode();
ObjectNode transportCall = objectMapper.createObjectNode();
ArrayNode transportCallsArrayNode = OBJECT_MAPPER.createArrayNode();
ObjectNode transportCall = OBJECT_MAPPER.createObjectNode();
transportCall.put("transportCallReference", transportCallReference);
transportCall.put("carrierImportVoyageNumber", carrierImportVoyageNumber);
transportCall.put("carrierExportVoyageNumber", carrierExportVoyageNumber);
transportCall.put("universalImportVoyageReference", universalImportVoyageReference);
transportCall.put("universalExportVoyageReference", universalExportVoyageReference);

// Create the location ObjectNode for the first transportCall
ObjectNode location = objectMapper.createObjectNode();
ObjectNode location = OBJECT_MAPPER.createObjectNode();
location.put("UNLocationCode", UNLocationCode);
transportCall.set("location", location);
transportCall.set("timestamps", createTimestamps());
Expand All @@ -460,7 +447,7 @@ private JsonNode createTransportCalls(

private JsonNode createEventDateTime(String eventDateTime) {
// Create a timestamp for timestamps ArrayNode
ObjectNode timestamp = objectMapper.createObjectNode();
ObjectNode timestamp = OBJECT_MAPPER.createObjectNode();
timestamp.put("eventTypeCode", "ARRI");
timestamp.put("eventClassifierCode", "PLN");
timestamp.put("eventDateTime", eventDateTime);
Expand All @@ -469,7 +456,7 @@ private JsonNode createEventDateTime(String eventDateTime) {

private JsonNode createTimestamps() {
// Create the timestamps ArrayNode
ArrayNode timestampsArrayNode = objectMapper.createArrayNode();
ArrayNode timestampsArrayNode = OBJECT_MAPPER.createArrayNode();
timestampsArrayNode.add(createEventDateTime("2024-07-21T10:00:00Z"));
timestampsArrayNode.add(createEventDateTime("2024-07-22T10:00:00Z"));
timestampsArrayNode.add(createEventDateTime("2024-07-23T10:00:00Z"));
Expand Down

0 comments on commit a75e892

Please sign in to comment.