Skip to content

Commit 5dfa61d

Browse files
authored
#76 Pass signedMessage XML and payload XML to UftpIncomingHandler (#77)
Signed-off-by: Tom Wetjens <tom.wetjens@edsn.nl>
1 parent 88be862 commit 5dfa61d

File tree

21 files changed

+539
-389
lines changed

21 files changed

+539
-389
lines changed

README.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ public class IncomingMessageHandler implements UftpIncomingHandler<FlexRequest>
207207
}
208208

209209
@Override
210-
public void handle(UftpParticipant sender, FlexRequest message) {
210+
public void handle(IncomingUftpMessage<FlexRequest> message) {
211211
// call UftpReceivedMessageService immediately or queue for later processing
212212
}
213213
}
@@ -222,7 +222,7 @@ To process a message (asynchronously) you can use the `UftpReceivedMessageServic
222222
@Autowired
223223
UftpReceivedMessageService uftpReceivedMessageService;
224224

225-
uftpReceivedMessageService.process(sender,message);
225+
uftpReceivedMessageService.process(message);
226226
```
227227

228228
To verify an incoming message, the connector must know the sender's public key. For this you must
@@ -262,9 +262,19 @@ public class MyUftpMessageSupport implements UftpMessageSupport {
262262

263263
// ...
264264
@Override
265-
public Optional<PayloadMessageType> getPreviousMessage(String messageID, String recipientDomain) {
265+
public Optional<PayloadMessageType> findDuplicateMessage(String messageID, String senderDomain, String recipientDomain) {
266266
// Add the retrieval of the previous message here....
267267
}
268+
269+
@Override
270+
public <T extends PayloadMessageType> Optional<T> findReferencedMessage(UftpMessageReference<T> reference) {
271+
// Add the retrieval of the referenced message here....
272+
}
273+
274+
@Override
275+
public Optional<FlexOfferRevocation> findFlexRevocation(String conversationID, String flexOfferMessageID, String senderDomain, String recipientDomain) {
276+
// Add the retrieval of the revocation message here....
277+
}
268278
}
269279
```
270280

@@ -276,7 +286,7 @@ interface;
276286
public class MyCongestionPointSupport implements CongestionPointSupport {
277287

278288
@Override
279-
public boolean areKnownCongestionPoints(Collection<String> connectionPoints) {
289+
public boolean areKnownCongestionPoints(Collection<EntityAddress> congestionPoints) {
280290
// connect this to your local administration of congestion points
281291
}
282292
}
@@ -307,7 +317,7 @@ public class MyCustomValidator implements UftpUserDefinedValidator<FlexRequest>
307317
}
308318

309319
@Override
310-
public boolean valid(UftpParticipant sender, FlexRequest flexRequest) {
320+
public boolean valid(UftpMessage<T> uftpMessage) {
311321
// implement your validation logic here; return true if valid, false otherwise
312322
}
313323

@@ -341,7 +351,7 @@ public class OutgoingMessageHandler implements UftpOutgoingHandler<FlexRequest>
341351
}
342352

343353
@Override
344-
public void handle(UftpParticipant sender, FlexRequest message) {
354+
public void handle(OutgoingUftpMessage<T> message) {
345355
// call UftpSendMessageService immediately or queue message for sending later
346356
}
347357

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2024 Contributors to the Shapeshifter project
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package org.lfenergy.shapeshifter.core.model;
6+
7+
import org.lfenergy.shapeshifter.api.PayloadMessageType;
8+
9+
public final class IncomingUftpMessage<T extends PayloadMessageType> extends UftpMessage<T> {
10+
11+
private final String signedMessageXml;
12+
private final String payloadMessageXml;
13+
14+
private IncomingUftpMessage(UftpParticipant sender, T payloadMessage, String signedMessageXml, String payloadMessageXml) {
15+
super(sender, payloadMessage);
16+
this.signedMessageXml = signedMessageXml;
17+
this.payloadMessageXml = payloadMessageXml;
18+
}
19+
20+
public static <T extends PayloadMessageType> IncomingUftpMessage<T> create(UftpParticipant sender, T payloadMessage, String signedMessageXml, String payloadMessageXml) {
21+
return new IncomingUftpMessage<>(sender, payloadMessage, signedMessageXml, payloadMessageXml);
22+
}
23+
24+
@Override
25+
public UftpMessageDirection direction() {
26+
return UftpMessageDirection.INCOMING;
27+
}
28+
29+
public String signedMessageXml() {
30+
return signedMessageXml;
31+
}
32+
33+
public String payloadMessageXml() {
34+
return payloadMessageXml;
35+
}
36+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 Contributors to the Shapeshifter project
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package org.lfenergy.shapeshifter.core.model;
6+
7+
import org.lfenergy.shapeshifter.api.PayloadMessageType;
8+
9+
public final class OutgoingUftpMessage<T extends PayloadMessageType> extends UftpMessage<T> {
10+
11+
private OutgoingUftpMessage(UftpParticipant sender, T payloadMessage) {
12+
super(sender, payloadMessage);
13+
}
14+
15+
public static <T extends PayloadMessageType> OutgoingUftpMessage<T> create(UftpParticipant sender, T payloadMessage) {
16+
return new OutgoingUftpMessage<>(sender, payloadMessage);
17+
}
18+
19+
@Override
20+
public UftpMessageDirection direction() {
21+
return UftpMessageDirection.OUTGOING;
22+
}
23+
}

core/src/main/java/org/lfenergy/shapeshifter/core/model/UftpMessage.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@
88
import org.lfenergy.shapeshifter.api.PayloadMessageType;
99
import org.lfenergy.shapeshifter.api.TestMessageResponse;
1010

11-
public record UftpMessage<T extends PayloadMessageType>(
12-
UftpParticipant sender,
13-
UftpMessageDirection direction,
14-
T payloadMessage
15-
) {
16-
17-
public static <T extends PayloadMessageType> UftpMessage<T> createIncoming(UftpParticipant sender, T payloadMessage) {
18-
return new UftpMessage<>(sender, UftpMessageDirection.INCOMING, payloadMessage);
11+
public abstract sealed class UftpMessage<T extends PayloadMessageType> permits IncomingUftpMessage, OutgoingUftpMessage {
12+
13+
private final UftpParticipant sender;
14+
private final T payloadMessage;
15+
16+
protected UftpMessage(UftpParticipant sender, T payloadMessage) {
17+
this.sender = sender;
18+
this.payloadMessage = payloadMessage;
1919
}
2020

21-
public static <T extends PayloadMessageType> UftpMessage<T> createOutgoing(UftpParticipant sender, T payloadMessage) {
22-
return new UftpMessage<>(sender, UftpMessageDirection.OUTGOING, payloadMessage);
21+
public static <T extends PayloadMessageType> IncomingUftpMessage<T> createIncoming(UftpParticipant sender, T payloadMessage, String signedMessageXml, String payloadMessageXml) {
22+
return IncomingUftpMessage.create(sender, payloadMessage, signedMessageXml, payloadMessageXml);
23+
}
24+
25+
public static <T extends PayloadMessageType> OutgoingUftpMessage<T> createOutgoing(UftpParticipant sender, T payloadMessage) {
26+
return OutgoingUftpMessage.create(sender, payloadMessage);
2327
}
2428

2529
/**
@@ -36,7 +40,7 @@ public <U extends PayloadMessageType> UftpMessageReference<U> referenceToPreviou
3640
return new UftpMessageReference<>(referencedMessageID,
3741
conversationID,
3842
// Having the correct direction is crucial for distinguishing between sender and recipient domain
39-
direction.inverse(),
43+
direction().inverse(),
4044
// Flip domains as the referencing message is sent by the recipient of the referenced message
4145
payloadMessage.getRecipientDomain(),
4246
payloadMessage.getSenderDomain(),
@@ -46,4 +50,14 @@ public <U extends PayloadMessageType> UftpMessageReference<U> referenceToPreviou
4650
public static boolean isResponse(PayloadMessageType message) {
4751
return message instanceof PayloadMessageResponseType || message instanceof TestMessageResponse;
4852
}
53+
54+
public UftpParticipant sender() {
55+
return sender;
56+
}
57+
58+
public T payloadMessage() {
59+
return payloadMessage;
60+
}
61+
62+
public abstract UftpMessageDirection direction();
4963
}
Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
11
package org.lfenergy.shapeshifter.core.service.handler;
22

33
import org.lfenergy.shapeshifter.api.PayloadMessageType;
4+
import org.lfenergy.shapeshifter.core.model.IncomingUftpMessage;
5+
import org.lfenergy.shapeshifter.core.model.OutgoingUftpMessage;
46
import org.lfenergy.shapeshifter.core.model.UftpParticipant;
57

68
public interface UftpPayloadHandler {
79

8-
void notifyNewIncomingMessage(UftpParticipant from, PayloadMessageType message);
10+
/**
11+
* @deprecated This method will be removed in the future. Use {@link #notifyNewIncomingMessage(IncomingUftpMessage)} instead.
12+
*/
13+
@Deprecated(forRemoval = true, since = "2.3.0")
14+
default void notifyNewIncomingMessage(UftpParticipant from, PayloadMessageType message) {
15+
// Default implementation to allow switching to the new method without breaking later when it's removed.
16+
throw new UnsupportedOperationException("Deprecated for removal");
17+
}
918

10-
void notifyNewOutgoingMessage(UftpParticipant from, PayloadMessageType message);
19+
default void notifyNewIncomingMessage(IncomingUftpMessage<? extends PayloadMessageType> message) {
20+
notifyNewIncomingMessage(message.sender(), message.payloadMessage());
21+
}
1122

23+
/**
24+
* @deprecated This method will be removed in the future. Use {@link #notifyNewOutgoingMessage(OutgoingUftpMessage)} instead.
25+
*/
26+
@Deprecated(forRemoval = true, since = "2.3.0")
27+
default void notifyNewOutgoingMessage(UftpParticipant from, PayloadMessageType message) {
28+
// Default implementation to allow switching to the new method without breaking later when it's removed.
29+
throw new UnsupportedOperationException("Deprecated for removal");
30+
}
31+
32+
default void notifyNewOutgoingMessage(OutgoingUftpMessage<? extends PayloadMessageType> message) {
33+
notifyNewOutgoingMessage(message.sender(), message.payloadMessage());
34+
}
1235
}

core/src/main/java/org/lfenergy/shapeshifter/core/service/receiving/ReceivedMessageProcessor.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
import lombok.RequiredArgsConstructor;
88
import lombok.extern.apachecommons.CommonsLog;
99
import org.lfenergy.shapeshifter.api.PayloadMessageType;
10-
import org.lfenergy.shapeshifter.api.SignedMessage;
10+
import org.lfenergy.shapeshifter.core.model.IncomingUftpMessage;
1111
import org.lfenergy.shapeshifter.core.model.UftpParticipant;
1212
import org.lfenergy.shapeshifter.core.service.UftpErrorProcessor;
1313
import org.lfenergy.shapeshifter.core.service.handler.UftpPayloadHandler;
1414
import org.lfenergy.shapeshifter.core.service.receiving.DuplicateMessageDetection.DuplicateMessageResult;
1515

16+
/**
17+
* This is an internal API and should not be used by applications. It may change or be removed in a future release.
18+
*/
1619
@CommonsLog
1720
@RequiredArgsConstructor
1821
public class ReceivedMessageProcessor {
@@ -21,16 +24,17 @@ public class ReceivedMessageProcessor {
2124
private final DuplicateMessageDetection duplicateDetection;
2225
private final UftpErrorProcessor errorProcessor;
2326

24-
public void onReceivedMessage(SignedMessage signedMessage, PayloadMessageType request) {
25-
var sender = new UftpParticipant(signedMessage);
27+
public void onReceivedMessage(IncomingUftpMessage<? extends PayloadMessageType> message) {
28+
var request = message.payloadMessage();
29+
var sender = message.sender();
2630
log.debug(String.format("Processing of received %s message from %s", request.getClass().getSimpleName(), sender));
2731

2832
if (isDuplicateMessage(sender, request)) {
2933
throw new DuplicateMessageException(
3034
"Received " + request.getClass().getSimpleName() + " with MessageID '" + request.getMessageID() + "' from " + sender + " is a duplicate and has already been received.");
3135
}
3236

33-
payloadHandler.notifyNewIncomingMessage(sender, request);
37+
payloadHandler.notifyNewIncomingMessage(message);
3438
}
3539

3640
private boolean isDuplicateMessage(UftpParticipant sender, PayloadMessageType payloadMessage) {

core/src/main/java/org/lfenergy/shapeshifter/core/service/receiving/UftpReceivedMessageService.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import lombok.RequiredArgsConstructor;
1010
import lombok.extern.apachecommons.CommonsLog;
1111
import org.lfenergy.shapeshifter.api.PayloadMessageType;
12+
import org.lfenergy.shapeshifter.core.model.IncomingUftpMessage;
1213
import org.lfenergy.shapeshifter.core.model.UftpMessage;
1314
import org.lfenergy.shapeshifter.core.model.UftpParticipant;
1415
import org.lfenergy.shapeshifter.core.service.handler.UftpPayloadHandler;
@@ -41,14 +42,36 @@ public class UftpReceivedMessageService {
4142
* @param from The company uftp details of the recipient
4243
* @param payloadMessage The details of the flex message, including messageID and conversationID
4344
* @return The validation result, either `ok` or `rejected` including a rejection reason
45+
* @deprecated This method will be removed in the future. Use {@link #process(IncomingUftpMessage)} instead.
4446
*/
47+
@Deprecated(forRemoval = true, since = "2.3.0")
4548
public ValidationResult process(UftpParticipant from, PayloadMessageType payloadMessage) {
46-
var validationResult = validateMessage(from, payloadMessage);
49+
return process(IncomingUftpMessage.create(from, payloadMessage, null, null));
50+
}
51+
52+
/**
53+
* Processes an incoming flex message in a specific conversation. Can be called from within your own incoming flex message processor. When the message passed validation, a
54+
* response message is created and sent.
55+
*
56+
* <pre><code>
57+
* public void process(IncomingUftpMessage&lt;? extends PayloadMessageType&gt; message) {
58+
* var validationResult = uftpReceivedMessageService.process(message);
59+
*
60+
* // implement further business logic here
61+
* }
62+
* </code></pre>
63+
*
64+
* @param uftpMessage The flex message
65+
* @return The validation result, either `ok` or `rejected` including a rejection reason
66+
*/
67+
public <T extends PayloadMessageType> ValidationResult process(IncomingUftpMessage<T> uftpMessage) {
68+
var validationResult = validateMessage(uftpMessage);
4769

70+
var payloadMessage = uftpMessage.payloadMessage();
4871
if (UftpMessage.isResponse(payloadMessage)) {
4972
processPayloadMessageResponse(payloadMessage, validationResult);
5073
} else {
51-
processPayloadMessage(from, payloadMessage, validationResult);
74+
processPayloadMessage(uftpMessage.sender(), payloadMessage, validationResult);
5275
}
5376

5477
return validationResult;
@@ -64,12 +87,12 @@ private void processPayloadMessage(UftpParticipant from, PayloadMessageType payl
6487
var response = UftpValidationResponseCreator.getResponseForMessage(payloadMessage, validationResult);
6588
var originalRecipient = new UftpParticipant(payloadMessage.getRecipientDomain(), getRecipientRoleBySenderRole(from.role()));
6689

67-
payloadHandler.notifyNewOutgoingMessage(originalRecipient, response);
90+
payloadHandler.notifyNewOutgoingMessage(UftpMessage.createOutgoing(originalRecipient, response));
6891
}
6992

70-
private ValidationResult validateMessage(UftpParticipant from, PayloadMessageType payloadMessage) {
93+
private <T extends PayloadMessageType> ValidationResult validateMessage(UftpMessage<T> uftpMessage) {
7194
if (shouldPerformValidations) {
72-
return validationService.validate(UftpMessage.createIncoming(from, payloadMessage));
95+
return validationService.validate(uftpMessage);
7396
}
7497
return ValidationResult.ok();
7598
}

core/src/main/java/org/lfenergy/shapeshifter/core/service/sending/UftpSendMessageService.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.lfenergy.shapeshifter.core.common.HttpStatusCode;
2323
import org.lfenergy.shapeshifter.core.model.SigningDetails;
2424
import org.lfenergy.shapeshifter.core.model.UftpMessage;
25-
import org.lfenergy.shapeshifter.core.model.UftpMessageDirection;
2625
import org.lfenergy.shapeshifter.core.model.UftpParticipant;
2726
import org.lfenergy.shapeshifter.core.service.crypto.UftpCryptoService;
2827
import org.lfenergy.shapeshifter.core.service.participant.ParticipantResolutionService;
@@ -106,7 +105,7 @@ public void attemptToSendMessage(@NonNull PayloadMessageType payloadMessage, @No
106105
public void attemptToValidateAndSendMessage(@NonNull PayloadMessageType payloadMessage, @NonNull SigningDetails details) throws UftpSendException {
107106
// We will validate outgoing messages, but we will not validate outgoing response messages.
108107
if (!(payloadMessage instanceof PayloadMessageResponseType)) {
109-
var uftpMessage = new UftpMessage<>(details.sender(), UftpMessageDirection.OUTGOING, payloadMessage);
108+
var uftpMessage = UftpMessage.createOutgoing(details.sender(), payloadMessage);
110109
var validationResult = uftpValidationService.validate(uftpMessage);
111110
if (!validationResult.valid()) {
112111
throw new UftpSendException(MessageFormat.format(MSG_VALIDATION_FAILED, payloadMessage.getClass().getSimpleName(), validationResult.rejectionReason()));

core/src/main/java/org/lfenergy/shapeshifter/core/service/validation/CongestionPointSupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ public interface CongestionPointSupport {
3030
/**
3131
* Checks whether every congestion point in a given list is a known congestion point
3232
*
33-
* @param connectionPoints The list of congestion points to be checked
33+
* @param congestionPoints The list of congestion points to be checked
3434
* @return Whether all given congestion points are a known congestion point
3535
*/
36-
boolean areKnownCongestionPoints(Collection<EntityAddress> connectionPoints);
36+
boolean areKnownCongestionPoints(Collection<EntityAddress> congestionPoints);
3737
}

core/src/test/java/org/lfenergy/shapeshifter/core/model/UftpMessageFixture.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@
99

1010
public final class UftpMessageFixture {
1111

12-
private UftpMessageFixture() {
13-
// Utility class
14-
}
15-
16-
public static <T extends PayloadMessageType> UftpMessage<T> createIncoming(UftpParticipant sender, T payloadMessage) {
17-
return new UftpMessage<>(sender, UftpMessageDirection.INCOMING, payloadMessage);
18-
}
19-
public static <T extends PayloadMessageResponseType> UftpMessage<T> createIncomingResponse(UftpParticipant sender, T payloadMessage) {
20-
return new UftpMessage<>(sender, UftpMessageDirection.INCOMING, payloadMessage);
21-
}
22-
23-
public static <T extends PayloadMessageType> UftpMessage<T> createOutgoing(UftpParticipant sender, T payloadMessage) {
24-
return new UftpMessage<>(sender, UftpMessageDirection.OUTGOING, payloadMessage);
25-
}
12+
private UftpMessageFixture() {
13+
// Utility class
14+
}
15+
16+
public static <T extends PayloadMessageType> UftpMessage<T> createIncoming(UftpParticipant sender, T payloadMessage) {
17+
return UftpMessage.createIncoming(sender, payloadMessage, "<SignedMessage/>", "<Payload/>");
18+
}
19+
20+
public static <T extends PayloadMessageResponseType> UftpMessage<T> createIncomingResponse(UftpParticipant sender, T payloadMessage) {
21+
return UftpMessage.createIncoming(sender, payloadMessage,"<SignedMessage/>", "<Payload/>");
22+
}
23+
24+
public static <T extends PayloadMessageType> UftpMessage<T> createOutgoing(UftpParticipant sender, T payloadMessage) {
25+
return UftpMessage.createOutgoing(sender, payloadMessage);
26+
}
2627

2728
}

0 commit comments

Comments
 (0)