Skip to content
Snippets Groups Projects
Commit 66c1bf1a authored by Jan Zickermann's avatar Jan Zickermann
Browse files

OZG-6748 KOP-2733 XtaClientITCase: Test fetchMessages

parent 997983b3
No related branches found
No related tags found
No related merge requests found
Showing
with 531 additions and 80 deletions
......@@ -10,6 +10,7 @@ import jakarta.validation.constraints.NotNull;
import de.ozgcloud.xta.client.config.XtaClientConfig;
import de.ozgcloud.xta.client.core.XtaClientService;
import de.ozgcloud.xta.client.exception.ClientInitializationException;
import de.ozgcloud.xta.client.exception.ClientRuntimeException;
import de.ozgcloud.xta.client.model.XtaIdentifier;
import de.ozgcloud.xta.client.model.XtaMessage;
......@@ -19,20 +20,22 @@ import de.ozgcloud.xta.client.model.XtaMessageStatus;
import de.ozgcloud.xta.client.model.XtaTransportReport;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.extern.log4j.Log4j2;
@RequiredArgsConstructor(access = AccessLevel.MODULE)
@Builder(access = AccessLevel.MODULE)
@Getter(AccessLevel.MODULE)
@Slf4j
@Log4j2
public class XtaClient {
private final XtaClientService service;
private final XtaClientConfig config;
private final FetchMessageParameterFactory fetchMessageParameterFactory;
public static XtaClient from(XtaClientConfig config) throws ClientInitializationException {
return XtaClientFactory.from(config).create();
}
public List<XtaTransportReport> fetchMessages(@NotNull Consumer<XtaMessage> processMessage) {
return config.getClientIdentifiers().stream()
.filter(service::checkAccountActive)
......
......@@ -30,6 +30,7 @@ public class XtaClientFactory {
return XtaClient.builder()
.config(config)
.service(xtaClientServiceFactory.create())
.fetchMessageParameterFactory(fetchMessageParameterFactory)
.build();
}
}
......@@ -11,12 +11,13 @@
*/
package de.ozgcloud.xta.client.config;
import static java.util.Collections.*;
import java.util.List;
import java.util.function.Predicate;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
......@@ -33,8 +34,8 @@ import lombok.ToString;
@ToString
public class XtaClientConfig {
@NotEmpty(message = "at least one client identifier is required")
private final List<@Valid XtaIdentifier> clientIdentifiers;
@Builder.Default
private final List<@Valid XtaIdentifier> clientIdentifiers = emptyList();
@Builder.Default
private final Predicate<XtaMessageMetaData> isMessageSupported = null;
......
......@@ -10,7 +10,7 @@ import jakarta.validation.constraints.PositiveOrZero;
import lombok.Builder;
@Builder
@Builder(toBuilder = true)
public record XtaFile(
@NotNull DataHandler content,
@NotBlank String contentType,
......
......@@ -24,6 +24,8 @@ class XtaClientFactoryTest {
private XtaClientServiceFactory xtaClientServiceFactory;
@Mock
private XtaClientConfig config;
@Mock
private FetchMessageParameterFactory fetchMessageParameterFactory;
@InjectMocks
private XtaClientFactory factory;
......@@ -41,24 +43,6 @@ class XtaClientFactoryTest {
when(xtaClientServiceFactory.create()).thenReturn(service);
}
@DisplayName("should have service")
@Test
@SneakyThrows
void shouldHaveService() {
var client = factory.create();
assertThat(client.getService()).isEqualTo(service);
}
@DisplayName("should have config")
@Test
@SneakyThrows
void shouldHaveConfig() {
var client = factory.create();
assertThat(client.getConfig()).isEqualTo(config);
}
@DisplayName("should call validate")
@Test
@SneakyThrows
......@@ -67,5 +51,18 @@ class XtaClientFactoryTest {
verify(configValidator).validate(config);
}
@DisplayName("should return")
@Test
@SneakyThrows
void shouldReturn() {
assertThat(factory.create())
.usingRecursiveComparison()
.isEqualTo(XtaClient.builder()
.config(config)
.service(service)
.fetchMessageParameterFactory(fetchMessageParameterFactory)
.build());
}
}
}
\ No newline at end of file
package de.ozgcloud.xta.client;
import static de.ozgcloud.xta.client.extension.XtaServerSetupExtensionTestUtil.*;
import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.*;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import de.ozgcloud.common.errorhandling.TechnicalException;
import de.ozgcloud.xta.client.extension.XtaMessageExampleLoader;
import de.ozgcloud.xta.client.extension.XtaTestServerSetupExtension;
import de.ozgcloud.xta.client.model.XtaIdentifier;
import de.ozgcloud.xta.client.model.XtaMessage;
import de.ozgcloud.xta.client.model.XtaMessageMetaData;
import de.ozgcloud.xta.client.model.XtaMessageStatus;
import de.ozgcloud.xta.client.model.XtaTransportReport;
import lombok.SneakyThrows;
class XtaClientITCase {
@RegisterExtension
static final XtaTestServerSetupExtension XTA_TEST_SERVER_SETUP_EXTENSION = new XtaTestServerSetupExtension();
static final int TWO_MAX_LIST_ITEMS = 2;
private XtaClient setupClient;
private XtaClient testClient;
private XtaClient client;
private List<XtaMessageMetaData> supportCheckedMetadataItems;
private List<XtaMessage> processedMessages;
private Consumer<XtaMessage> processMessageDummy;
private Predicate<XtaMessageMetaData> isSupportedDummy;
@BeforeEach
@SneakyThrows
void setup() {
client = XTA_TEST_SERVER_SETUP_EXTENSION.getClient();
processMessageDummy = (message) -> {
};
supportCheckedMetadataItems = new ArrayList<>();
isSupportedDummy = (metaData) -> true;
processedMessages = new ArrayList<>();
setupClient = XTA_TEST_SERVER_SETUP_EXTENSION.getSetupClient();
closeMessagesForAllReaders();
}
private void closeMessagesForAllReaders() {
Stream.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3)
.forEach(clientId -> closeAllMessages(setupClient, clientId));
}
@DisplayName("fetch messages")
@Nested
class TestFetchMessages {
// TODO KOP-2733
private List<XtaMessage> sendMessages;
@BeforeEach
void setup() {
sendMessages = List.of(
createMessage("dfoerdermittel", AUTHOR_CLIENT_IDENTIFIER, READER_CLIENT_IDENTIFIER1),
createMessage("dfoerdermittel", AUTHOR_CLIENT_IDENTIFIER, READER_CLIENT_IDENTIFIER2),
createMessage("abgabe0401-kleiner-waffenschein", AUTHOR_CLIENT_IDENTIFIER, READER_CLIENT_IDENTIFIER2),
createMessage("versammlungsanzeige", AUTHOR_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER2),
createMessage("versammlungsanzeige", AUTHOR_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3),
createMessage("versammlungsanzeige", AUTHOR_CLIENT_IDENTIFIER3, READER_CLIENT_IDENTIFIER3)
);
sendMessages.forEach(message -> sendTestMessage(setupClient, message));
}
private XtaMessage createMessage(String messageLabel, XtaIdentifier author, XtaIdentifier reader) {
return XtaMessageExampleLoader.load(
XtaMessageExampleLoader.MessageExampleConfig.builder()
.messageLabel(messageLabel)
.reader(reader)
.author(author)
.build());
}
@DisplayName("should fetch no messages if no client identifier is configured")
@Test
void shouldFetchNoMessagesIfNoClientIdentifierIsConfigured() {
setupClientWithIdentifiers(emptyList());
var messages = fetchMessages();
assertThat(supportCheckedMetadataItems).isEmpty();
assertThat(processedMessages).isEmpty();
assertThat(messages).isEmpty();
}
@DisplayName("should fetch no messages if client identifier has no messages pending")
@Test
void shouldFetchNoMessagesIfClientIdentifierHasNoMessagesPending() {
setupClientWithIdentifiers(List.of(AUTHOR_CLIENT_IDENTIFIER));
var messages = fetchMessages();
assertThat(supportCheckedMetadataItems).isEmpty();
assertThat(processedMessages).isEmpty();
assertThat(messages).isEmpty();
}
@DisplayName("should fetch messages from first reader")
@Test
@SneakyThrows
void shouldFetchMessagesFromFirstReader() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1));
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1);
assertThatMessages(processedMessages).containExactlyInAnyOrder(sendMessages.getFirst());
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(messageIdBySendIndex(0));
}
@DisplayName("should fetch messages from second reader")
@Test
void shouldFetchMessagesFromSecondReader() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER2));
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(3);
assertThatMessages(processedMessages).containExactlyInAnyOrder(sendMessages.get(1), sendMessages.get(2), sendMessages.get(3));
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(messageIdBySendIndex(1), messageIdBySendIndex(2), messageIdBySendIndex(3));
}
@DisplayName("should fetch messages from first and second reader")
@Test
void shouldFetchMessagesFromFirstAndSecondReader() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2));
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 3);
assertThatMessages(processedMessages).containExactlyInAnyOrder(
sendMessages.get(0),
sendMessages.get(1), sendMessages.get(2), sendMessages.get(3)
);
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(
messageIdBySendIndex(0),
messageIdBySendIndex(1), messageIdBySendIndex(2), messageIdBySendIndex(3)
);
}
@DisplayName("should fetch messages from first, second and third reader")
@Test
void shouldFetchMessagesFromFirstSecondAndThirdReader() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 3 + 2);
assertThatMessages(processedMessages).containExactlyInAnyOrder(
sendMessages.get(0),
sendMessages.get(1), sendMessages.get(2), sendMessages.get(3),
sendMessages.get(4), sendMessages.get(5)
);
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(
messageIdBySendIndex(0),
messageIdBySendIndex(1), messageIdBySendIndex(2), messageIdBySendIndex(3),
messageIdBySendIndex(4), messageIdBySendIndex(5)
);
}
@DisplayName("should close messages only if no exception occurs during processing, with no exception for author1")
@Test
void shouldCloseMessagesOnlyIfNoExceptionOccursDuringProcessingWithNoExceptionForAuthor1() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
processMessageDummy = message -> throwRuntimeExceptionExceptForAuthorIdentifier(message, AUTHOR_CLIENT_IDENTIFIER);
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 3 + 2);
assertThatMessages(processedMessages).containExactlyInAnyOrder(
sendMessages.get(0),
sendMessages.get(1), sendMessages.get(2), sendMessages.get(3),
sendMessages.get(4), sendMessages.get(5)
);
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(
messageIdBySendIndex(0),
messageIdBySendIndex(1), messageIdBySendIndex(2)
);
}
@DisplayName("should close messages only if no exception occurs during processing, with no exception for author2")
@Test
void shouldCloseMessagesOnlyIfNoExceptionOccursDuringProcessingWithNoExceptionForAuthor2() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
processMessageDummy = message -> throwRuntimeExceptionExceptForAuthorIdentifier(message, AUTHOR_CLIENT_IDENTIFIER2);
var transportReports = fetchMessages();
if (processedMessages.size() != 5) {
assertThat(supportCheckedMetadataItems).hasSize(1 + 3 + 2);
assertThatMessages(processedMessages).containExactlyInAnyOrder(
sendMessages.get(0),
sendMessages.get(1), sendMessages.get(2), sendMessages.get(3),
sendMessages.get(4), sendMessages.get(5)
);
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(
messageIdBySendIndex(3),
messageIdBySendIndex(4)
);
} else {
// If (by chance) sendMessages.get(1), sendMessages.get(2) are fetched first, both are not closed due to the runtime exception.
// Which results in the warning: "No message has been closed although more are pending. Try increasing max list items."
// and sendMessages.get(3) not being fetched/checked or processed.
assertThat(supportCheckedMetadataItems).hasSize(1 + 3 - 1 + 2);
assertThatMessages(processedMessages).containExactlyInAnyOrder(
sendMessages.get(0),
sendMessages.get(1), sendMessages.get(2),
sendMessages.get(4), sendMessages.get(5)
);
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(
messageIdBySendIndex(4)
);
}
}
private void throwRuntimeExceptionExceptForAuthorIdentifier(XtaMessage message, XtaIdentifier authorIdentifier) {
var authorId = message.metaData().authorIdentifier().value();
var readerId = message.metaData().readerIdentifier().value();
if (!authorId.equals(authorIdentifier.value())) {
throw new RuntimeException("Test exception for message with author '%s' and reader '%s'!".formatted(authorId, readerId));
}
}
@DisplayName("should process messages only if supported, with support for author1")
@Test
void shouldProcessMessagesOnlyIfSupportedWithSupportForAuthor1() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
isSupportedDummy = metaData -> metaData.authorIdentifier().value().equals(AUTHOR_CLIENT_IDENTIFIER.value());
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 3 + 2);
assertThatMessages(processedMessages).containExactlyInAnyOrder(sendMessages.get(0), sendMessages.get(1), sendMessages.get(2));
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(messageIdBySendIndex(0), messageIdBySendIndex(1), messageIdBySendIndex(2));
}
@DisplayName("should process messages only if supported, with support for author2")
@Test
void shouldProcessMessagesOnlyIfSupportedWithSupportForAuthor2() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
isSupportedDummy = metaData -> metaData.authorIdentifier().value().equals(AUTHOR_CLIENT_IDENTIFIER2.value());
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 3 + 2);
assertThatMessages(processedMessages).containExactlyInAnyOrder(sendMessages.get(3), sendMessages.get(4));
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyGreenStatusFor(messageIdBySendIndex(3), messageIdBySendIndex(4));
}
@SneakyThrows
private void setupClientWithIdentifiers(List<XtaIdentifier> identifiers) {
testClient = XtaClient.from(
XTA_TEST_SERVER_SETUP_EXTENSION.createSpecificClientConfigBuilder()
.clientIdentifiers(identifiers)
.maxListItems(TWO_MAX_LIST_ITEMS)
.isMessageSupported(metaData -> {
supportCheckedMetadataItems.add(metaData);
return isSupportedDummy.test(metaData);
})
.build()
);
}
private String messageIdBySendIndex(int sendIndex) {
var expectedMessageMetadata = withoutMessageIdAndSize(sendMessages.get(sendIndex).metaData());
var messageIds = processedMessages.stream()
.map(XtaMessage::metaData)
.filter(metaData -> withoutMessageIdAndSize(metaData).equals(expectedMessageMetadata))
.map(XtaMessageMetaData::messageId)
.toList();
if (messageIds.size() != 1) {
throw new TechnicalException(
"Expected exactly one message id for send index %d, but found %d!".formatted(sendIndex, messageIds.size())
+ "Ensure that all test messages have unique metadata!");
}
return messageIds.getFirst();
}
private List<XtaTransportReport> fetchMessages() {
return testClient.fetchMessages((message) -> {
processedMessages.add(message);
processMessageDummy.accept(message);
});
}
}
@DisplayName("send message")
......@@ -45,7 +329,7 @@ class XtaClientITCase {
var messageConfig = XtaMessageExampleLoader.MessageExampleConfig.builder()
.messageLabel("dfoerdermittel")
.reader(READER_CLIENT_IDENTIFIER1)
.author(READER_CLIENT_IDENTIFIER1)
.author(AUTHOR_CLIENT_IDENTIFIER)
.build();
message = XtaMessageExampleLoader.load(messageConfig);
}
......@@ -54,11 +338,10 @@ class XtaClientITCase {
@Test
@SneakyThrows
void shouldReturnTransportReportWithOpenStatus() {
var transportReport = client.sendMessage(message);
var transportReport = setupClient.sendMessage(message);
assertThat(transportReport.status()).isEqualTo(XtaMessageStatus.OPEN);
}
}
}
package de.ozgcloud.xta.client.config;
import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.*;
import java.util.List;
import java.util.function.UnaryOperator;
import org.junit.jupiter.api.DisplayName;
......@@ -10,8 +10,9 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import de.ozgcloud.xta.client.factory.XtaClientConfigTestFactory;
import de.ozgcloud.xta.client.exception.ClientInitializationException;
import de.ozgcloud.xta.client.factory.XtaClientConfigTestFactory;
import de.ozgcloud.xta.client.model.XtaIdentifier;
import lombok.SneakyThrows;
class XtaConfigValidatorTest {
......@@ -43,11 +44,11 @@ class XtaConfigValidatorTest {
validator.validate(config);
}
@DisplayName("should throw without client identifiers")
@DisplayName("should throw with blank client identifier")
@Test
void shouldThrowWithoutIdentifiers() {
void shouldThrowWithBlankClientIdentifier() {
var config = XtaClientConfigTestFactory.createBuilder()
.clientIdentifiers(emptyList())
.clientIdentifiers(List.of(XtaIdentifier.builder().value("").build()))
.build();
assertThatThrownBy(() -> validator.validate(config))
......
......@@ -131,7 +131,7 @@ public class XtaMessageExampleLoader {
private static List<XtaFile> mapXtaFiles(List<Map<String, Object>> attachmentFiles, String resourcePrefix) {
return attachmentFiles.stream()
.map(messageFileMap -> mapXtaFile(messageFileMap, resourcePrefix, null))
.map(messageFileMap -> mapXtaFile(messageFileMap, resourcePrefix, (path, content) -> content))
.toList();
}
......
package de.ozgcloud.xta.client.extension;
import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import de.ozgcloud.xta.client.XtaClient;
import de.ozgcloud.xta.client.config.XtaClientConfig;
import de.ozgcloud.xta.client.core.WrappedXtaService;
import de.ozgcloud.xta.client.core.XtaClientService;
import de.ozgcloud.xta.client.exception.ClientRuntimeException;
import de.ozgcloud.xta.client.model.XtaFile;
import de.ozgcloud.xta.client.model.XtaIdentifier;
import de.ozgcloud.xta.client.model.XtaMessage;
import de.ozgcloud.xta.client.model.XtaMessageMetaData;
import de.ozgcloud.xta.client.model.XtaMessageStatus;
import de.ozgcloud.xta.client.model.XtaTransportReport;
import genv3.de.xoev.transport.xta.x211.CodeFehlernummer;
import genv3.de.xoev.transport.xta.x211.MessageSchemaViolationException;
import genv3.de.xoev.transport.xta.x211.ParameterIsNotValidException;
......@@ -26,6 +37,17 @@ public class XtaServerSetupExtensionTestUtil {
.category("DMS Schleswig-Holstein")
.name("Generischer Antragsdienst")
.build();
public static final XtaIdentifier AUTHOR_CLIENT_IDENTIFIER2 = XtaIdentifier.builder()
.value("ehp:010100100000")
.category("Engagement- und Hobbyportal (FIM Sender)")
.name("OSI-Onlinedienst Schleswig-Holstein Versammlungsanzeige Test")
.build();
public static final XtaIdentifier AUTHOR_CLIENT_IDENTIFIER3 = XtaIdentifier.builder()
.value("ehp:010200100000")
.category("Engagement- und Hobbyportal (FIM Sender2)")
.name("OSI-Onlinedienst Hamburg Versammlungsanzeige Test")
.build();
public static final XtaIdentifier READER_CLIENT_IDENTIFIER2 = XtaIdentifier.builder()
.value("gae:test-environment@ozg-cloud.de")
.category("Generischer Antragsempfänger")
......@@ -36,10 +58,15 @@ public class XtaServerSetupExtensionTestUtil {
.category("Generischer Antragsempfänger")
.name("OZG-Cloud Dev")
.build();
public static final XtaIdentifier READER_CLIENT_IDENTIFIER3 = XtaIdentifier.builder()
.value("vbe:010510440100")
.category("Versammlungsbehörde (FIM Empfänger)")
.name("Kreisordnungsbehörde Dithmarschen")
.build();
public static XtaClientConfig.XtaClientConfigBuilder createClientConfigBuilder() {
return XtaClientConfig.builder()
.clientIdentifiers(List.of(AUTHOR_CLIENT_IDENTIFIER, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER1))
.clientIdentifiers(emptyList())
.logSoapRequests(true)
.logSoapResponses(true);
}
......@@ -97,9 +124,160 @@ public class XtaServerSetupExtensionTestUtil {
return (T) field.get(object);
}
public static XtaMessageMetaData withoutMessageIdAndSize(XtaMessageMetaData metaData) {
return metaData.toBuilder()
.messageId(null)
.messageSize(null)
.build();
}
public record MessagesAssert(List<XtaMessage> processedMessages) {
public MessagesAssert containExactlyInAnyOrder(XtaMessage... messages) {
try {
// Assert equal message counts
assertThat(processedMessages).hasSize(messages.length);
// Assert equal metadata (ignoring message id and size since they should be null before sending)
assertThat(processedMessages)
.extracting(XtaMessage::metaData)
.extracting(XtaServerSetupExtensionTestUtil::withoutMessageIdAndSize)
.containsExactlyInAnyOrderElementsOf(Arrays.stream(messages)
.map(XtaMessage::metaData)
.map(XtaServerSetupExtensionTestUtil::withoutMessageIdAndSize)
.toList());
// Assert equal message file and attachment files without content (ignoring size since it may be null before sending)
UnaryOperator<XtaFile> withoutContentAndSize = xtaFile -> xtaFile.toBuilder()
.content(null)
.size(null)
.build();
assertThat(processedMessages)
.extracting(XtaMessage::messageFile)
.extracting(withoutContentAndSize)
.containsExactlyInAnyOrderElementsOf(Arrays.stream(messages)
.map(XtaMessage::messageFile)
.map(withoutContentAndSize)
.toList());
UnaryOperator<List<XtaFile>> filesWithoutContentAndSize = fileList -> fileList.stream().map(withoutContentAndSize).toList();
assertThat(processedMessages)
.extracting(XtaMessage::attachmentFiles)
.extracting(filesWithoutContentAndSize)
.containsExactlyInAnyOrderElementsOf(Arrays.stream(messages)
.map(XtaMessage::attachmentFiles)
.map(filesWithoutContentAndSize)
.toList());
// Assert equal content of message file
var listOfMessageFileContents = processedMessages.stream()
.map(XtaMessage::messageFile)
.map(XtaServerSetupExtensionTestUtil::readBytesOfXtaFile)
.toList();
var exceptedListOfMessageFileContents = Arrays.stream(messages)
.map(XtaMessage::messageFile)
.map(XtaServerSetupExtensionTestUtil::readBytesOfXtaFile)
.toList();
Function<byte[], Integer> contentLength = b -> b.length;
assertThat(listOfMessageFileContents)
.extracting(contentLength)
.containsExactlyInAnyOrderElementsOf(exceptedListOfMessageFileContents.stream().map(contentLength).toList());
assertThat(listOfMessageFileContents).containsExactlyInAnyOrderElementsOf(exceptedListOfMessageFileContents);
// Assert equal content of attachment files
var attachmentFileContents = processedMessages.stream()
.map(XtaMessage::attachmentFiles)
.map(XtaServerSetupExtensionTestUtil::readBytesOfXtaFiles)
.toList();
var exceptedAttachmentFileContents = Arrays.stream(messages)
.map(XtaMessage::attachmentFiles)
.map(XtaServerSetupExtensionTestUtil::readBytesOfXtaFiles)
.toList();
Function<List<byte[]>, List<Integer>> contentLengths = contentList -> contentList.stream().map(contentLength).toList();
assertThat(attachmentFileContents)
.extracting(contentLengths)
.containsExactlyInAnyOrderElementsOf(exceptedAttachmentFileContents.stream().map(contentLengths).toList());
assertThat(attachmentFileContents)
.usingElementComparator((a, b) -> {
var sizeComparison = Integer.compare(a.size(), b.size());
return sizeComparison != 0
? sizeComparison
: IntStream.range(0, a.size())
.map(i -> Arrays.compare(a.get(i), b.get(i)))
.filter(i -> i != 0)
.findFirst()
.orElse(0);
})
.containsExactlyInAnyOrderElementsOf(exceptedAttachmentFileContents);
} catch (AssertionError | RuntimeException e) {
log.error("Messages do not exactly contain excepted messages!");
throw e;
}
return this;
}
}
public static MessagesAssert assertThatMessages(List<XtaMessage> processedMessages) {
return new MessagesAssert(processedMessages);
}
public record TransportReportsAssert(List<XtaTransportReport> transportReports) {
public TransportReportsAssert reportExactlyFor(List<XtaMessage> processedMessages) {
try {
assertThat(transportReports).hasSize(processedMessages.size());
// Compare message ids
assertThat(transportReports)
.extracting(XtaTransportReport::metaData)
.extracting(XtaMessageMetaData::messageId)
.containsExactlyElementsOf(processedMessages.stream()
.map(XtaMessage::metaData)
.map(XtaMessageMetaData::messageId)
.toList());
// Compare message metadata
assertThat(transportReports)
.extracting(XtaTransportReport::metaData)
.containsExactlyElementsOf(processedMessages.stream()
.map(XtaMessage::metaData)
.toList());
} catch (AssertionError | RuntimeException e) {
log.error("TransportReports do not exactly match messages metadata!");
throw e;
}
return this;
}
public TransportReportsAssert haveExactlyGreenStatusFor(String... messageIds) {
try {
var setOfMessageIds = Arrays.stream(messageIds).collect(Collectors.toSet());
assertThat(transportReports)
.allMatch(transportReport ->
transportReport.status().equals(XtaMessageStatus.GREEN) == setOfMessageIds
.contains(transportReport.metaData().messageId())
);
} catch (AssertionError | RuntimeException e) {
log.error("TransportReports do not have excepted green status for messageIds!");
throw e;
}
return this;
}
}
public static TransportReportsAssert assertThatTransportReports(List<XtaTransportReport> transportReports) {
return new TransportReportsAssert(transportReports);
}
private static List<byte[]> readBytesOfXtaFiles(List<XtaFile> xtaFiles) {
return xtaFiles.stream()
.map(XtaServerSetupExtensionTestUtil::readBytesOfXtaFile)
.toList();
}
@SneakyThrows
public static byte[] extractMessageFileContent(XtaMessage xtaMessage) {
return xtaMessage.messageFile().content().getInputStream().readAllBytes();
private static byte[] readBytesOfXtaFile(XtaFile xtaFile) {
try (var inputStream = xtaFile.content().getInputStream()) {
return inputStream.readAllBytes();
}
}
}
......@@ -6,7 +6,6 @@ import java.util.Objects;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.testcontainers.utility.DockerImageName;
......@@ -22,7 +21,7 @@ import lombok.extern.slf4j.Slf4j;
@Getter
@Setter
@Slf4j
public class XtaTestServerSetupExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback {
public class XtaTestServerSetupExtension implements BeforeAllCallback, AfterAllCallback {
private static final DockerImageName XTA_TEST_SERVER_IMAGE = DockerImageName.parse("docker.ozg-sh.de/xta-test-server")
.withTag("1.6.0");
......@@ -33,10 +32,11 @@ public class XtaTestServerSetupExtension implements BeforeAllCallback, AfterAllC
private static final String XTA_TEST_SERVER_TRUSTSTORE_PATH = "store/xta-test-server-truststore.jks";
private static final String XTA_TEST_SERVER_TRUSTSTORE_PASSWORD = "password";
private XtaClient client;
private XtaClientConfig config;
private XtaClient setupClient;
private XtaClientFactory clientFactory;
private XtaTestServerContainer xtaServerContainer;
private XtaClientConfig.KeyStore clientCertKeyStore;
private XtaClientConfig.KeyStore trustStore;
@Override
@SneakyThrows
......@@ -44,9 +44,26 @@ public class XtaTestServerSetupExtension implements BeforeAllCallback, AfterAllC
if (xtaServerContainer != null) {
return;
}
setupServer();
client = setupClient();
setupClient();
}
@SneakyThrows
private void setupClient() {
clientCertKeyStore = XtaClientConfig.KeyStore.builder()
.content(readBytesFromResource(JOHN_SMITH_KEYSTORE_PATH))
.type("PKCS12")
.password(JOHN_SMITH_KEYSTORE_PASSWORD.toCharArray())
.build();
trustStore = XtaClientConfig.KeyStore.builder()
.content(readBytesFromResource(XTA_TEST_SERVER_TRUSTSTORE_PATH))
.type("JKS")
.password(XTA_TEST_SERVER_TRUSTSTORE_PASSWORD.toCharArray())
.build();
setupClient = XtaClient.from(createSpecificClientConfigBuilder()
.logSoapRequests(false)
.logSoapResponses(false)
.build());
}
private void setupServer() {
......@@ -66,43 +83,13 @@ public class XtaTestServerSetupExtension implements BeforeAllCallback, AfterAllC
}
@SneakyThrows
XtaClient setupClient() {
var clientCertKeyStore = XtaClientConfig.KeyStore.builder()
.content(readBytesFromResource(JOHN_SMITH_KEYSTORE_PATH))
.type("PKCS12")
.password(JOHN_SMITH_KEYSTORE_PASSWORD.toCharArray())
.build();
var trustStore = XtaClientConfig.KeyStore.builder()
.content(readBytesFromResource(XTA_TEST_SERVER_TRUSTSTORE_PATH))
.type("JKS")
.password(XTA_TEST_SERVER_TRUSTSTORE_PASSWORD.toCharArray())
.build();
config = createClientConfigBuilder()
public XtaClientConfig.XtaClientConfigBuilder createSpecificClientConfigBuilder() {
return createClientConfigBuilder()
.managementServiceUrl(xtaServerContainer.getManagementPortUrl())
.sendServiceUrl(xtaServerContainer.getSendPortUrl())
.msgBoxServiceUrl(xtaServerContainer.getMsgBoxPortUrl())
.clientCertKeystore(clientCertKeyStore)
.trustStore(trustStore)
.build();
clientFactory = XtaClientFactory.from(config);
return clientFactory.create();
}
@Override
@SneakyThrows
public void beforeEach(ExtensionContext context) {
closeAllMessages(client, READER_CLIENT_IDENTIFIER1);
}
@SneakyThrows
public String sendTestMessage() {
return XtaServerSetupExtensionTestUtil.sendTestMessage(client, XtaMessageExampleLoader.MessageExampleConfig.builder()
.messageLabel("dfoerdermittel")
.reader(READER_CLIENT_IDENTIFIER1)
.author(READER_CLIENT_IDENTIFIER1)
.build());
.trustStore(trustStore);
}
@SneakyThrows
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment