-
Martin Vogel authoredMartin Vogel authored
SenderClientIT.java 32.83 KiB
package dev.fitko.fitconnect.integrationtests;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.RSAKey;
import dev.fitko.fitconnect.api.config.ApplicationConfig;
import dev.fitko.fitconnect.api.config.chunking.AttachmentChunkingConfig;
import dev.fitko.fitconnect.api.domain.model.attachment.Attachment;
import dev.fitko.fitconnect.api.domain.model.event.Event;
import dev.fitko.fitconnect.api.domain.model.event.Status;
import dev.fitko.fitconnect.api.domain.model.metadata.AuthenticationInformation;
import dev.fitko.fitconnect.api.domain.model.metadata.ContentStructure;
import dev.fitko.fitconnect.api.domain.model.metadata.Hash;
import dev.fitko.fitconnect.api.domain.model.metadata.Metadata;
import dev.fitko.fitconnect.api.domain.model.metadata.SignatureType;
import dev.fitko.fitconnect.api.domain.model.metadata.attachment.ApiAttachment;
import dev.fitko.fitconnect.api.domain.model.metadata.attachment.Purpose;
import dev.fitko.fitconnect.api.domain.model.metadata.data.Data;
import dev.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
import dev.fitko.fitconnect.api.domain.model.metadata.data.SubmissionSchema;
import dev.fitko.fitconnect.api.domain.model.reply.replychannel.ReplyChannel;
import dev.fitko.fitconnect.api.domain.sender.SendableEncryptedSubmission;
import dev.fitko.fitconnect.api.domain.sender.SendableSubmission;
import dev.fitko.fitconnect.api.domain.subscriber.ReceivedSubmission;
import dev.fitko.fitconnect.api.exceptions.client.FitConnectSenderException;
import dev.fitko.fitconnect.api.services.crypto.CryptoService;
import dev.fitko.fitconnect.client.SenderClient;
import dev.fitko.fitconnect.client.SubscriberClient;
import dev.fitko.fitconnect.client.bootstrap.ClientFactory;
import dev.fitko.fitconnect.client.util.ReplyChannelKeyGenerator;
import dev.fitko.fitconnect.core.crypto.HashService;
import dev.fitko.fitconnect.core.crypto.JWECryptoService;
import dev.fitko.fitconnect.integrationtests.condition.EnableIfEnvironmentVariablesAreSet;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static dev.fitko.fitconnect.client.util.ResourceLoadingUtils.readResourceToString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isOneOf;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnableIfEnvironmentVariablesAreSet
public class SenderClientIT extends IntegrationTestBase {
@BeforeEach
public void cleanup() {
cleanupTestSubmissions();
}
@Test
void testSendAndConfirmCycleWithJsonData() {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final String submissionData = readResourceToString("/submission_data.json");
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromPath(Path.of("src/test/resources/attachment.txt"), "text/plain"))
.addAttachment(Attachment.fromByteArray("attachment data".getBytes(), "text/plain"))
.setReplyChannel(ReplyChannel.ofDeMail("test@mail.org"))
.setCallback(URI.create("https://example.callback.net"), "callbackSecretWithMoreThan32Chars")
.setAuthenticationInformation(List.of(new AuthenticationInformation("identificationReport", "1.0.0", "content")))
.build();
final var sentSubmission = ClientFactory.createSenderClient(config).send(submission);
assertNotNull(sentSubmission);
// When
final ReceivedSubmission receivedSubmission =
ClientFactory.createSubscriberClient(config)
.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission);
assertThat(receivedSubmission.getDataAsString(), is(submissionData));
assertThat(receivedSubmission.getDataSchemaUri(), is(URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json")));
assertThat(receivedSubmission.getDataMimeType(), is("application/json"));
assertThat(receivedSubmission.getServiceType().getIdentifier(), is("urn:de:fim:leika:leistung:99400048079000"));
assertThat(receivedSubmission.getAttachments(), hasSize(2));
assertThat(receivedSubmission.getMetadata().getReplyChannel(), is(ReplyChannel.ofDeMail("test@mail.org")));
assertThat(receivedSubmission.getAttachments().get(0).getDataAsString(), is("Test attachment"));
assertThat(receivedSubmission.getAttachments().get(0).getMimeType(), is("text/plain"));
}
@Test
void testSendAndConfirmCycleWithXmlData() throws IOException {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final String submissionData = readResourceToString("/submission_data.xml");
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setXmlData(submissionData, URI.create("urn:de:fim:leika:leistung:99400048079000"))
.addAttachment(Attachment.fromPath(Path.of("src/test/resources/attachment.txt"), "text/plain"))
.addAttachment(Attachment.fromByteArray("attachment data".getBytes(), "text/plain"))
.setReplyChannel(ReplyChannel.ofDeMail("test@mail.org"))
.setCallback(URI.create("https://example.callback.net"), "callBackSecretWithMoreThan32Chars")
.build();
final var sentSubmission = ClientFactory.createSenderClient(config).send(submission);
assertNotNull(sentSubmission);
// When
final ReceivedSubmission receivedSubmission =
ClientFactory.createSubscriberClient(config)
.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission);
assertThat(receivedSubmission.getDataAsString(), is(submissionData));
assertThat(receivedSubmission.getDataSchemaUri(), is(URI.create("urn:de:fim:leika:leistung:99400048079000")));
assertThat(receivedSubmission.getDataMimeType(), is("application/xml"));
assertThat(receivedSubmission.getAttachments(), hasSize(2));
assertThat(receivedSubmission.getMetadata().getReplyChannel(), is(ReplyChannel.ofDeMail("test@mail.org")));
assertThat(new String(receivedSubmission.getAttachments().get(0).getDataAsBytes()), is("Test attachment"));
}
@Test
void testNewSubmissionForExistingCaseWithFitConnectReplyChannel() {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final SenderClient senderClient = ClientFactory.createSenderClient(config);
final SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID"));
final String submissionData = readResourceToString("/submission_data.json");
final var firstSubmission = SendableSubmission.Builder()
.setDestination(destinationId)
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromPath(Path.of("src/test/resources/attachment.txt"), "text/plain"))
.build();
// When
final var sentFirstSubmission = senderClient.send(firstSubmission);
assertNotNull(sentFirstSubmission);
final var secondSubmissionForCase = SendableSubmission.Builder()
.setDestination(destinationId)
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.setCase(sentFirstSubmission.getCaseId())
.setReplyChannel(ReplyChannel.ofFitConnect(ReplyChannelKeyGenerator.generateKeyPair().getPublicKey(), List.of("https://test.fitko.de")))
.build();
final var sentSecondSubmission = senderClient.send(secondSubmissionForCase);
// Then
assertNotNull(secondSubmissionForCase);
assertThat(sentSecondSubmission.getCaseId(), is(sentFirstSubmission.getCaseId()));
// check if reply channel communication is possible by getting the encryption key
final ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(sentSecondSubmission.getSubmissionId());
final JWK encryptionPublicKey = receivedSubmission.getMetadata().getReplyChannel().getFitConnect().getEncryptionPublicKey().toJwk();
assertThat(encryptionPublicKey, is(secondSubmissionForCase.getReplyChannel().getFitConnect().getEncryptionPublicKey().toJwk()));
}
@Test
void testSendAndConfirmCycleWithEncryptedData() throws ParseException, IOException {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID"));
final CryptoService cryptoService = new JWECryptoService(new HashService());
final SenderClient senderClient = ClientFactory.createSenderClient(config);
final SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
final RSAKey encryptionKey = RSAKey.parse(senderClient.getPublicKeyForDestination(destinationId));
final String jsonData = readResourceToString("/submission_data.json");
final File attachmentFile = new File("src/test/resources/attachment.txt");
final String attachmentData = Files.readString(attachmentFile.toPath());
final String encryptedData = cryptoService.encryptBytes(encryptionKey, jsonData.getBytes(StandardCharsets.UTF_8), "application/json");
final String encryptedAttachment = cryptoService.encryptBytes(encryptionKey, attachmentData.getBytes(StandardCharsets.UTF_8), "text/plain");
final var submissionSchema = new SubmissionSchema();
submissionSchema.setSchemaUri(URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"));
submissionSchema.setMimeType(MimeType.APPLICATION_JSON);
final var dataHash = new Hash();
dataHash.setSignatureType(SignatureType.SHA_512);
dataHash.setContent(cryptoService.hashBytes(jsonData.getBytes(StandardCharsets.UTF_8)));
final var data = new Data();
data.setHash(dataHash);
data.setSubmissionSchema(submissionSchema);
final var attachment = new ApiAttachment();
attachment.setAttachmentId(UUID.randomUUID());
attachment.setPurpose(Purpose.ATTACHMENT);
attachment.setFilename(attachmentFile.getName());
attachment.setMimeType("text/plain");
final var attachmentHash = new Hash();
attachmentHash.setContent(cryptoService.hashBytes(attachmentData.getBytes(StandardCharsets.UTF_8)));
attachmentHash.setSignatureType(SignatureType.SHA_512);
attachment.setHash(attachmentHash);
final var contentStructure = new ContentStructure();
contentStructure.setAttachments(List.of(attachment));
contentStructure.setData(data);
final var metadata = new Metadata();
metadata.setSchema(config.getMetadataSchemaWriteVersion().toString());
metadata.setContentStructure(contentStructure);
final String encryptedMetadata = cryptoService.encryptObject(encryptionKey, metadata, "application/json");
// When
final var submission = SendableEncryptedSubmission.Builder()
.setDestination(destinationId)
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setEncryptedMetadata(encryptedMetadata)
.setEncryptedData(encryptedData)
.addEncryptedAttachment(attachment.getAttachmentId(), encryptedAttachment)
.build();
final var sentSubmission = senderClient.send(submission);
assertNotNull(sentSubmission);
final ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission);
assertThat(receivedSubmission.getDataAsString(), Matchers.is(jsonData));
assertThat(receivedSubmission.getDataMimeType(), Matchers.is("application/json"));
assertThat(receivedSubmission.getAttachments().get(0).getDataAsString(StandardCharsets.UTF_8), Matchers.is("Test attachment"));
}
@Test
void testNewEncryptedSubmissionForExistingCaseWithFitConnectReplyChannel() throws ParseException, IOException {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID"));
final CryptoService cryptoService = new JWECryptoService(new HashService());
final SenderClient senderClient = ClientFactory.createSenderClient(config);
final SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
final RSAKey encryptionKey = RSAKey.parse(senderClient.getPublicKeyForDestination(destinationId));
final String jsonData = readResourceToString("/submission_data.json");
final File attachmentFile = new File("src/test/resources/attachment.txt");
final String attachmentData = Files.readString(attachmentFile.toPath());
final String encryptedData = cryptoService.encryptBytes(encryptionKey, jsonData.getBytes(StandardCharsets.UTF_8), MimeType.APPLICATION_JSON.value());
final String encryptedAttachment = cryptoService.encryptBytes(encryptionKey, attachmentData.getBytes(StandardCharsets.UTF_8), "text/plain");
final var submissionSchema = new SubmissionSchema();
submissionSchema.setSchemaUri(URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"));
submissionSchema.setMimeType(MimeType.APPLICATION_JSON);
final var dataHash = new Hash();
dataHash.setSignatureType(SignatureType.SHA_512);
dataHash.setContent(cryptoService.hashBytes(jsonData.getBytes(StandardCharsets.UTF_8)));
final var data = new Data();
data.setHash(dataHash);
data.setSubmissionSchema(submissionSchema);
final var attachment = new ApiAttachment();
attachment.setAttachmentId(UUID.randomUUID());
attachment.setPurpose(Purpose.ATTACHMENT);
attachment.setFilename(attachmentFile.getName());
attachment.setMimeType("text/plain");
final var attachmentHash = new Hash();
attachmentHash.setContent(cryptoService.hashBytes(attachmentData.getBytes(StandardCharsets.UTF_8)));
attachmentHash.setSignatureType(SignatureType.SHA_512);
attachment.setHash(attachmentHash);
final var contentStructure = new ContentStructure();
contentStructure.setAttachments(List.of(attachment));
contentStructure.setData(data);
final var metadata = new Metadata();
metadata.setSchema(config.getMetadataSchemaWriteVersion().toString());
metadata.setContentStructure(contentStructure);
final var contentStructureForNewSubmission = new ContentStructure();
contentStructureForNewSubmission.setData(data);
final var metadataForNewSubmission = new Metadata();
metadataForNewSubmission.setSchema(config.getMetadataSchemaWriteVersion().toString());
metadataForNewSubmission.setContentStructure(contentStructureForNewSubmission);
metadataForNewSubmission.setReplyChannel(ReplyChannel.ofFitConnect(ReplyChannelKeyGenerator.generateKeyPair().getPublicKey(), List.of("https://test.fitko.de")));
final String encryptedMetadata = cryptoService.encryptBytes(encryptionKey, new ObjectMapper().writeValueAsBytes(metadata), MimeType.APPLICATION_JSON.value());
final String encryptedMetadataForNewSubmission = cryptoService.encryptBytes(encryptionKey, new ObjectMapper().writeValueAsBytes(metadataForNewSubmission), MimeType.APPLICATION_JSON.value());
// When
final var initialSubmission = SendableEncryptedSubmission.Builder()
.setDestination(destinationId)
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setEncryptedMetadata(encryptedMetadata)
.setEncryptedData(encryptedData)
.addEncryptedAttachment(attachment.getAttachmentId(), encryptedAttachment)
.build();
final var sentInitialSubmission = senderClient.send(initialSubmission);
assertNotNull(sentInitialSubmission);
final var secondSubmissionForExistingCase = SendableEncryptedSubmission.Builder()
.setDestination(destinationId)
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setEncryptedMetadata(encryptedMetadataForNewSubmission)
.setEncryptedData(encryptedData)
.setCase(sentInitialSubmission.getCaseId())
.build();
// Then
final var sentSecondSubmissionForExistingCase = senderClient.send(secondSubmissionForExistingCase);
assertNotNull(sentSecondSubmissionForExistingCase);
final ReceivedSubmission receivedNewSubmissionForCase = subscriberClient.requestSubmission(sentSecondSubmissionForExistingCase.getSubmissionId());
assertNotNull(sentSecondSubmissionForExistingCase);
final JWK encryptionPublicKey = receivedNewSubmissionForCase.getMetadata().getReplyChannel().getFitConnect().getEncryptionPublicKey().toJwk();
assertThat(encryptionPublicKey, is(metadataForNewSubmission.getReplyChannel().getFitConnect().getEncryptionPublicKey().toJwk()));
}
@Test
void testSubmissionDataValidationFromLocalSchemaFile(@TempDir final Path tempDir) throws IOException {
// Given
// Prepare locally set submission data schema in given path
final String schemaResource = readResourceToString("/submission-data-schema/submission_data_schema.json");
final Path schemaPath = Files.writeString(Path.of(tempDir.toString(), "submission_data_schema.json"), schemaResource);
final String schemaUri = "https://schema.fitko.de/fim/s00000114_1.1.schema.json";
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment(true, Map.of(schemaUri, schemaPath.toString()));
final String submissionData = readResourceToString("/submission_data.json");
final URI submissionDataSchemaUri = URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json");
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, submissionDataSchemaUri)
.addAttachment(Attachment.fromPath(Path.of("src/test/resources/attachment.txt"), "text/plain"))
.addAttachment(Attachment.fromByteArray("attachment data".getBytes(), "text/plain"))
.setReplyChannel(ReplyChannel.ofDeMail("test@mail.org"))
.build();
// When
final var sentSubmission = ClientFactory.createSenderClient(config).send(submission);
// Then
assertNotNull(sentSubmission);
}
@Test
void testAbortedSendSubmissionWithKeyValidationNotSilent() {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment(false);
// When
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(readResourceToString("/submission_data.json"), URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.build();
final FitConnectSenderException exception = assertThrows(FitConnectSenderException.class, () -> ClientFactory.createSenderClient(config).send(submission));
// Then
assertThat(exception.getMessage(), containsString("Invalid public encryption key"));
assertThat(exception.getCause().getMessage(), containsString("JWK with id jsMQHFiA2uMGtiG3Ro8RJnYdEhp5W5KjGW-Vcf3-YMk has an invalid amount of certificates. Is 1 but should be 3."));
}
@Test
void testReadSubmissionStatus() {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final String submissionData = readResourceToString("/submission_data.json");
final SenderClient senderClient = ClientFactory.createSenderClient(config);
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromPath(Path.of("src/test/resources/attachment.txt"), "plain/text"))
.build();
final var sentSubmission = senderClient.send(submission);
assertNotNull(sentSubmission);
final Status statusForSubmission = senderClient.getSubmissionStatus(sentSubmission);
assertThat(statusForSubmission.getState(), isOneOf(Event.SUBMIT_SUBMISSION.getState(), Event.NOTIFY_SUBMISSION.getState()));
assertThat(statusForSubmission.getIssuer(), containsString("https://test.fit-connect.fitko.dev"));
}
@Test
void testSendSubmissionWithAdditionalReferenceInfo() {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment(true);
final String submissionData = readResourceToString("/submission_data.json");
final LocalDate applicationDate = LocalDate.of(2020, 1, 1);
final UUID idBundDeApplicationId = UUID.randomUUID();
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.setApplicationDate(applicationDate)
.setIdBundDeApplicationId(idBundDeApplicationId)
.build();
final var sentSubmission = ClientFactory.createSenderClient(config).send(submission);
assertNotNull(sentSubmission);
// When
final ReceivedSubmission receivedSubmission =
ClientFactory.createSubscriberClient(config)
.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission);
assertTrue(receivedSubmission.getApplicationDate().isPresent());
assertThat(receivedSubmission.getApplicationDate().get(), is(applicationDate));
assertThat(receivedSubmission.getMetadata().getAdditionalReferenceInfo().getIdBundDeApplicationId(), is(idBundDeApplicationId));
}
@Test
void testSendSubmissionWithAdditionalReferenceInfoAndBundIdReplyChannel() {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment(true);
final String submissionData = readResourceToString("/submission_data.json");
final UUID idBundDeApplicationId = UUID.randomUUID();
final UUID mailboxId = UUID.randomUUID();
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.setReplyChannel(ReplyChannel.ofIdBundDeMailbox(mailboxId))
.setIdBundDeApplicationId(idBundDeApplicationId)
.build();
final var sentSubmission = ClientFactory.createSenderClient(config).send(submission);
assertNotNull(sentSubmission);
// When
final ReceivedSubmission receivedSubmission =
ClientFactory.createSubscriberClient(config)
.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission.getMetadata().getReplyChannel());
assertNotNull(receivedSubmission.getMetadata().getAdditionalReferenceInfo());
assertTrue(receivedSubmission.getMetadata().getReplyChannel().isIdBundDeMailbox());
assertThat(receivedSubmission.getMetadata().getReplyChannel().getIdBundDeMailbox().getMailboxUuid(), is(mailboxId));
assertThat(receivedSubmission.getMetadata().getAdditionalReferenceInfo().getIdBundDeApplicationId(), is(idBundDeApplicationId));
}
@Test
void testSendSubmissionWithChunkedAttachments(@TempDir Path attachmentStoragePath) throws IOException {
// Given
final AttachmentChunkingConfig chunkingConfig = AttachmentChunkingConfig.builder()
.chunkAllAttachments(true)
.chunkSizeInMB(1)
.attachmentStoragePath(attachmentStoragePath)
.build();
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment(true, chunkingConfig);
final SenderClient senderClient = ClientFactory.createSenderClient(config);
final Path attachmentPath = Path.of("src/test/resources/large-pdf.pdf");
final byte[] expectedAttachmentData = Files.readAllBytes(attachmentPath);
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(readResourceToString("/submission_data.json"), URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromLargeAttachment(attachmentPath, "application/pdf", "large-pdf_1.pdf", "test large pdf"))
.addAttachment(Attachment.fromPath(attachmentPath, "application/pdf", "large-pdf_3.pdf", "test in-memory pdf"))
.build();
final var sentSubmission = senderClient.send(submission);
assertNotNull(sentSubmission);
// When
final ReceivedSubmission receivedSubmission =
ClientFactory.createSubscriberClient(config)
.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission);
assertThat(receivedSubmission.getAttachments(), hasSize(2));
assertArrayEquals(expectedAttachmentData, receivedSubmission.getAttachments().get(0).getDataAsBytes());
assertArrayEquals(expectedAttachmentData, receivedSubmission.getAttachments().get(1).getDataAsBytes());
// chunking all attachments will lead to attachments that are all stored in filesystem
assertTrue(receivedSubmission.getAttachments().get(0).isLargeAttachment());
assertTrue(receivedSubmission.getAttachments().get(1).isLargeAttachment());
senderClient.clearAttachmentStorage();
assertThat(attachmentStoragePath.toFile().listFiles().length, is(0));
}
@Test
void testSendSubmissionWithDefaultChunkingForLargeAttachmentsOnly() throws IOException {
// Given
final AttachmentChunkingConfig chunkingConfig = AttachmentChunkingConfig.builder()
.chunkAllAttachments(false)
.chunkSizeInMB(1)
.build();
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment(true, chunkingConfig);
final Path attachmentPath = Path.of("src/test/resources/large-pdf.pdf");
final byte[] expectedAttachmentData = Files.readAllBytes(attachmentPath);
final var submission = SendableSubmission.Builder()
.setDestination(UUID.fromString(System.getenv("TEST_DESTINATION_ID")))
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(readResourceToString("/submission_data.json"), URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromLargeAttachment(attachmentPath, "application/pdf", "large-pdf_1.pdf", "test large pdf"))
.addAttachment(Attachment.fromPath(attachmentPath, "application/pdf", "large-pdf_3.pdf", "test in-memory pdf"))
.build();
final var sentSubmission = ClientFactory.createSenderClient(config).send(submission);
assertNotNull(sentSubmission);
// When
final ReceivedSubmission receivedSubmission =
ClientFactory.createSubscriberClient(config)
.requestSubmission(sentSubmission.getSubmissionId());
// Then
assertNotNull(receivedSubmission);
assertThat(receivedSubmission.getAttachments(), hasSize(2));
assertArrayEquals(expectedAttachmentData, receivedSubmission.getAttachments().get(0).getDataAsBytes());
assertArrayEquals(expectedAttachmentData, receivedSubmission.getAttachments().get(1).getDataAsBytes());
assertTrue(receivedSubmission.getAttachments().get(0).isLargeAttachment());
assertTrue(receivedSubmission.getAttachments().get(1).isInMemoryAttachment());
}
@Test
void testMultiThreadExecution() throws InterruptedException {
// Given
final ApplicationConfig config = getConfigWithCredentialsFromEnvironment();
final SenderClient senderClient = ClientFactory.createSenderClient(config);
final SubscriberClient subscriberClient = ClientFactory.createSubscriberClient(config);
final String submissionData = readResourceToString("/submission_data.json");
final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID"));
final var submission = SendableSubmission.Builder()
.setDestination(destinationId)
.setServiceType("urn:de:fim:leika:leistung:99400048079000", "Test Service")
.setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"))
.addAttachment(Attachment.fromPath(Path.of("src/test/resources/attachment.txt"), "plain/text"))
.build();
// When
final ExecutorService es = Executors.newFixedThreadPool(5);
for (int i = 0; i < 25; i++) {
es.execute(new SenderRunner(senderClient, submission, "Thread-" + i));
}
es.shutdown();
es.awaitTermination(1, TimeUnit.MINUTES);
// wait for ZSD processing
Thread.sleep(5000);
final int handedInSubmissions = subscriberClient.getAvailableSubmissionsForDestination(destinationId).size();
// Then
assertThat(handedInSubmissions, is(25));
}
static class SenderRunner implements Runnable {
private final SenderClient senderClient;
private final SendableSubmission submission;
private final String threadName;
SenderRunner(final SenderClient senderClient, final SendableSubmission submission, final String threadName) {
this.senderClient = senderClient;
this.submission = submission;
this.threadName = threadName;
System.out.println("Creating " + threadName);
}
public void run() {
System.out.println("Running " + threadName);
assertNotNull(senderClient.send(submission));
System.out.println("Thread " + threadName + " exiting.");
}
}
}