Newer
Older
package de.ozgcloud.xta.client;
import static de.ozgcloud.xta.client.XtaClient.*;
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 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.xta.client.exception.XtaClientException;
import de.ozgcloud.xta.client.extension.StaticStringListAppender;
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
private static final XtaTestServerSetupExtension XTA_TEST_SERVER_SETUP_EXTENSION = new XtaTestServerSetupExtension();
static final int TWO_MAX_LIST_ITEMS = 2;
private XtaClient testClient;
private List<XtaMessageMetaData> supportCheckedMetadataItems;
private List<XtaMessage> processedMessages;
private Consumer<XtaMessage> processMessageDummy;
private Predicate<XtaMessageMetaData> isSupportedDummy;
@BeforeEach
@SneakyThrows
void setup() {
};
supportCheckedMetadataItems = new ArrayList<>();
processedMessages = new ArrayList<>();
silentTestClient = XTA_TEST_SERVER_SETUP_EXTENSION.getSilentTestClient();
StaticStringListAppender.clearLogLines();
closeMessagesForAllReaders();
}
private void closeMessagesForAllReaders() {
var silentTestClientConfig = XTA_TEST_SERVER_SETUP_EXTENSION.getSilentTestClientConfig();
closeAllMessages(silentTestClientConfig, READER_CLIENT_IDENTIFIER1);
closeAllMessages(silentTestClientConfig, READER_CLIENT_IDENTIFIER2);
closeAllMessages(silentTestClientConfig, READER_CLIENT_IDENTIFIER3);
private List<XtaMessage> sendMessages;
private List<String> sendMessageIds;
@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)
);
sendMessageIds = sendMessages.stream()
.map(message -> sendTestMessage(silentTestClient, 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 throw exception on connection failure")
@Test
@SneakyThrows
void shouldThrowExceptionOnConnectionFailure() {
setupClientWithoutTrustStore();
assertThatThrownBy(() -> testClient.fetchMessages(message -> fail("Should not process any message!")))
.isInstanceOf(XtaClientException.class);
}
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
@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)
}
@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)
.haveExactlyClosedStatusFor(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)
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)
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);
assertThat(hasLogLineContaining(NO_MESSAGE_CLOSED_WARNING)).isFalse();
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)
messageIdBySendIndex(0),
messageIdBySendIndex(1), messageIdBySendIndex(2)
);
}
@DisplayName("should close messages only if no exception occurs during processing, with no exception for author3")
@Test
void shouldCloseMessagesOnlyIfNoExceptionOccursDuringProcessingWithNoExceptionForAuthor3() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
processMessageDummy = message -> throwRuntimeExceptionExceptForAuthorIdentifier(message, AUTHOR_CLIENT_IDENTIFIER3);
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 2 + 2);
assertThat(hasLogLineContaining(NO_MESSAGE_CLOSED_WARNING)).isTrue();
assertThatMessages(processedMessages).containMetaDataExactlyInAnyOrder(
sendMessages.get(0).metaData(),
supportCheckedMetadataItems.get(1), supportCheckedMetadataItems.get(2),
sendMessages.get(4).metaData(), sendMessages.get(5).metaData()
);
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
messageIdBySendIndex(5)
);
}
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);
assertThat(hasLogLineContaining(NO_MESSAGE_CLOSED_WARNING)).isFalse();
assertThatMessages(processedMessages).containExactlyInAnyOrder(sendMessages.get(0), sendMessages.get(1), sendMessages.get(2));
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
.haveExactlyClosedStatusFor(messageIdBySendIndex(0), messageIdBySendIndex(1), messageIdBySendIndex(2));
@DisplayName("should process messages only if supported, with support for author3")
@Test
void shouldProcessMessagesOnlyIfSupportedWithSupportForAuthor3() {
setupClientWithIdentifiers(List.of(READER_CLIENT_IDENTIFIER1, READER_CLIENT_IDENTIFIER2, READER_CLIENT_IDENTIFIER3));
isSupportedDummy = metaData -> metaData.authorIdentifier().value().equals(AUTHOR_CLIENT_IDENTIFIER3.value());
var transportReports = fetchMessages();
assertThat(supportCheckedMetadataItems).hasSize(1 + 2 + 2);
assertThat(hasLogLineContaining(NO_MESSAGE_CLOSED_WARNING)).isTrue();
assertThatMessages(processedMessages).containExactlyInAnyOrder(sendMessages.get(5));
assertThatTransportReports(transportReports)
.reportExactlyFor(processedMessages)
@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) {
return sendMessageIds.get(sendIndex);
@SneakyThrows
private List<XtaTransportReport> fetchMessages() {
processedMessages.add(message);
processMessageDummy.accept(message);
});
}
@DisplayName("send message")
@Nested
class TestSendMessage {
private XtaMessage message;
@BeforeEach
void beforeEach() {
var messageConfig = XtaMessageExampleLoader.MessageExampleConfig.builder()
.messageLabel("dfoerdermittel")
.author(AUTHOR_CLIENT_IDENTIFIER)
.build();
message = XtaMessageExampleLoader.load(messageConfig);
}
@DisplayName("should throw exception on connection failure")
@Test
@SneakyThrows
void shouldThrowExceptionOnConnectionFailure() {
setupClientWithoutTrustStore();
assertThatThrownBy(() -> testClient.sendMessage(message))
.isInstanceOf(XtaClientException.class);
}
@DisplayName("should return transport report with open status")
@Test
@SneakyThrows
void shouldReturnTransportReportWithOpenStatus() {
var transportReport = silentTestClient.sendMessage(message);
assertThat(transportReport.status()).isEqualTo(XtaMessageStatus.OPEN);
}
}
@SneakyThrows
private void setupClientWithoutTrustStore() {
testClient = XtaClient.from(
XTA_TEST_SERVER_SETUP_EXTENSION.createSpecificClientConfigBuilder()
.trustStore(null)
.clientIdentifiers(List.of(READER_CLIENT_IDENTIFIER1))
.maxListItems(TWO_MAX_LIST_ITEMS)
.isMessageSupported(metaData -> fail("Should not process any message!"))
.build()
);
}