Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DT-271: Add scenario for receiver validation #186

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class PintScenarioListBuilder extends ScenarioListBuilder<PintScenarioListBuilde
private static final String ENVELOPE_MANIFEST_SCHEMA = "EnvelopeManifest";
private static final String ENVELOPE_TRANSFER_CHAIN_ENTRY_SCHEMA = "EnvelopeTransferChainEntry";
private static final String ISSUANCE_MANIFEST_SCHEMA = "IssuanceManifest";
private static final String RECEIVER_VALIDATION_RESPONSE = "ReceiverValidationResponse";

public static LinkedHashMap<String, PintScenarioListBuilder> createModuleScenarioListBuilders(
String standardVersion, String sendingPlatformPartyName, String receivingPlatformPartyName) {
Expand All @@ -34,9 +35,9 @@ public static LinkedHashMap<String, PintScenarioListBuilder> createModuleScenari
RECEIVING_PLATFORM_PARTY_NAME.set(receivingPlatformPartyName);
return Stream.of(
Map.entry(
"",
"Transfer scenarios",
noAction().thenEither(
supplyScenarioParameters(0).thenEither(
supplySenderTransferScenarioParameters(0).thenEither(
receiverStateSetup(ScenarioClass.NO_ISSUES)
.thenEither(
initiateAndCloseTransferAction(PintResponseCode.RECE).thenEither(
Expand Down Expand Up @@ -74,7 +75,7 @@ public static LinkedHashMap<String, PintScenarioListBuilder> createModuleScenari
initiateAndCloseTransferAction(PintResponseCode.RECE)))
))
),
supplyScenarioParameters(2).thenEither(
supplySenderTransferScenarioParameters(2).thenEither(
receiverStateSetup(ScenarioClass.NO_ISSUES)
.then(
initiateTransfer(2).thenEither(
Expand Down Expand Up @@ -115,7 +116,11 @@ public static LinkedHashMap<String, PintScenarioListBuilder> createModuleScenari
)
)
)))
)))
)),
Map.entry("Receiver validation scenarios",
supplyReceiverValidationScenarioParameters()
.then(receiverValidation())
))
.collect(
Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Expand All @@ -127,8 +132,33 @@ private PintScenarioListBuilder(
super(actionBuilder);
}

private static PintScenarioListBuilder supplyReceiverValidationScenarioParameters() {
String sendingPlatform = SENDING_PLATFORM_PARTY_NAME.get();
String receivingPlatform = RECEIVING_PLATFORM_PARTY_NAME.get();
return new PintScenarioListBuilder(
previousAction ->
new SupplyValidationEndpointScenarioParametersAction(
sendingPlatform,
receivingPlatform,
(PintAction) previousAction
));
}

private static PintScenarioListBuilder receiverValidation() {
String sendingPlatform = SENDING_PLATFORM_PARTY_NAME.get();
String receivingPlatform = RECEIVING_PLATFORM_PARTY_NAME.get();
return new PintScenarioListBuilder(
previousAction ->
new PintReceiverValidationAction(
sendingPlatform,
receivingPlatform,
(PintAction) previousAction,
200,
resolveMessageSchemaValidator(RECEIVER_VALIDATION_RESPONSE)
));
}

private static PintScenarioListBuilder supplyScenarioParameters(int documentCount) {
private static PintScenarioListBuilder supplySenderTransferScenarioParameters(int documentCount) {
String sendingPlatform = SENDING_PLATFORM_PARTY_NAME.get();
String receivingPlatform = RECEIVING_PLATFORM_PARTY_NAME.get();
return new PintScenarioListBuilder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import java.util.Set;

import static org.dcsa.conformance.core.toolkit.JsonToolkit.OBJECT_MAPPER;

public abstract class PintAction extends ConformanceAction {
protected final int expectedStatus;
private final OverwritingReference<DynamicScenarioParameters> dspReference;
Expand All @@ -28,7 +30,7 @@ public PintAction(
this.expectedStatus = expectedStatus;
if (previousAction == null) {
this.dspReference =
new OverwritingReference<>(null, new DynamicScenarioParameters(null, -1, Set.of(), null));
new OverwritingReference<>(null, new DynamicScenarioParameters(null, -1, Set.of(), null, OBJECT_MAPPER.createObjectNode()));
this.rspReference = new OverwritingReference<>(null, new ReceiverScenarioParameters("", "", "", "", ""));
this.sspReference = new OverwritingReference<>(null, new SenderScenarioParameters(null, "", "", ""));
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.dcsa.conformance.standards.eblinterop.action;

import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.stream.Stream;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.dcsa.conformance.core.check.*;
import org.dcsa.conformance.core.traffic.HttpMessageType;
import org.dcsa.conformance.standards.eblinterop.party.PintRole;

@Getter
@Slf4j
public class PintReceiverValidationAction extends PintAction {
private final JsonSchemaValidator responseSchemaValidator;

public PintReceiverValidationAction(
String sourcePartyName,
String targetPartyName,
PintAction previousAction,
int responseCode,
JsonSchemaValidator responseSchemaValidator
) {
super(
sourcePartyName,
targetPartyName,
previousAction,
"ReceiverValidation(%d)".formatted(responseCode),
responseCode
);
this.responseSchemaValidator = responseSchemaValidator;
}

@Override
public String getHumanReadablePrompt() {
return ("Request receiver validation for: " + getDsp().receiverValidation().toString());
}

@Override
public ObjectNode asJsonNode() {
var node = super.asJsonNode();
node.set("dsp", getDsp().toJson());
return node;
}

@Override
public ConformanceCheck createCheck(String expectedApiVersion) {
return new ConformanceCheck(getActionTitle()) {
@Override
protected Stream<? extends ConformanceCheck> createSubChecks() {

return Stream.of(
new HttpMethodCheck(PintRole::isSendingPlatform, getMatchedExchangeUuid(), "POST"),
new UrlPathCheck(
PintRole::isSendingPlatform, getMatchedExchangeUuid(), "/receiver-validation"),
new ResponseStatusCheck(
PintRole::isReceivingPlatform, getMatchedExchangeUuid(), expectedStatus),
new ApiHeaderCheck(
PintRole::isSendingPlatform,
getMatchedExchangeUuid(),
HttpMessageType.REQUEST,
expectedApiVersion),
new ApiHeaderCheck(
PintRole::isReceivingPlatform,
getMatchedExchangeUuid(),
HttpMessageType.RESPONSE,
expectedApiVersion),
new JsonSchemaCheck(
PintRole::isReceivingPlatform,
getMatchedExchangeUuid(),
HttpMessageType.RESPONSE,
responseSchemaValidator
)
);
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.dcsa.conformance.standards.eblinterop.action;

import static org.dcsa.conformance.core.toolkit.JsonToolkit.OBJECT_MAPPER;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Getter
@Slf4j
public class SupplyValidationEndpointScenarioParametersAction extends PintAction {

public SupplyValidationEndpointScenarioParametersAction(
String platformPartyName,
String carrierPartyName,
PintAction previousAction) {
super(
carrierPartyName,
platformPartyName,
previousAction,
"SupplyValidationEndpointScenarioParameters",
-1);
}

@Override
public boolean isInputRequired() {
return true;
}

@Override
public void handlePartyInput(JsonNode partyInput) {
super.handlePartyInput(partyInput);
setDsp(getDsp().withReceiverValidation(partyInput));
}

public static ObjectNode getJsonForPrompt() {
var partyDef = OBJECT_MAPPER.createObjectNode();
partyDef.put("codeListProvider", "ZZZ")
.put("partyCode", "valid-party")
.put("codeListName", "CTK");
return partyDef;
}

@Override
public JsonNode getJsonForHumanReadablePrompt() {
return getJsonForPrompt();
}

@Override
public String getHumanReadablePrompt() {
return ("Provide parameters for the receiver validation endpoint");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public record DynamicScenarioParameters(
String transportDocumentChecksum,
int documentCount,
Set<String> documentChecksums,
String envelopeReference
String envelopeReference,
JsonNode receiverValidation
) {
public ObjectNode toJson() {
var node = OBJECT_MAPPER.createObjectNode()
Expand All @@ -26,6 +27,7 @@ public ObjectNode toJson() {
for (var checksum : documentChecksums) {
jsonDocumentChecksums.add(checksum);
}
node.set("receiverValidation", receiverValidation);
return node;
}

Expand All @@ -36,7 +38,8 @@ public static DynamicScenarioParameters fromJson(JsonNode jsonNode) {
StreamSupport.stream(jsonNode.required("documentChecksums").spliterator(), false)
.map(JsonNode::asText)
.collect(Collectors.toUnmodifiableSet()),
jsonNode.required("envelopeReference").asText()
jsonNode.required("envelopeReference").asText(),
jsonNode.path("receiverValidation")
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ protected void doReset() {
protected Map<Class<? extends ConformanceAction>, Consumer<JsonNode>> getActionPromptHandlers() {
return Map.ofEntries(
Map.entry(ReceiverSupplyScenarioParametersAndStateSetupAction.class, this::initiateState),
Map.entry(ResetScenarioClassAction.class, this::resetScenarioClass)
Map.entry(ResetScenarioClassAction.class, this::resetScenarioClass),
Map.entry(SupplyValidationEndpointScenarioParametersAction.class, this::providedReceiverValidationScenarioParameters)
);
}

Expand All @@ -81,6 +82,14 @@ private void resetScenarioClass(JsonNode actionPrompt) {
"Finished resetScenarioClass");
}

private void providedReceiverValidationScenarioParameters(JsonNode actionPrompt) {
log.info("EblInteropReceivingPlatform.providedReceiverValidationScenarioParameters(%s)".formatted(actionPrompt.toPrettyString()));
asyncOrchestratorPostPartyInput(
actionPrompt.required("actionId").asText(), SupplyValidationEndpointScenarioParametersAction.getJsonForPrompt());
addOperatorLogEntry(
"Finished providedReceiverValidationScenarioParameters");
}

private void initiateState(JsonNode actionPrompt) {
log.info("EblInteropSendingPlatform.handleScenarioTypeAction(%s)".formatted(actionPrompt.toPrettyString()));
var ssp = SenderScenarioParameters.fromJson(actionPrompt.get("ssp"));
Expand Down Expand Up @@ -262,13 +271,23 @@ public ConformanceResponse handleEnvelopeRequest(ConformanceRequest request) {
"Unknown endpoint")));
}

private ConformanceResponse handleReceiverValidation(ConformanceRequest request) {
return request.createResponse(
200,
Map.of(API_VERSION, List.of(apiVersion)),
new ConformanceMessageBody(OBJECT_MAPPER.createObjectNode().put("partyName", "Name of Test Party"))
);
}

@Override
public ConformanceResponse handleRequest(ConformanceRequest request) {
log.info("EblInteropPlatform.handleRequest(%s)".formatted(request));

var url = request.url().replaceFirst("/++$", "");
ConformanceResponse response;
if (url.endsWith("/envelopes")) {
if (url.endsWith("/receiver-validation")) {
response = handleReceiverValidation(request);
} else if (url.endsWith("/envelopes")) {
response = handleInitiateTransferRequest(request);
} else if(url.contains("/envelopes/")) {
response = handleEnvelopeRequest(request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ protected Map<Class<? extends ConformanceAction>, Consumer<JsonNode>> getActionP
Map.entry(PintTransferAdditionalDocumentFailureAction.class, this::transferActionDocument),
Map.entry(PintRetryTransferAction.class, this::retryTransfer),
Map.entry(PintRetryTransferAndCloseAction.class, this::retryTransfer),
Map.entry(PintCloseTransferAction.class, this::finishTransfer)
Map.entry(PintCloseTransferAction.class, this::finishTransfer),
Map.entry(PintReceiverValidationAction.class, this::requestReceiverValidation)
);
}

Expand Down Expand Up @@ -133,6 +134,14 @@ private String generateTDR() {
return tdrChars.toString();
}

private void requestReceiverValidation(JsonNode actionPrompt) {
log.info("EblInteropSendingPlatform.requestReceiverValidation(%s)".formatted(actionPrompt.toPrettyString()));
var dsp = DynamicScenarioParameters.fromJson(actionPrompt.required("dsp"));
this.syncCounterpartPost("/v" + apiVersion.charAt(0) + "/receiver-validation", dsp.receiverValidation());
addOperatorLogEntry(
"Requested receiver validation");
}

private void supplyScenarioParameters(JsonNode actionPrompt) {
log.info("EblInteropSendingPlatform.supplyScenarioParameters(%s)".formatted(actionPrompt.toPrettyString()));
var tdr = generateTDR();
Expand Down