package dev.fitko.fitconnect.integrationtests; import dev.fitko.fitconnect.api.config.ApplicationConfig; import dev.fitko.fitconnect.api.domain.model.event.Event; import dev.fitko.fitconnect.api.domain.model.event.SubmissionState; import dev.fitko.fitconnect.api.domain.model.event.SubmissionStatus; import dev.fitko.fitconnect.api.domain.model.event.problems.data.DataEncryptionIssue; import dev.fitko.fitconnect.api.domain.model.event.problems.data.IncorrectDataAuthenticationTag; import dev.fitko.fitconnect.api.domain.model.event.problems.submission.InvalidEventLog; import dev.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup; import dev.fitko.fitconnect.api.exceptions.RestApiException; import dev.fitko.fitconnect.api.exceptions.SubmissionRequestException; import dev.fitko.fitconnect.client.SenderClient; import dev.fitko.fitconnect.client.SubscriberClient; import dev.fitko.fitconnect.client.factory.ClientFactory; import dev.fitko.fitconnect.client.sender.model.Attachment; import dev.fitko.fitconnect.client.sender.model.SendableSubmission; import dev.fitko.fitconnect.client.subscriber.ReceivedSubmission; import dev.fitko.fitconnect.integrationtests.condition.EnableIfEnvironmentVariablesAreSet; import org.awaitility.Awaitility; import org.hamcrest.Matchers; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.IOException; import java.net.URI; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.time.Duration; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; 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 SubscriberClientIT extends IntegrationTestBase { @BeforeEach public void cleanup() { cleanupTestSubmissions(); } @Test void testListSubmissionsForDestination() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final var senderClient = ClientFactory.getSenderClient(config); final var subscriberClient = ClientFactory.getSubscriberClient(config); final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID")); final String leikaKey = "urn:de:fim:leika:leistung:99400048079000"; final String serviceName = "Test Service"; final String submissionData = getResourceAsString("/submission_data.json"); final URI submissionDataSchemaUri = URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json"); final var submissionOne = SendableSubmission.Builder() .setDestination(destinationId) .setServiceType(leikaKey, serviceName) .setJsonData(submissionData, submissionDataSchemaUri) .build(); final var submissionTwo = SendableSubmission.Builder() .setDestination(destinationId) .setServiceType(leikaKey, serviceName) .setJsonData(submissionData, submissionDataSchemaUri) .build(); final var sentSubmissionOne = senderClient.send(submissionOne); final var sentSubmissionTwo = senderClient.send(submissionTwo); assertNotNull(sentSubmissionOne); assertNotNull(sentSubmissionTwo); // When final Set<SubmissionForPickup> submissions = subscriberClient.getAvailableSubmissionsForDestination(destinationId); // Then Assertions.assertFalse(submissions.isEmpty()); final List<UUID> submissionIds = submissions.stream().map(SubmissionForPickup::getSubmissionId).collect(Collectors.toList()); assertThat(submissionIds, Matchers.hasItems(sentSubmissionOne.getSubmissionId(), sentSubmissionTwo.getSubmissionId())); // remove by confirming subscriberClient.requestSubmission(sentSubmissionOne.getSubmissionId()).acceptSubmission(); subscriberClient.requestSubmission(sentSubmissionTwo.getSubmissionId()).acceptSubmission(); } @Test void testReceiveSingleSubmission() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final var senderClient = ClientFactory.getSenderClient(config); final var subscriberClient = ClientFactory.getSubscriberClient(config); final UUID destinationId = UUID.fromString(System.getenv("TEST_DESTINATION_ID")); final String leikaKey = "urn:de:fim:leika:leistung:99400048079000"; final String serviceName = "Test Service"; final String submissionData = getResourceAsString("/submission_data.json"); final var submission = SendableSubmission.Builder() .setDestination(destinationId) .setServiceType(leikaKey, serviceName) .setJsonData(submissionData, URI.create("https://schema.fitko.de/fim/s00000114_1.1.schema.json")) .addAttachment(Attachment.fromString("foo", "plain/text")) .build(); final var sentSubmission = senderClient.send(submission); assertNotNull(sentSubmission); // When final ReceivedSubmission receivedSubmission = subscriberClient.requestSubmission(sentSubmission.getSubmissionId()); // Then assertNotNull(receivedSubmission); assertThat(receivedSubmission.getAttachments(), hasSize(1)); assertThat(receivedSubmission.getAttachments().get(0).getDataAString(StandardCharsets.UTF_8), is("foo")); assertThat(receivedSubmission.getDataAsString(), is(submissionData)); } @Test void testRejectEvent() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final String submissionData = getResourceAsString("/submission_data.json"); final SenderClient senderClient = ClientFactory.getSenderClient(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); // When final var subscriberClient = ClientFactory.getSubscriberClient(config); final var sentSubmissionId = sentSubmission.getSubmissionId(); // reject and remove subscriberClient.requestSubmission(sentSubmissionId).rejectSubmission(List.of(new DataEncryptionIssue())); // check event log if reject event was sent final SubmissionStatus status = senderClient.getStatusForSubmission(sentSubmission); assertThat(status.getStatus(), is(SubmissionState.REJECTED)); // second attempt to receive and reject the submission should return an empty result // since the submission is gone after being rejected final SubmissionRequestException exception = assertThrows(SubmissionRequestException.class, () -> subscriberClient.requestSubmission(sentSubmissionId)); assertThat(exception.getCause(), instanceOf(RestApiException.class)); assertThat(((RestApiException) exception.getCause()).getStatusCode(), is(404)); } @Test void testAcceptEvent() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final String submissionData = getResourceAsString("/submission_data.json"); final SenderClient senderClient = ClientFactory.getSenderClient(config); final SubscriberClient subscriberClient = ClientFactory.getSubscriberClient(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); Assertions.assertNotNull(sentSubmission); // When final var sentSubmissionId = sentSubmission.getSubmissionId(); // accept and remove subscriberClient.requestSubmission(sentSubmissionId).acceptSubmission(); // check event log if accept event was sent final SubmissionStatus status = senderClient.getStatusForSubmission(sentSubmission); assertThat(status.getStatus(), is(SubmissionState.ACCEPTED)); // second attempt to receive the submission should return an empty result // since the submission is gone after being accepted final SubmissionRequestException exception = assertThrows(SubmissionRequestException.class, () -> subscriberClient.requestSubmission(sentSubmissionId)); assertThat(exception.getCause(), instanceOf(RestApiException.class)); assertThat(((RestApiException) exception.getCause()).getStatusCode(), is(404)); } @Test void testAcceptEventWithProblem() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final String submissionData = getResourceAsString("/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"), "plain/text")) .build(); final SenderClient senderClient = ClientFactory.getSenderClient(config); final var subscriberClient = ClientFactory.getSubscriberClient(config); final var sentSubmission = senderClient.send(submission); assertNotNull(sentSubmission); // When final var sentSubmissionId = sentSubmission.getSubmissionId(); // accept and remove subscriberClient.requestSubmission(sentSubmissionId).acceptSubmission(new IncorrectDataAuthenticationTag()); // check event log if accept event was sent and contains a problem // check event log if accept event was sent final SubmissionStatus status = senderClient.getStatusForSubmission(sentSubmission); assertThat(status.getStatus(), is(SubmissionState.ACCEPTED)); // second attempt to receive the submission should return an empty result // since the submission is gone after being accepted final SubmissionRequestException exception = assertThrows(SubmissionRequestException.class, () -> subscriberClient.requestSubmission(sentSubmissionId)); assertThat(exception.getCause(), instanceOf(RestApiException.class)); assertThat(((RestApiException) exception.getCause()).getStatusCode(), is(404)); } @Test void testRejectEventViaClient() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final String submissionData = getResourceAsString("/submission_data.json"); final SenderClient senderClient = ClientFactory.getSenderClient(config); final SubscriberClient subscriberClient = ClientFactory.getSubscriberClient(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"), "text/plain")) .build(); final var sentSubmission = senderClient.send(submission); assertNotNull(sentSubmission); // When final Optional<SubmissionForPickup> submissionForPickup = subscriberClient.getAvailableSubmissionsForDestination(submission.getDestinationId()) .stream().filter(s -> s.getSubmissionId().equals(sentSubmission.getSubmissionId())) .findFirst(); assertTrue(submissionForPickup.isPresent()); subscriberClient.rejectSubmission(submissionForPickup.get(), List.of(new InvalidEventLog())); // simulate some waiting time for e.g. persistence await().atLeast(Duration.ofSeconds(2)); // Then assertThat(senderClient.getStatusForSubmission(sentSubmission).getStatus(), is(SubmissionState.REJECTED)); // second attempt to receive and reject the submission should return an empty result since the submission is gone after being rejected final SubmissionRequestException exception = assertThrows(SubmissionRequestException.class, () -> subscriberClient.requestSubmission(sentSubmission.getSubmissionId())); assertThat(exception.getCause(), instanceOf(RestApiException.class)); assertThat(((RestApiException) exception.getCause()).getStatusCode(), is(404)); } @Test void testReadSubmissionStatus() throws IOException { // Given final ApplicationConfig config = getConfigWithCredentialsFromEnvironment("TESTING", true); final String submissionData = getResourceAsString("/submission_data.json"); final SenderClient senderClient = ClientFactory.getSenderClient(config); final SubscriberClient subscriberClient = ClientFactory.getSubscriberClient(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); Assertions.assertNotNull(sentSubmission); Awaitility.await().atMost(Duration.ofSeconds(30)).until(() -> { // When final SubmissionStatus statusForSubmission = subscriberClient.getStatusForSubmission(sentSubmission.getDestinationId(), sentSubmission.getCaseId(), sentSubmission.getSubmissionId()); // Then return statusForSubmission.getStatus().equals(Event.SUBMIT.getState()); }); } }