diff --git a/feasibility-dsf-process-docker-test-setup/docker-compose.yml b/feasibility-dsf-process-docker-test-setup/docker-compose.yml index 627e135..6569bfe 100755 --- a/feasibility-dsf-process-docker-test-setup/docker-compose.yml +++ b/feasibility-dsf-process-docker-test-setup/docker-compose.yml @@ -551,7 +551,7 @@ services: # ---- DIC-2 - FHIR Data Store ---------------------------------------------- dic-2-store: - image: samply/blaze:0.22.3 + image: samply/blaze:0.23 restart: on-failure healthcheck: test: [ "CMD", "curl", "http://localhost:8080/health" ] @@ -734,7 +734,7 @@ services: # ---- DIC-3 - FHIR Data Store ---------------------------------------------- dic-3-store: - image: samply/blaze:0.22.3 + image: samply/blaze:0.23 restart: on-failure healthcheck: test: [ "CMD", "curl", "http://localhost:8080/health" ] diff --git a/feasibility-dsf-process/src/main/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResources.java b/feasibility-dsf-process/src/main/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResources.java index dd9743d..43275ad 100755 --- a/feasibility-dsf-process/src/main/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResources.java +++ b/feasibility-dsf-process/src/main/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResources.java @@ -1,13 +1,12 @@ package de.medizininformatik_initiative.feasibility_dsf_process.service; -import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.client.api.IGenericClient; -import de.medizininformatik_initiative.feasibility_dsf_process.variables.ConstantsFeasibility; import dev.dsf.bpe.v1.ProcessPluginApi; import dev.dsf.bpe.v1.activity.AbstractServiceDelegate; import dev.dsf.bpe.v1.variables.Variables; import org.camunda.bpm.engine.delegate.DelegateExecution; -import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Library; import org.hl7.fhir.r4.model.Measure; import org.slf4j.Logger; @@ -16,8 +15,9 @@ import java.util.Objects; -import static de.medizininformatik_initiative.feasibility_dsf_process.variables.ConstantsFeasibility.VARIABLE_LIBRARY; -import static de.medizininformatik_initiative.feasibility_dsf_process.variables.ConstantsFeasibility.VARIABLE_MEASURE; +import static de.medizininformatik_initiative.feasibility_dsf_process.variables.ConstantsFeasibility.*; +import static org.hl7.fhir.r4.model.Bundle.BundleType.TRANSACTION; +import static org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST; public class StoreFeasibilityResources extends AbstractServiceDelegate implements InitializingBean { @@ -49,21 +49,21 @@ protected void doExecute(DelegateExecution execution, Variables variables) { cleaner.cleanLibrary(library); cleaner.cleanMeasure(measure); - var libraryRes = storeLibraryResource(library); - var measureRes = storeMeasureResource(measure, libraryRes.getId()); + var transactionResponse = storeResources(measure, library); - variables.setString(ConstantsFeasibility.VARIABLE_MEASURE_ID, measureRes.getId().getIdPart()); + variables.setString(VARIABLE_MEASURE_ID, extractMeasureId(transactionResponse)); } - private MethodOutcome storeLibraryResource(Library library) { - logger.info("Store Library `{}`", library.getId()); - return storeClient.create().resource(library).execute(); + private Bundle storeResources(Measure measure, Library library) { + logger.info("Store Measure `{}` and Library `{}`", measure.getId(), library.getUrl()); + + Bundle bundle = new Bundle().setType(TRANSACTION); + bundle.addEntry().setResource(measure).getRequest().setMethod(POST).setUrl("Measure"); + bundle.addEntry().setResource(library).getRequest().setMethod(POST).setUrl("Library"); + return storeClient.transaction().withBundle(bundle).execute(); } - private MethodOutcome storeMeasureResource(Measure measure, IIdType libraryId) { - logger.info("Store Measure `{}`", measure.getId()); - measure.getLibrary().clear(); - measure.addLibrary("Library/" + libraryId.getIdPart()); - return storeClient.create().resource(measure).execute(); + private String extractMeasureId(Bundle transactionResponse) { + return new IdType(transactionResponse.getEntryFirstRep().getResponse().getLocation()).getIdPart(); } } diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/Assertions.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/Assertions.java new file mode 100644 index 0000000..e69be92 --- /dev/null +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/Assertions.java @@ -0,0 +1,19 @@ +package de.medizininformatik_initiative.feasibility_dsf_process; + +import org.hl7.fhir.r4.model.Base; +import org.hl7.fhir.r4.model.Bundle; + +public interface Assertions { + + static BaseAssert assertThat(Base actual) { + return new BaseAssert(actual); + } + + static BundleAssert assertThat(Bundle actual) { + return new BundleAssert(actual); + } + + static BundleEntryRequestComponentAssert assertThat(Bundle.BundleEntryRequestComponent actual) { + return new BundleEntryRequestComponentAssert(actual); + } +} diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BaseAssert.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BaseAssert.java new file mode 100644 index 0000000..1c0f92a --- /dev/null +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BaseAssert.java @@ -0,0 +1,20 @@ +package de.medizininformatik_initiative.feasibility_dsf_process; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.Condition; +import org.hl7.fhir.r4.model.Base; + +public class BaseAssert extends AbstractAssert { + + protected BaseAssert(Base actual) { + super(actual, BaseAssert.class); + } + + private static Condition deepEqualTo(Base expected) { + return new Condition<>(base -> base.equalsDeep(expected), "deep equal to " + expected); + } + + public BaseAssert isDeepEqualTo(Base expected) { + return is(deepEqualTo(expected)); + } +} diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BundleAssert.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BundleAssert.java new file mode 100644 index 0000000..48ce212 --- /dev/null +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BundleAssert.java @@ -0,0 +1,20 @@ +package de.medizininformatik_initiative.feasibility_dsf_process; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.Condition; +import org.hl7.fhir.r4.model.Bundle; + +public class BundleAssert extends AbstractAssert { + + protected BundleAssert(Bundle actual) { + super(actual, BundleAssert.class); + } + + public BundleAssert hasType(String type) { + return has(type(type)); + } + + private static Condition type(String type) { + return new Condition<>(bundle -> bundle.getType().toCode().equals(type), "of type " + type); + } +} diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BundleEntryRequestComponentAssert.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BundleEntryRequestComponentAssert.java new file mode 100644 index 0000000..0ed87f7 --- /dev/null +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/BundleEntryRequestComponentAssert.java @@ -0,0 +1,30 @@ +package de.medizininformatik_initiative.feasibility_dsf_process; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.Condition; +import org.hl7.fhir.r4.model.Bundle; + + +public class BundleEntryRequestComponentAssert extends AbstractAssert { + + protected BundleEntryRequestComponentAssert(Bundle.BundleEntryRequestComponent actual) { + super(actual, BundleEntryRequestComponentAssert.class); + } + + public BundleEntryRequestComponentAssert hasMethod(Bundle.HTTPVerb method) { + return has(method(method)); + } + + private static Condition method(Bundle.HTTPVerb method) { + return new Condition<>(bundle -> bundle.getMethod() == method, "of method " + method); + } + + public BundleEntryRequestComponentAssert hasUrl(String url) { + return has(url(url)); + } + + private static Condition url(String url) { + return new Condition<>(bundle -> bundle.getUrl().equals(url), "of URL " + url); + } +} diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/flare/FlareWebserviceClientImplBaseIT.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/flare/FlareWebserviceClientImplBaseIT.java index 0d45968..ebb7c1f 100644 --- a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/flare/FlareWebserviceClientImplBaseIT.java +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/flare/FlareWebserviceClientImplBaseIT.java @@ -15,7 +15,7 @@ public abstract class FlareWebserviceClientImplBaseIT { @Container public static GenericContainer fhirServer = new GenericContainer<>( - DockerImageName.parse("samply/blaze:0.23.0")) + DockerImageName.parse("samply/blaze:0.23")) .withExposedPorts(8080) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withNetworkAliases("fhir-server") diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/store/StoreClientIT.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/store/StoreClientIT.java index bca6a64..b33daf4 100644 --- a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/store/StoreClientIT.java +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/client/store/StoreClientIT.java @@ -53,7 +53,7 @@ public class StoreClientIT { private static final Network DEFAULT_CONTAINER_NETWORK = Network.newNetwork(); @Container - public GenericContainer fhirServer = new GenericContainer<>(DockerImageName.parse("samply/blaze:0.23.0")) + public GenericContainer fhirServer = new GenericContainer<>(DockerImageName.parse("samply/blaze:0.23")) .withExposedPorts(8080) .withNetwork(DEFAULT_CONTAINER_NETWORK) .withNetworkAliases("fhir-server") diff --git a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResourcesTest.java b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResourcesTest.java index 9fda4ae..481d71e 100644 --- a/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResourcesTest.java +++ b/feasibility-dsf-process/src/test/java/de/medizininformatik_initiative/feasibility_dsf_process/service/StoreFeasibilityResourcesTest.java @@ -1,22 +1,18 @@ package de.medizininformatik_initiative.feasibility_dsf_process.service; -import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.client.api.IGenericClient; import dev.dsf.bpe.v1.variables.Variables; import org.camunda.bpm.engine.delegate.DelegateExecution; -import org.hl7.fhir.r4.model.IdType; -import org.hl7.fhir.r4.model.Library; -import org.hl7.fhir.r4.model.Measure; -import org.hl7.fhir.r4.model.Resource; +import org.hl7.fhir.r4.model.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Answers; -import org.mockito.InjectMocks; -import org.mockito.Mock; +import org.mockito.*; import org.mockito.junit.jupiter.MockitoExtension; import static de.medizininformatik_initiative.feasibility_dsf_process.variables.ConstantsFeasibility.*; -import static org.mockito.ArgumentMatchers.any; +import static org.assertj.core.api.Assertions.assertThat; +import static de.medizininformatik_initiative.feasibility_dsf_process.Assertions.assertThat; +import static org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -32,6 +28,9 @@ public class StoreFeasibilityResourcesTest { @Mock private FeasibilityResourceCleaner cleaner; + @Captor + private ArgumentCaptor transactionBundleCaptor; + @Mock private DelegateExecution execution; @@ -45,20 +44,29 @@ public class StoreFeasibilityResourcesTest { public void testDoExecute() { var measure = new Measure(); var library = new Library(); + var transactionResponse = new Bundle(); + transactionResponse.addEntry().getResponse().setLocation("Measure/" + MEASURE_ID); library.getContentFirstRep().setContentType("text/cql"); when(variables.getResource(VARIABLE_MEASURE)).thenReturn(measure); when(variables.getResource(VARIABLE_LIBRARY)).thenReturn(library); - - var libraryMethodOutcome = new MethodOutcome(new IdType(LIBRARY_ID)); - var measureMethodOutcome = new MethodOutcome(new IdType(MEASURE_ID)); - - when(storeClient.create().resource(any(Resource.class)).execute()) - .thenReturn(libraryMethodOutcome, measureMethodOutcome); + when(storeClient.transaction().withBundle(transactionBundleCaptor.capture()).execute()).thenReturn(transactionResponse); service.doExecute(execution, variables); verify(cleaner).cleanLibrary(library); verify(cleaner).cleanMeasure(measure); + assertThat(transactionBundleCaptor.getValue()).hasType("transaction"); + assertThat(transactionBundleCaptor.getValue().getEntry()).hasSize(2); + assertThat(transactionBundleCaptor.getValue().getEntry().get(0).getResource()) + .isDeepEqualTo(measure); + assertThat(transactionBundleCaptor.getValue().getEntry().get(0).getRequest()) + .hasMethod(POST) + .hasUrl("Measure"); + assertThat(transactionBundleCaptor.getValue().getEntry().get(1).getResource()) + .isDeepEqualTo(library); + assertThat(transactionBundleCaptor.getValue().getEntry().get(1).getRequest()) + .hasMethod(POST) + .hasUrl("Library"); verify(variables).setString(VARIABLE_MEASURE_ID, MEASURE_ID); } }