From a2aa2ca1c37ec9f171285c0ef8d3502448c8b37e Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Thu, 29 Jul 2021 15:52:09 -0400 Subject: [PATCH 01/46] 2849 Added new parameter to MDM processing --- .../ca/uhn/fhir/interceptor/api/Pointcut.java | 6 +- .../jpa/mdm/broker/MdmMessageHandler.java | 18 ++++-- .../fhir/jpa/mdm/svc/MdmEidUpdateService.java | 2 + .../uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java | 5 ++ .../fhir/jpa/mdm/helper/BaseMdmHelper.java | 3 + .../interceptor/MdmStorageInterceptorIT.java | 26 +++++++++ .../uhn/fhir/mdm/api/MdmLinkChangeEvent.java | 55 +++++++++++++++++++ .../fhir/mdm/model/MdmTransactionContext.java | 11 ++++ 8 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java index db6dff8b7a1..d8f0f33ae9f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java @@ -1986,13 +1986,17 @@ public enum Pointcut implements IPointcut { * *

*

* Hooks should return void. *

*/ - MDM_AFTER_PERSISTED_RESOURCE_CHECKED(void.class, "ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage", "ca.uhn.fhir.rest.server.TransactionLogMessages"), + MDM_AFTER_PERSISTED_RESOURCE_CHECKED(void.class, + "ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage", + "ca.uhn.fhir.rest.server.TransactionLogMessages", + "ca.uhn.fhir.mdm.api.MdmLinkChangeEvent"), /** * Performance Tracing Hook: diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java index 3a84eebb083..b80d2caafc7 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java @@ -30,12 +30,15 @@ import ca.uhn.fhir.jpa.mdm.svc.candidate.TooManyCandidatesException; import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage; import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage; import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.rest.server.TransactionLogMessages; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage; import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.Message; @@ -89,11 +92,11 @@ public class MdmMessageHandler implements MessageHandler { try { switch (theMsg.getOperationType()) { case CREATE: - handleCreatePatientOrPractitioner(theMsg, mdmContext); + handleCreateResource(theMsg, mdmContext); break; case UPDATE: case MANUALLY_TRIGGERED: - handleUpdatePatientOrPractitioner(theMsg, mdmContext); + handleUpdateResource(theMsg, mdmContext); break; case DELETE: default: @@ -105,12 +108,15 @@ public class MdmMessageHandler implements MessageHandler { } finally { // Interceptor call: MDM_AFTER_PERSISTED_RESOURCE_CHECKED - ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, theMsg.getPayload(myFhirContext), theMsg.getOperationType()); + IBaseResource targetResource = theMsg.getPayload(myFhirContext); + ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType()); outgoingMsg.setTransactionId(theMsg.getTransactionId()); HookParams params = new HookParams() .add(ResourceOperationMessage.class, outgoingMsg) - .add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages()); + .add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages()) + .add(MdmLinkChangeEvent.class, mdmContext.getMdmLinkChangeEvent()); + myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params); } } @@ -142,7 +148,7 @@ public class MdmMessageHandler implements MessageHandler { } } - private void handleCreatePatientOrPractitioner(ResourceModifiedMessage theMsg, MdmTransactionContext theMdmTransactionContext) { + private void handleCreateResource(ResourceModifiedMessage theMsg, MdmTransactionContext theMdmTransactionContext) { myMdmMatchLinkSvc.updateMdmLinksForMdmSource(getResourceFromPayload(theMsg), theMdmTransactionContext); } @@ -150,7 +156,7 @@ public class MdmMessageHandler implements MessageHandler { return (IAnyResource) theMsg.getNewPayload(myFhirContext); } - private void handleUpdatePatientOrPractitioner(ResourceModifiedMessage theMsg, MdmTransactionContext theMdmTransactionContext) { + private void handleUpdateResource(ResourceModifiedMessage theMsg, MdmTransactionContext theMdmTransactionContext) { myMdmMatchLinkSvc.updateMdmLinksForMdmSource(getResourceFromPayload(theMsg), theMdmTransactionContext); } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java index 94db6849073..d23c27db9f1 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java @@ -85,6 +85,8 @@ public class MdmEidUpdateService { myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext); myMdmResourceDaoSvc.upsertGoldenResource(updateContext.getMatchedGoldenResource(), theMdmTransactionContext.getResourceType()); } + + theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(updateContext.getExistingGoldenResource()); } private void handleNoEidsInCommon(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext, MdmUpdateContext theUpdateContext) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index fdd04914646..90020ffc259 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -112,11 +112,14 @@ public class MdmMatchLinkSvc { //Set all GoldenResources as POSSIBLE_DUPLICATE of the last GoldenResource. IAnyResource firstGoldenResource = goldenResources.get(0); + theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(firstGoldenResource); + goldenResources.subList(1, goldenResources.size()) .forEach(possibleDuplicateGoldenResource -> { MdmMatchOutcome outcome = MdmMatchOutcome.POSSIBLE_DUPLICATE; outcome.setEidMatch(theCandidateList.isEidMatch()); myMdmLinkSvc.updateLink(firstGoldenResource, possibleDuplicateGoldenResource, outcome, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); + theMdmTransactionContext.getMdmLinkChangeEvent().addDuplicateGoldenResourceId(possibleDuplicateGoldenResource); }); } } @@ -129,6 +132,8 @@ public class MdmMatchLinkSvc { // 2. Create source resource for the MDM source // 3. UPDATE MDM LINK TABLE myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); + + theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(newGoldenResource); } private void handleMdmCreate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/helper/BaseMdmHelper.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/helper/BaseMdmHelper.java index 1389c4c5ea1..601b3ce2920 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/helper/BaseMdmHelper.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/helper/BaseMdmHelper.java @@ -106,5 +106,8 @@ public abstract class BaseMdmHelper implements BeforeEachCallback, AfterEachCall return channel.getQueueSizeForUnitTest(); } + public PointcutLatch getAfterMdmLatch() { + return myAfterMdmLatch; + } } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index c722b23dab2..7d24395852d 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -7,13 +7,16 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent; import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.rules.config.MdmSettings; +import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.server.TransactionLogMessages; import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException; +import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -21,16 +24,21 @@ import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Medication; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.SearchParameter; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.data.domain.Pageable; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import java.util.Date; import java.util.List; +import java.util.Optional; import static ca.uhn.fhir.mdm.api.MdmConstants.CODE_GOLDEN_RECORD; import static ca.uhn.fhir.mdm.api.MdmConstants.CODE_GOLDEN_RECORD_REDIRECTED; @@ -67,6 +75,24 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { assertLinkCount(1); } + @Test + public void testCreateLinkChangeEvent() throws InterruptedException { + Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC"); + myMdmHelper.createWithLatch(pr); + + ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class); + assertNotNull(resourceOperationMessage); + assertEquals(pr.getId(), resourceOperationMessage.getId()); + + MdmLink example = new MdmLink(); + example.setSourcePid(pr.getIdElement().getIdPartAsLong()); + MdmLink link = myMdmLinkDao.findAll(Example.of(example)).get(0); + + MdmLinkChangeEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkChangeEvent.class); + assertNotNull(linkChangeEvent); + assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); + } + @Test public void testSearchExpandingInterceptorWorks() { SearchParameterMap subject = new SearchParameterMap("subject", new ReferenceParam("Patient/123").setMdmExpand(true)).setLoadSynchronous(true); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java new file mode 100644 index 00000000000..374d955aba8 --- /dev/null +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java @@ -0,0 +1,55 @@ +package ca.uhn.fhir.mdm.api; + +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class MdmLinkChangeEvent { + + private String myGoldenResourceId; + private Set myDuplicateGoldenResourceIds = new HashSet<>(); + + public String getGoldenResourceId() { + return myGoldenResourceId; + } + + public void setGoldenResourceId(IBaseResource theGoldenResourceId) { + setGoldenResourceId(getIdAsString(theGoldenResourceId)); + } + + public void setGoldenResourceId(String theGoldenResourceId) { + myGoldenResourceId = theGoldenResourceId; + } + + private String getIdAsString(IBaseResource theResource) { + if (theResource == null) { + return null; + } + IIdType idElement = theResource.getIdElement(); + if (idElement == null) { + return null; + } + return idElement.getValueAsString(); + } + + public Set getDuplicateGoldenResourceIds() { + return myDuplicateGoldenResourceIds; + } + + public void setDuplicateGoldenResourceIds(Set theDuplicateGoldenResourceIds) { + myDuplicateGoldenResourceIds = theDuplicateGoldenResourceIds; + } + + public MdmLinkChangeEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) { + String id = getIdAsString(theDuplicateGoldenResourceId); + if (id != null) { + getDuplicateGoldenResourceIds().add(id); + } + return this; + } + +} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java index a2fb07fe200..db699fd602b 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.mdm.model; * #L% */ +import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent; import ca.uhn.fhir.rest.server.TransactionLogMessages; public class MdmTransactionContext { @@ -45,6 +46,8 @@ public class MdmTransactionContext { private String myResourceType; + private MdmLinkChangeEvent myMdmLinkChangeEvent = new MdmLinkChangeEvent(); + public TransactionLogMessages getTransactionLogMessages() { return myTransactionLogMessages; } @@ -92,4 +95,12 @@ public class MdmTransactionContext { public void setResourceType(String myResourceType) { this.myResourceType = myResourceType; } + + public MdmLinkChangeEvent getMdmLinkChangeEvent() { + return myMdmLinkChangeEvent; + } + + public void setMdmLinkChangeEvent(MdmLinkChangeEvent theMdmLinkChangeEvent) { + myMdmLinkChangeEvent = theMdmLinkChangeEvent; + } } From 0d34fe61c81da55d5d641a496cef957de1c5fd4b Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Fri, 30 Jul 2021 11:17:56 -0400 Subject: [PATCH 02/46] Adding tests --- .../jpa/mdm/broker/MdmMessageHandler.java | 1 + .../interceptor/MdmStorageInterceptorIT.java | 36 +++++++++++++++++++ .../uhn/fhir/mdm/api/MdmLinkChangeEvent.java | 16 +++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java index b80d2caafc7..967349c0823 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java @@ -111,6 +111,7 @@ public class MdmMessageHandler implements MessageHandler { IBaseResource targetResource = theMsg.getPayload(myFhirContext); ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType()); outgoingMsg.setTransactionId(theMsg.getTransactionId()); + mdmContext.getMdmLinkChangeEvent().setTargetResourceId(targetResource); HookParams params = new HookParams() .add(ResourceOperationMessage.class, outgoingMsg) diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index 7d24395852d..919911a3e25 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -91,6 +91,42 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { MdmLinkChangeEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkChangeEvent.class); assertNotNull(linkChangeEvent); assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); + assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); + } + + @Test + public void testUpdateLinkChangeEvent() throws InterruptedException { + Patient patient1 = addExternalEID(buildJanePatient(), "eid-1"); + patient1 = createPatientAndUpdateLinks(patient1); + + Patient patient2 = addExternalEID(buildJanePatient(), "eid-2"); + patient2 = createPatientAndUpdateLinks(patient2); + + MdmLinkChangeEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkChangeEvent.class); + assertNotNull(linkChangeEvent); +// assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); +// assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); + } + + @Test + public void testDuplicateLinkChangeEvent() throws InterruptedException { + fail(); + + Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC"); + myMdmHelper.createWithLatch(pr); + + ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class); + assertNotNull(resourceOperationMessage); + assertEquals(pr.getId(), resourceOperationMessage.getId()); + + MdmLink example = new MdmLink(); + example.setSourcePid(pr.getIdElement().getIdPartAsLong()); + MdmLink link = myMdmLinkDao.findAll(Example.of(example)).get(0); + + MdmLinkChangeEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkChangeEvent.class); + assertNotNull(linkChangeEvent); + assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); + assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); } @Test diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java index 374d955aba8..c0593b2929d 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java @@ -1,15 +1,15 @@ package ca.uhn.fhir.mdm.api; +import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; public class MdmLinkChangeEvent { + private String myTargetResourceId; private String myGoldenResourceId; private Set myDuplicateGoldenResourceIds = new HashSet<>(); @@ -36,6 +36,18 @@ public class MdmLinkChangeEvent { return idElement.getValueAsString(); } + public String getTargetResourceId() { + return myTargetResourceId; + } + + public void setTargetResourceId(IBaseResource theTargetResource) { + setTargetResourceId(getIdAsString(theTargetResource)); + } + + public void setTargetResourceId(String theTargetResourceId) { + myTargetResourceId = theTargetResourceId; + } + public Set getDuplicateGoldenResourceIds() { return myDuplicateGoldenResourceIds; } From 891a6304d0e021021c540282e8ebf8b7adf6c0f4 Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Wed, 4 Aug 2021 11:06:14 -0400 Subject: [PATCH 03/46] WIP --- .../dao/r4/FhirResourceDaoCodeSystemR4.java | 2 +- .../jpa/mdm/broker/MdmMessageHandler.java | 1 - .../uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java | 6 +++ .../interceptor/MdmStorageInterceptorIT.java | 54 ++++++++----------- .../uhn/fhir/mdm/api/MdmLinkChangeEvent.java | 36 ++++++++++++- .../fhir/mdm/model/MdmTransactionContext.java | 1 + 6 files changed, 65 insertions(+), 35 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java index 2ff1ee51c70..335cef64375 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java @@ -139,7 +139,7 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao myDuplicateGoldenResourceIds = new HashSet<>(); public String getGoldenResourceId() { @@ -64,4 +88,12 @@ public class MdmLinkChangeEvent { return this; } + @Override + public String toString() { + return "MdmLinkChangeEvent{" + + "myTargetResourceId='" + myTargetResourceId + '\'' + + ", myGoldenResourceId='" + myGoldenResourceId + '\'' + + ", myDuplicateGoldenResourceIds=" + myDuplicateGoldenResourceIds + + '}'; + } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java index db699fd602b..ce35ea3f150 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java @@ -103,4 +103,5 @@ public class MdmTransactionContext { public void setMdmLinkChangeEvent(MdmLinkChangeEvent theMdmLinkChangeEvent) { myMdmLinkChangeEvent = theMdmLinkChangeEvent; } + } From 4be3334f6ff29f13629d65e67957475547de0c46 Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Wed, 4 Aug 2021 16:33:59 -0400 Subject: [PATCH 04/46] WIP after persistence checked --- .../dao/r4/FhirResourceDaoCodeSystemR4.java | 2 +- .../jpa/mdm/broker/MdmMessageHandler.java | 30 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java index 6a01ab94c70..5f2aa32a2ec 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java @@ -138,7 +138,7 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao mdmLinkBySource = myMdmLinkDaoSvc.findMdmLinkBySource(targetResource); + if (!mdmLinkBySource.isPresent()) { + ourLog.warn("Unable to find link by source for {}", targetResource.getIdElement()); + } + + mdmLinkBySource.ifPresent(link -> { + linkChangeEvent.setMdmMatchResult(link.getMatchResult()); + linkChangeEvent.setMdmLinkSource(link.getLinkSource()); + linkChangeEvent.setEidMatch(link.isEidMatchPresent()); + linkChangeEvent.setNewGoldenResource(link.getHadToCreateNewGoldenResource()); + linkChangeEvent.setScore(link.getScore()); + linkChangeEvent.setRuleCount(link.getRuleCount()); + }); + HookParams params = new HookParams() .add(ResourceOperationMessage.class, outgoingMsg) .add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages()) From 8670f107b5118c274b00c92327478f26f55bc9ad Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Tue, 17 Aug 2021 13:17:44 -0400 Subject: [PATCH 05/46] Updated link expansion --- .../ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java | 9 +++ .../fhir/jpa/dao/mdm/MdmLinkExpandSvc.java | 22 +++++- .../fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java | 9 +++ .../uhn/fhir/mdm/api/MdmLinkChangeEvent.java | 72 ++++++++++++++++++- 4 files changed, 106 insertions(+), 6 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java index 16834facbe2..be0a6289a4e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java @@ -67,4 +67,13 @@ public interface IMdmLinkDao extends JpaRepository { "AND ml.myMatchResult=:matchResult") List expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum); + @Query("SELECT DISTINCT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid " + + "FROM MdmLink ml " + + "INNER JOIN MdmLink ml2 " + + "ON ml.myGoldenResourcePid = ml2.myGoldenResourcePid " + + "WHERE (ml2.mySourcePid = :sourceOrGoldenPid OR ml2.myGoldenResourcePid = :sourceOrGoldenPid) " + + "AND ml2.myMatchResult=:matchResult " + + "AND ml.myMatchResult=:matchResult") + List expandPidsBySourceOrGoldenResourcePidAndMatchResult(@Param("sourceOrGoldenPid") Long theSourceOrGoldenPid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum); + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java index 66af7f5a706..b03e22d04b8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java @@ -72,6 +72,19 @@ public class MdmLinkExpandSvc { return expandMdmBySourceResourcePid(pidOrThrowException); } + /** + * Given a resource ID of a source resource or golden resource, perform MDM expansion and return all the resource + * IDs of all resources that are MDM-Matched to this resource. + * + * @param theId The Resource ID of the resource to MDM-Expand + * @return A set of strings representing the FHIR ids of the expanded resources. + */ + public Set expandMdmBySourceOrGoldenResourceId(IIdType theId) { + ourLog.debug("About to expand source resource with resource id {}", theId); + Long pidOrThrowException = myIdHelperService.getPidOrThrowException(theId); + return flatten(myMdmLinkDao.expandPidsBySourceOrGoldenResourcePidAndMatchResult(pidOrThrowException, MdmMatchResultEnum.MATCH)); + } + /** * Given a PID of a source resource, perform MDM expansion and return all the resource IDs of all resources that are * MDM-Matched to this resource. @@ -81,14 +94,17 @@ public class MdmLinkExpandSvc { */ public Set expandMdmBySourceResourcePid(Long theSourceResourcePid) { ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid); - List goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH); + return flatten(myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH)); + } + + protected Set flatten(List thePidTuples) { Set flattenedPids = new HashSet<>(); - goldenPidSourcePidTuples.forEach(tuple -> { + thePidTuples.forEach(tuple -> { flattenedPids.add(tuple.getSourcePid()); flattenedPids.add(tuple.getGoldenPid()); }); Set resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids); - ourLog.debug("Pid {} has been expanded to [{}]", theSourceResourcePid, String.join(",", resourceIds)); + ourLog.debug("Expanded pids are [{}]", String.join(",", resourceIds)); return resourceIds; } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java index ae034af6fa7..b5deb25f0c6 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java @@ -83,6 +83,15 @@ public class MdmLinkDaoSvcTest extends BaseMdmR4Test { assertThat(lists, hasSize(10)); + lists.stream() + .forEach(tuple -> { + assertThat(tuple.getGoldenPid(), is(equalTo(golden.getIdElement().getIdPartAsLong()))); + assertThat(tuple.getSourcePid(), is(in(expectedExpandedPids))); + }); + + lists = myMdmLinkDao.expandPidsBySourceOrGoldenResourcePidAndMatchResult(mdmLinks.get(0).getGoldenResourcePid(), MdmMatchResultEnum.MATCH); + assertThat(lists, hasSize(10)); + lists.stream() .forEach(tuple -> { assertThat(tuple.getGoldenPid(), is(equalTo(golden.getIdElement().getIdPartAsLong()))); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java index e2d6b199812..8e306c16e6e 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java @@ -30,9 +30,21 @@ import java.util.Set; public class MdmLinkChangeEvent implements IModelJson { - @JsonProperty(value = "targetResourceId") + @JsonProperty(value = "matchResult") + private MdmMatchResultEnum myMdmMatchResult; + @JsonProperty(value = "linkSource") + private MdmLinkSourceEnum myMdmLinkSource; + @JsonProperty(value = "eidMatch") + private Boolean myEidMatch; + @JsonProperty(value = "newGoldenResource") + private Boolean myNewGoldenResource; + @JsonProperty(value = "score") + private Double myScore; + @JsonProperty(value = "ruleCount") + private Long myRuleCount; + @JsonProperty(value = "targetResourceId", required = true) private String myTargetResourceId; - @JsonProperty(value = "goldenResourceId") + @JsonProperty(value = "goldenResourceId", required = true) private String myGoldenResourceId; @JsonProperty(value = "duplicateResourceIds") private Set myDuplicateGoldenResourceIds = new HashSet<>(); @@ -88,10 +100,64 @@ public class MdmLinkChangeEvent implements IModelJson { return this; } + public MdmMatchResultEnum getMdmMatchResult() { + return myMdmMatchResult; + } + + public void setMdmMatchResult(MdmMatchResultEnum theMdmMatchResult) { + myMdmMatchResult = theMdmMatchResult; + } + + public MdmLinkSourceEnum getMdmLinkSource() { + return myMdmLinkSource; + } + + public void setMdmLinkSource(MdmLinkSourceEnum theMdmLinkSource) { + myMdmLinkSource = theMdmLinkSource; + } + + public Boolean getEidMatch() { + return myEidMatch; + } + + public void setEidMatch(Boolean theEidMatch) { + myEidMatch = theEidMatch; + } + + public Boolean getNewGoldenResource() { + return myNewGoldenResource; + } + + public void setNewGoldenResource(Boolean theNewGoldenResource) { + myNewGoldenResource = theNewGoldenResource; + } + + public Double getScore() { + return myScore; + } + + public void setScore(Double theScore) { + myScore = theScore; + } + + public Long getRuleCount() { + return myRuleCount; + } + + public void setRuleCount(Long theRuleCount) { + myRuleCount = theRuleCount; + } + @Override public String toString() { return "MdmLinkChangeEvent{" + - "myTargetResourceId='" + myTargetResourceId + '\'' + + "myMdmMatchResult=" + myMdmMatchResult + + ", myMdmLinkSource=" + myMdmLinkSource + + ", myEidMatch=" + myEidMatch + + ", myNewGoldenResource=" + myNewGoldenResource + + ", myScore=" + myScore + + ", myRuleCount=" + myRuleCount + + ", myTargetResourceId='" + myTargetResourceId + '\'' + ", myGoldenResourceId='" + myGoldenResourceId + '\'' + ", myDuplicateGoldenResourceIds=" + myDuplicateGoldenResourceIds + '}'; From 1e41621eca369ceb8e3a116db4002d1b334cc33f Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Thu, 19 Aug 2021 16:43:51 -0400 Subject: [PATCH 06/46] Rolled back changes --- .../ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java | 9 -------- .../fhir/jpa/dao/mdm/MdmLinkExpandSvc.java | 22 +++---------------- .../fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java | 9 -------- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java index be0a6289a4e..16834facbe2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IMdmLinkDao.java @@ -67,13 +67,4 @@ public interface IMdmLinkDao extends JpaRepository { "AND ml.myMatchResult=:matchResult") List expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum); - @Query("SELECT DISTINCT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid " + - "FROM MdmLink ml " + - "INNER JOIN MdmLink ml2 " + - "ON ml.myGoldenResourcePid = ml2.myGoldenResourcePid " + - "WHERE (ml2.mySourcePid = :sourceOrGoldenPid OR ml2.myGoldenResourcePid = :sourceOrGoldenPid) " + - "AND ml2.myMatchResult=:matchResult " + - "AND ml.myMatchResult=:matchResult") - List expandPidsBySourceOrGoldenResourcePidAndMatchResult(@Param("sourceOrGoldenPid") Long theSourceOrGoldenPid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum); - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java index b03e22d04b8..66af7f5a706 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/mdm/MdmLinkExpandSvc.java @@ -72,19 +72,6 @@ public class MdmLinkExpandSvc { return expandMdmBySourceResourcePid(pidOrThrowException); } - /** - * Given a resource ID of a source resource or golden resource, perform MDM expansion and return all the resource - * IDs of all resources that are MDM-Matched to this resource. - * - * @param theId The Resource ID of the resource to MDM-Expand - * @return A set of strings representing the FHIR ids of the expanded resources. - */ - public Set expandMdmBySourceOrGoldenResourceId(IIdType theId) { - ourLog.debug("About to expand source resource with resource id {}", theId); - Long pidOrThrowException = myIdHelperService.getPidOrThrowException(theId); - return flatten(myMdmLinkDao.expandPidsBySourceOrGoldenResourcePidAndMatchResult(pidOrThrowException, MdmMatchResultEnum.MATCH)); - } - /** * Given a PID of a source resource, perform MDM expansion and return all the resource IDs of all resources that are * MDM-Matched to this resource. @@ -94,17 +81,14 @@ public class MdmLinkExpandSvc { */ public Set expandMdmBySourceResourcePid(Long theSourceResourcePid) { ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid); - return flatten(myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH)); - } - - protected Set flatten(List thePidTuples) { + List goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH); Set flattenedPids = new HashSet<>(); - thePidTuples.forEach(tuple -> { + goldenPidSourcePidTuples.forEach(tuple -> { flattenedPids.add(tuple.getSourcePid()); flattenedPids.add(tuple.getGoldenPid()); }); Set resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids); - ourLog.debug("Expanded pids are [{}]", String.join(",", resourceIds)); + ourLog.debug("Pid {} has been expanded to [{}]", theSourceResourcePid, String.join(",", resourceIds)); return resourceIds; } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java index b5deb25f0c6..ae034af6fa7 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/dao/MdmLinkDaoSvcTest.java @@ -83,15 +83,6 @@ public class MdmLinkDaoSvcTest extends BaseMdmR4Test { assertThat(lists, hasSize(10)); - lists.stream() - .forEach(tuple -> { - assertThat(tuple.getGoldenPid(), is(equalTo(golden.getIdElement().getIdPartAsLong()))); - assertThat(tuple.getSourcePid(), is(in(expectedExpandedPids))); - }); - - lists = myMdmLinkDao.expandPidsBySourceOrGoldenResourcePidAndMatchResult(mdmLinks.get(0).getGoldenResourcePid(), MdmMatchResultEnum.MATCH); - assertThat(lists, hasSize(10)); - lists.stream() .forEach(tuple -> { assertThat(tuple.getGoldenPid(), is(equalTo(golden.getIdElement().getIdPartAsLong()))); From 6ea58f74d1e3317683242a8fd0f94ac8bb2b881d Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Mon, 23 Aug 2021 10:55:09 -0400 Subject: [PATCH 07/46] Code review --- .../jpa/mdm/broker/MdmMessageHandler.java | 22 +++----- .../jpa/mdm/config/MdmConsumerConfig.java | 11 +++- .../jpa/mdm/svc/IMdmModelConverterSvc.java | 39 ++++++++++++++ ...cImpl.java => MdmLinkQuerySvcImplSvc.java} | 32 ++++-------- .../jpa/mdm/svc/MdmModelConverterSvcImpl.java | 52 +++++++++++++++++++ .../interceptor/MdmStorageInterceptorIT.java | 7 +-- ...LinkChangeEvent.java => MdmLinkEvent.java} | 21 +++++++- .../java/ca/uhn/fhir/mdm/api/MdmLinkJson.java | 19 ++++++- .../fhir/mdm/model/MdmTransactionContext.java | 12 ++--- 9 files changed, 160 insertions(+), 55 deletions(-) create mode 100644 hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/IMdmModelConverterSvc.java rename hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/{MdmLinkQuerySvcImpl.java => MdmLinkQuerySvcImplSvc.java} (73%) create mode 100644 hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java rename hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/{MdmLinkChangeEvent.java => MdmLinkEvent.java} (86%) diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java index 5f103311abb..701f00b034b 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java @@ -26,15 +26,14 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; -import ca.uhn.fhir.jpa.mdm.svc.MdmLinkSvcImpl; +import ca.uhn.fhir.jpa.mdm.svc.IMdmModelConverterSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmMatchLinkSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmResourceFilteringSvc; import ca.uhn.fhir.jpa.mdm.svc.candidate.TooManyCandidatesException; import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage; import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage; -import ca.uhn.fhir.mdm.api.IMdmLinkSvc; import ca.uhn.fhir.mdm.api.IMdmSettings; -import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent; +import ca.uhn.fhir.mdm.api.MdmLinkEvent; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.rest.server.TransactionLogMessages; @@ -42,7 +41,6 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IIdType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.Message; @@ -69,6 +67,8 @@ public class MdmMessageHandler implements MessageHandler { private MdmResourceFilteringSvc myMdmResourceFilteringSvc; @Autowired private IMdmSettings myMdmSettings; + @Autowired + private IMdmModelConverterSvc myModelConverter; @Override public void handleMessage(Message theMessage) throws MessagingException { @@ -119,25 +119,17 @@ public class MdmMessageHandler implements MessageHandler { ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType()); outgoingMsg.setTransactionId(theMsg.getTransactionId()); - MdmLinkChangeEvent linkChangeEvent = mdmContext.getMdmLinkChangeEvent(); + MdmLinkEvent linkChangeEvent = mdmContext.getMdmLinkChangeEvent(); Optional mdmLinkBySource = myMdmLinkDaoSvc.findMdmLinkBySource(targetResource); if (!mdmLinkBySource.isPresent()) { ourLog.warn("Unable to find link by source for {}", targetResource.getIdElement()); } - mdmLinkBySource.ifPresent(link -> { - linkChangeEvent.setMdmMatchResult(link.getMatchResult()); - linkChangeEvent.setMdmLinkSource(link.getLinkSource()); - linkChangeEvent.setEidMatch(link.isEidMatchPresent()); - linkChangeEvent.setNewGoldenResource(link.getHadToCreateNewGoldenResource()); - linkChangeEvent.setScore(link.getScore()); - linkChangeEvent.setRuleCount(link.getRuleCount()); - }); - + mdmLinkBySource.ifPresent(link -> linkChangeEvent.setFromLink(myModelConverter.toJson(link))); HookParams params = new HookParams() .add(ResourceOperationMessage.class, outgoingMsg) .add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages()) - .add(MdmLinkChangeEvent.class, mdmContext.getMdmLinkChangeEvent()); + .add(MdmLinkEvent.class, mdmContext.getMdmLinkChangeEvent()); myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params); } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java index 51981cdecaa..56f81f8b87a 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java @@ -31,15 +31,17 @@ import ca.uhn.fhir.jpa.mdm.dao.MdmLinkFactory; import ca.uhn.fhir.jpa.mdm.interceptor.IMdmStorageInterceptor; import ca.uhn.fhir.jpa.mdm.interceptor.MdmStorageInterceptor; import ca.uhn.fhir.jpa.mdm.svc.GoldenResourceMergerSvcImpl; +import ca.uhn.fhir.jpa.mdm.svc.IMdmModelConverterSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmClearSvcImpl; import ca.uhn.fhir.jpa.mdm.svc.MdmControllerSvcImpl; import ca.uhn.fhir.jpa.mdm.svc.MdmEidUpdateService; import ca.uhn.fhir.jpa.mdm.svc.MdmGoldenResourceDeletingSvc; -import ca.uhn.fhir.jpa.mdm.svc.MdmLinkQuerySvcImpl; +import ca.uhn.fhir.jpa.mdm.svc.MdmLinkQuerySvcImplSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmLinkSvcImpl; import ca.uhn.fhir.jpa.mdm.svc.MdmLinkUpdaterSvcImpl; import ca.uhn.fhir.jpa.mdm.svc.MdmMatchFinderSvcImpl; import ca.uhn.fhir.jpa.mdm.svc.MdmMatchLinkSvc; +import ca.uhn.fhir.jpa.mdm.svc.MdmModelConverterSvcImpl; import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmResourceFilteringSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmSearchParamSvc; @@ -179,7 +181,12 @@ public class MdmConsumerConfig { @Bean IMdmLinkQuerySvc mdmLinkQuerySvc() { - return new MdmLinkQuerySvcImpl(); + return new MdmLinkQuerySvcImplSvc(); + } + + @Bean + IMdmModelConverterSvc mdmModelConverterSvc() { + return new MdmModelConverterSvcImpl(); } @Bean diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/IMdmModelConverterSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/IMdmModelConverterSvc.java new file mode 100644 index 00000000000..67c534a9489 --- /dev/null +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/IMdmModelConverterSvc.java @@ -0,0 +1,39 @@ +package ca.uhn.fhir.jpa.mdm.svc; + +/*- + * #%L + * HAPI FHIR JPA Server - Master Data Management + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.mdm.api.MdmLinkJson; + +/** + * Contract for decoupling API dependency from the base / JPA modules. + */ +public interface IMdmModelConverterSvc { + + /** + * Creates JSON representation of the provided MDM link + * + * @param theLink Link to convert + * @return Returns the converted link + */ + public MdmLinkJson toJson(MdmLink theLink); + +} diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java similarity index 73% rename from hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImpl.java rename to hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java index ea00e81ec4d..996dbe8e5cc 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkQuerySvcImplSvc.java @@ -36,20 +36,24 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; -public class MdmLinkQuerySvcImpl implements IMdmLinkQuerySvc { +public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc { - private static final Logger ourLog = LoggerFactory.getLogger(MdmLinkQuerySvcImpl.class); + private static final Logger ourLog = LoggerFactory.getLogger(MdmLinkQuerySvcImplSvc.class); + + @Autowired + MdmLinkDaoSvc myMdmLinkDaoSvc; @Autowired IdHelperService myIdHelperService; + @Autowired - MdmLinkDaoSvc myMdmLinkDaoSvc; + IMdmModelConverterSvc myMdmModelConverterSvc; @Override public Page queryLinks(IIdType theGoldenResourceId, IIdType theSourceResourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) { Example exampleLink = exampleLinkFromParameters(theGoldenResourceId, theSourceResourceId, theMatchResult, theLinkSource); Page mdmLinkByExample = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest); - Page map = mdmLinkByExample.map(this::toJson); + Page map = mdmLinkByExample.map(myMdmModelConverterSvc::toJson); return map; } @@ -57,28 +61,10 @@ public class MdmLinkQuerySvcImpl implements IMdmLinkQuerySvc { public Page getDuplicateGoldenResources(MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) { Example exampleLink = exampleLinkFromParameters(null, null, MdmMatchResultEnum.POSSIBLE_DUPLICATE, null); Page mdmLinkPage = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest); - Page map = mdmLinkPage.map(this::toJson); + Page map = mdmLinkPage.map(myMdmModelConverterSvc::toJson); return map; } - private MdmLinkJson toJson(MdmLink theLink) { - MdmLinkJson retval = new MdmLinkJson(); - String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue(); - retval.setSourceId(sourceId); - String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue(); - retval.setGoldenResourceId(goldenResourceId); - retval.setCreated(theLink.getCreated()); - retval.setEidMatch(theLink.getEidMatch()); - retval.setLinkSource(theLink.getLinkSource()); - retval.setMatchResult(theLink.getMatchResult()); - retval.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource()); - retval.setScore(theLink.getScore()); - retval.setUpdated(theLink.getUpdated()); - retval.setVector(theLink.getVector()); - retval.setVersion(theLink.getVersion()); - return retval; - } - private Example exampleLinkFromParameters(IIdType theGoldenResourceId, IIdType theSourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource) { MdmLink mdmLink = myMdmLinkDaoSvc.newMdmLink(); if (theGoldenResourceId != null) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java new file mode 100644 index 00000000000..195ac388e68 --- /dev/null +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java @@ -0,0 +1,52 @@ +package ca.uhn.fhir.jpa.mdm.svc; + +/*- + * #%L + * HAPI FHIR JPA Server - Master Data Management + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import ca.uhn.fhir.jpa.dao.index.IdHelperService; +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.mdm.api.MdmLinkJson; +import org.springframework.beans.factory.annotation.Autowired; + +public class MdmModelConverterSvcImpl implements IMdmModelConverterSvc { + + @Autowired + IdHelperService myIdHelperService; + + public MdmLinkJson toJson(MdmLink theLink) { + MdmLinkJson retval = new MdmLinkJson(); + String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue(); + retval.setSourceId(sourceId); + String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue(); + retval.setGoldenResourceId(goldenResourceId); + retval.setCreated(theLink.getCreated()); + retval.setEidMatch(theLink.getEidMatch()); + retval.setLinkSource(theLink.getLinkSource()); + retval.setMatchResult(theLink.getMatchResult()); + retval.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource()); + retval.setScore(theLink.getScore()); + retval.setUpdated(theLink.getUpdated()); + retval.setVector(theLink.getVector()); + retval.setVersion(theLink.getVersion()); + retval.setRuleCount(theLink.getRuleCount()); + return retval; + } + +} diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index 4d729730f7c..cd1518cbc59 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent; +import ca.uhn.fhir.mdm.api.MdmLinkEvent; import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.rules.config.MdmSettings; @@ -32,14 +32,11 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; -import org.springframework.data.domain.ExampleMatcher; -import org.springframework.data.domain.Pageable; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import java.util.Date; import java.util.List; -import java.util.Optional; import static ca.uhn.fhir.mdm.api.MdmConstants.CODE_GOLDEN_RECORD; import static ca.uhn.fhir.mdm.api.MdmConstants.CODE_GOLDEN_RECORD_REDIRECTED; @@ -89,7 +86,7 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { MdmLink link = getLinkByTargetId(pr); - MdmLinkChangeEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkChangeEvent.class); + MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); assertNotNull(linkChangeEvent); assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java similarity index 86% rename from hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java rename to hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java index 8e306c16e6e..7eda6f328d8 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkChangeEvent.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java @@ -28,7 +28,7 @@ import org.hl7.fhir.instance.model.api.IIdType; import java.util.HashSet; import java.util.Set; -public class MdmLinkChangeEvent implements IModelJson { +public class MdmLinkEvent implements IModelJson { @JsonProperty(value = "matchResult") private MdmMatchResultEnum myMdmMatchResult; @@ -92,7 +92,7 @@ public class MdmLinkChangeEvent implements IModelJson { myDuplicateGoldenResourceIds = theDuplicateGoldenResourceIds; } - public MdmLinkChangeEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) { + public MdmLinkEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) { String id = getIdAsString(theDuplicateGoldenResourceId); if (id != null) { getDuplicateGoldenResourceIds().add(id); @@ -121,6 +121,10 @@ public class MdmLinkChangeEvent implements IModelJson { } public void setEidMatch(Boolean theEidMatch) { + if (theEidMatch == null) { + myEidMatch = Boolean.FALSE; + return; + } myEidMatch = theEidMatch; } @@ -129,6 +133,10 @@ public class MdmLinkChangeEvent implements IModelJson { } public void setNewGoldenResource(Boolean theNewGoldenResource) { + if (theNewGoldenResource == null) { + myNewGoldenResource = Boolean.FALSE; + return; + } myNewGoldenResource = theNewGoldenResource; } @@ -148,6 +156,15 @@ public class MdmLinkChangeEvent implements IModelJson { myRuleCount = theRuleCount; } + public void setFromLink(MdmLinkJson theMdmLinkJson) { + setMdmMatchResult(theMdmLinkJson.getMatchResult()); + setMdmLinkSource(theMdmLinkJson.getLinkSource()); + setEidMatch(theMdmLinkJson.getEidMatch()); + setNewGoldenResource(theMdmLinkJson.getLinkCreatedNewResource()); + setScore(theMdmLinkJson.getScore()); + setRuleCount(theMdmLinkJson.getRuleCount()); + } + @Override public String toString() { return "MdmLinkChangeEvent{" + diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java index 744aa384823..424298418b4 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java @@ -48,11 +48,15 @@ public class MdmLinkJson implements IModelJson { @JsonProperty("version") private String myVersion; - /** This link was created as a result of an eid match **/ + /** + * This link was created as a result of an eid match + **/ @JsonProperty("eidMatch") private Boolean myEidMatch; - /** This link created a new golden resource **/ + /** + * This link created a new golden resource + **/ @JsonProperty("linkCreatedNewGoldenResource") private Boolean myLinkCreatedNewResource; @@ -62,6 +66,9 @@ public class MdmLinkJson implements IModelJson { @JsonProperty("score") private Double myScore; + @JsonProperty("ruleCount") + private Long myRuleCount; + public String getGoldenResourceId() { return myGoldenResourceId; } @@ -160,4 +167,12 @@ public class MdmLinkJson implements IModelJson { myScore = theScore; return this; } + + public Long getRuleCount() { + return myRuleCount; + } + + public void setRuleCount(Long theRuleCount) { + myRuleCount = theRuleCount; + } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java index ce35ea3f150..9853918a9d7 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.mdm.model; * #L% */ -import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent; +import ca.uhn.fhir.mdm.api.MdmLinkEvent; import ca.uhn.fhir.rest.server.TransactionLogMessages; public class MdmTransactionContext { @@ -46,7 +46,7 @@ public class MdmTransactionContext { private String myResourceType; - private MdmLinkChangeEvent myMdmLinkChangeEvent = new MdmLinkChangeEvent(); + private MdmLinkEvent myMdmLinkEvent = new MdmLinkEvent(); public TransactionLogMessages getTransactionLogMessages() { return myTransactionLogMessages; @@ -96,12 +96,12 @@ public class MdmTransactionContext { this.myResourceType = myResourceType; } - public MdmLinkChangeEvent getMdmLinkChangeEvent() { - return myMdmLinkChangeEvent; + public MdmLinkEvent getMdmLinkChangeEvent() { + return myMdmLinkEvent; } - public void setMdmLinkChangeEvent(MdmLinkChangeEvent theMdmLinkChangeEvent) { - myMdmLinkChangeEvent = theMdmLinkChangeEvent; + public void setMdmLinkChangeEvent(MdmLinkEvent theMdmLinkEvent) { + myMdmLinkEvent = theMdmLinkEvent; } } From 3a5e391c77690c0cc57975cd6dd9cf478fe174a0 Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Mon, 23 Aug 2021 11:00:04 -0400 Subject: [PATCH 08/46] Fixed pointcut def --- .../src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java index d8f0f33ae9f..30f81b90889 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java @@ -1996,7 +1996,7 @@ public enum Pointcut implements IPointcut { MDM_AFTER_PERSISTED_RESOURCE_CHECKED(void.class, "ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage", "ca.uhn.fhir.rest.server.TransactionLogMessages", - "ca.uhn.fhir.mdm.api.MdmLinkChangeEvent"), + "ca.uhn.fhir.mdm.api.MdmLinkEvent"), /** * Performance Tracing Hook: From 91a961f9fd6ec0b4cfc61746891a1b086cb30799 Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Fri, 27 Aug 2021 10:48:19 -0400 Subject: [PATCH 09/46] Added changelog --- .../hapi/fhir/changelog/5_6_0/2850-updated-mdm-pointcut.yaml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2850-updated-mdm-pointcut.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2850-updated-mdm-pointcut.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2850-updated-mdm-pointcut.yaml new file mode 100644 index 00000000000..712e336d130 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2850-updated-mdm-pointcut.yaml @@ -0,0 +1,4 @@ +--- +type: add +issue: 2850 +title: "Updated handling of MDM_AFTER_PERSISTED_RESOURCE_CHECKED pointcut to include additional MDM related info." From 4e012236c21e3614bc2615ffed7bfe67c9c5ea01 Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Fri, 27 Aug 2021 16:31:23 -0400 Subject: [PATCH 10/46] Updated comments and added misc refactorings --- .../fhir/jpa/mdm/broker/MdmMessageHandler.java | 4 ++-- .../fhir/jpa/mdm/svc/MdmEidUpdateService.java | 2 +- .../uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java | 12 ++++++------ .../candidate/FindCandidateByExampleSvc.java | 10 +++++----- .../ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java | 4 ++-- .../interceptor/MdmStorageInterceptorIT.java | 18 ++++++++++++------ .../fhir/mdm/model/MdmTransactionContext.java | 2 +- 7 files changed, 29 insertions(+), 23 deletions(-) diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java index 701f00b034b..6589d6b41e9 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java @@ -119,7 +119,7 @@ public class MdmMessageHandler implements MessageHandler { ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType()); outgoingMsg.setTransactionId(theMsg.getTransactionId()); - MdmLinkEvent linkChangeEvent = mdmContext.getMdmLinkChangeEvent(); + MdmLinkEvent linkChangeEvent = mdmContext.getMdmLinkEvent(); Optional mdmLinkBySource = myMdmLinkDaoSvc.findMdmLinkBySource(targetResource); if (!mdmLinkBySource.isPresent()) { ourLog.warn("Unable to find link by source for {}", targetResource.getIdElement()); @@ -129,7 +129,7 @@ public class MdmMessageHandler implements MessageHandler { HookParams params = new HookParams() .add(ResourceOperationMessage.class, outgoingMsg) .add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages()) - .add(MdmLinkEvent.class, mdmContext.getMdmLinkChangeEvent()); + .add(MdmLinkEvent.class, mdmContext.getMdmLinkEvent()); myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params); } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java index d23c27db9f1..2e035615200 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java @@ -86,7 +86,7 @@ public class MdmEidUpdateService { myMdmResourceDaoSvc.upsertGoldenResource(updateContext.getMatchedGoldenResource(), theMdmTransactionContext.getResourceType()); } - theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(updateContext.getExistingGoldenResource()); + theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(updateContext.getExistingGoldenResource()); } private void handleNoEidsInCommon(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext, MdmUpdateContext theUpdateContext) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index e0f6b932557..ce285b58bac 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -78,7 +78,7 @@ public class MdmMatchLinkSvc { private MdmTransactionContext doMdmUpdate(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) { CandidateList candidateList = myMdmGoldenResourceFindingSvc.findGoldenResourceCandidates(theResource); - theMdmTransactionContext.getMdmLinkChangeEvent().setTargetResourceId(theResource); + theMdmTransactionContext.getMdmLinkEvent().setTargetResourceId(theResource); if (candidateList.isEmpty()) { handleMdmWithNoCandidates(theResource, theMdmTransactionContext); @@ -114,14 +114,14 @@ public class MdmMatchLinkSvc { //Set all GoldenResources as POSSIBLE_DUPLICATE of the last GoldenResource. IAnyResource firstGoldenResource = goldenResources.get(0); - theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(firstGoldenResource); + theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(firstGoldenResource); goldenResources.subList(1, goldenResources.size()) .forEach(possibleDuplicateGoldenResource -> { MdmMatchOutcome outcome = MdmMatchOutcome.POSSIBLE_DUPLICATE; outcome.setEidMatch(theCandidateList.isEidMatch()); myMdmLinkSvc.updateLink(firstGoldenResource, possibleDuplicateGoldenResource, outcome, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); - theMdmTransactionContext.getMdmLinkChangeEvent().addDuplicateGoldenResourceId(possibleDuplicateGoldenResource); + theMdmTransactionContext.getMdmLinkEvent().addDuplicateGoldenResourceId(possibleDuplicateGoldenResource); }); } } @@ -135,7 +135,7 @@ public class MdmMatchLinkSvc { // 3. UPDATE MDM LINK TABLE myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); - theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(newGoldenResource); + theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(newGoldenResource); } private void handleMdmCreate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { @@ -145,7 +145,7 @@ public class MdmMatchLinkSvc { if (myGoldenResourceHelper.isPotentialDuplicate(goldenResource, theTargetResource)) { log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs."); IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theTargetResource, theMdmTransactionContext); - theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(newGoldenResource); + theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(newGoldenResource); myMdmLinkSvc.updateLink(newGoldenResource, theTargetResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); myMdmLinkSvc.updateLink(newGoldenResource, goldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); @@ -155,7 +155,7 @@ public class MdmMatchLinkSvc { myEidUpdateService.applySurvivorshipRulesAndSaveGoldenResource(theTargetResource, goldenResource, theMdmTransactionContext); } - theMdmTransactionContext.getMdmLinkChangeEvent().setGoldenResourceId(goldenResource); + theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(goldenResource); myMdmLinkSvc.updateLink(goldenResource, theTargetResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java index 43606a95818..5533c82667b 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java @@ -54,9 +54,9 @@ public class FindCandidateByExampleSvc extends BaseCandidateFinder { private IMdmMatchFinderSvc myMdmMatchFinderSvc; /** - * Attempt to find matching Golden Resources by resolving them from similar Matching target resources, where target resource - * can be either Patient or Practitioner. Runs MDM logic over the existing target resources, then finds their - * entries in the MdmLink table, and returns all the matches found therein. + * Attempt to find matching Golden Resources by resolving them from similar Matching target resources. Runs MDM logic + * over the existing target resources, then finds their entries in the MdmLink table, and returns all the matches + * found therein. * * @param theTarget the {@link IBaseResource} which we want to find candidate Golden Resources for. * @return an Optional list of {@link MatchedGoldenResourceCandidate} indicating matches. @@ -69,8 +69,8 @@ public class FindCandidateByExampleSvc extends BaseCandidateFinder { List matchedCandidates = myMdmMatchFinderSvc.getMatchedTargets(myFhirContext.getResourceType(theTarget), theTarget); - //Convert all possible match targets to their equivalent Golden Resources by looking up in the MdmLink table, - //while ensuring that the matches aren't in our NO_MATCH list. + // Convert all possible match targets to their equivalent Golden Resources by looking up in the MdmLink table, + // while ensuring that the matches aren't in our NO_MATCH list. // The data flow is as follows -> // MatchedTargetCandidate -> Golden Resource -> MdmLink -> MatchedGoldenResourceCandidate matchedCandidates = matchedCandidates.stream().filter(mc -> mc.isMatch() || mc.isPossibleMatch()).collect(Collectors.toList()); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java index 96115a95bf2..60936356c54 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java @@ -326,14 +326,14 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { assertEquals(theExpectedCount, myMdmLinkDao.count()); } - protected IAnyResource getGoldenResourceFromTargetResource(IAnyResource theBaseResource) { + protected T getGoldenResourceFromTargetResource(T theBaseResource) { String resourceType = theBaseResource.getIdElement().getResourceType(); IFhirResourceDao relevantDao = myDaoRegistry.getResourceDao(resourceType); Optional matchedLinkForTargetPid = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(theBaseResource)); if (matchedLinkForTargetPid.isPresent()) { Long goldenResourcePid = matchedLinkForTargetPid.get().getGoldenResourcePid(); - return (IAnyResource) relevantDao.readByPid(new ResourcePersistentId(goldenResourcePid)); + return (T) relevantDao.readByPid(new ResourcePersistentId(goldenResourcePid)); } else { return null; } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index cd1518cbc59..330e1380bef 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -6,8 +6,12 @@ import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; +import ca.uhn.fhir.jpa.mdm.svc.MdmLinkSvcImpl; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.mdm.api.IMdmLinkSvc; import ca.uhn.fhir.mdm.api.MdmLinkEvent; +import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; +import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.rules.config.MdmSettings; @@ -68,6 +72,8 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { public MdmHelperR4 myMdmHelper; @Autowired private IdHelperService myIdHelperService; + @Autowired + private IMdmLinkSvc myMdmLinkSvc; @Test public void testCreatePractitioner() throws InterruptedException { @@ -105,17 +111,17 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { MdmTransactionContext ctx = createContextForCreate("Patient"); myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx); - ourLog.info(ctx.getMdmLinkChangeEvent().toString()); - assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkChangeEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkChangeEvent().getGoldenResourceId()).getIdPartAsLong()); + ourLog.info(ctx.getMdmLinkEvent().toString()); + assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); + assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); Patient patient2 = addExternalEID(buildJanePatient(), "eid-2"); myMdmHelper.createWithLatch(patient2); ctx = createContextForCreate("Patient"); myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx); - ourLog.info(ctx.getMdmLinkChangeEvent().toString()); - assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkChangeEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkChangeEvent().getGoldenResourceId()).getIdPartAsLong()); + ourLog.info(ctx.getMdmLinkEvent().toString()); + assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); + assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); } @Test diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java index 9853918a9d7..4f13e7ac706 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java @@ -96,7 +96,7 @@ public class MdmTransactionContext { this.myResourceType = myResourceType; } - public MdmLinkEvent getMdmLinkChangeEvent() { + public MdmLinkEvent getMdmLinkEvent() { return myMdmLinkEvent; } From 2a60e91713ae20cd983365cdd8bdb51e3f097ecf Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Thu, 2 Sep 2021 17:41:57 -0400 Subject: [PATCH 11/46] WIP Dup Test --- .../uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java | 1 + .../fhir/jpa/mdm/interceptor/MdmEventIT.java | 190 ++++++++++++++++++ .../interceptor/MdmStorageInterceptorIT.java | 32 +-- 3 files changed, 193 insertions(+), 30 deletions(-) create mode 100644 hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index ce285b58bac..2c2eba5342e 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -101,6 +101,7 @@ public class MdmMatchLinkSvc { handleMdmWithSingleCandidate(theResource, firstMatch, theMdmTransactionContext); } else { log(theMdmTransactionContext, "MDM received multiple match candidates, that were linked to different Golden Resources. Setting POSSIBLE_DUPLICATES and POSSIBLE_MATCHES."); + //Set them all as POSSIBLE_MATCH List goldenResources = new ArrayList<>(); for (MatchedGoldenResourceCandidate matchedGoldenResourceCandidate : theCandidateList.getCandidates()) { diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java new file mode 100644 index 00000000000..1bfdd0c1cb2 --- /dev/null +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java @@ -0,0 +1,190 @@ +package ca.uhn.fhir.jpa.mdm.interceptor; + +import ca.uhn.fhir.jpa.dao.index.IdHelperService; +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; +import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; +import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; +import ca.uhn.fhir.jpa.search.HapiLuceneAnalysisConfigurer; +import ca.uhn.fhir.mdm.api.MdmLinkEvent; +import ca.uhn.fhir.mdm.model.MdmTransactionContext; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings; +import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings; +import org.hibernate.search.engine.cfg.BackendSettings; +import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Practitioner; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.Example; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +@TestPropertySource(properties = { + "mdm.prevent_multiple_eids=false" +}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +@ContextConfiguration(classes = {MdmHelperConfig.class}) +public class MdmEventIT extends BaseMdmR4Test { + + private static final Logger ourLog = getLogger(MdmEventIT.class); + + @RegisterExtension + @Autowired + public MdmHelperR4 myMdmHelper; + @Autowired + private IdHelperService myIdHelperService; + + @Bean + @Primary + public Properties jpaProperties() { + Properties extraProperties = new Properties(); + extraProperties.put("hibernate.format_sql", "true"); + extraProperties.put("hibernate.show_sql", "true"); + extraProperties.put("hibernate.hbm2ddl.auto", "update"); + extraProperties.put("hibernate.dialect", H2Dialect.class.getName()); + + extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene"); + extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER), HapiLuceneAnalysisConfigurer.class.getName()); + extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-heap"); + extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT"); + extraProperties.put(HibernateOrmMapperSettings.ENABLED, "true"); + + return extraProperties; + } + + + @Test + public void testDuplicateLinkChangeEvent() throws InterruptedException { + Patient patient1 = buildJanePatient(); + addExternalEID(patient1, "eid-1"); + addExternalEID(patient1, "eid-11"); + patient1 = createPatientAndUpdateLinks(patient1); + + Patient patient2 = buildPaulPatient(); + addExternalEID(patient2, "eid-2"); + addExternalEID(patient2, "eid-22"); + patient2 = createPatientAndUpdateLinks(patient2); + + Patient patient3 = buildPaulPatient(); + addExternalEID(patient3, "eid-22"); + patient3 = createPatientAndUpdateLinks(patient3); + + patient2.getIdentifier().clear(); + addExternalEID(patient2, "eid-11"); + addExternalEID(patient2, "eid-22"); + + patient2 = (Patient) myPatientDao.update(patient2).getResource(); + MdmTransactionContext ctx = myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, createContextForUpdate(patient2.getIdElement().getResourceType())); + + MdmLinkEvent mdmLinkEvent = ctx.getMdmLinkEvent(); + assertFalse(mdmLinkEvent.getDuplicateGoldenResourceIds().isEmpty()); + } + + // @Test + public void testCreateLinkChangeEvent() throws InterruptedException { + Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC"); + myMdmHelper.createWithLatch(pr); + + ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class); + assertNotNull(resourceOperationMessage); + assertEquals(pr.getId(), resourceOperationMessage.getId()); + + MdmLink link = getLinkByTargetId(pr); + + MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); + assertNotNull(linkChangeEvent); + assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); + assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); + } + + /* + @Test + public void testDuplicateLinkChangeEvent() throws InterruptedException { + logAllLinks(); + for (IBaseResource r : myPatientDao.search(new SearchParameterMap()).getAllResources()) { + ourLog.info("Found {}", r); + } + + Patient myPatient = createPatientAndUpdateLinks(buildPaulPatient()); + StringType myPatientId = new StringType(myPatient.getIdElement().getValue()); + + Patient mySourcePatient = getGoldenResourceFromTargetResource(myPatient); + StringType mySourcePatientId = new StringType(mySourcePatient.getIdElement().getValue()); + StringType myVersionlessGodlenResourceId = new StringType(mySourcePatient.getIdElement().toVersionless().getValue()); + + MdmLink myLink = myMdmLinkDaoSvc.findMdmLinkBySource(myPatient).get(); + // Tests require our initial link to be a POSSIBLE_MATCH + myLink.setMatchResult(MdmMatchResultEnum.POSSIBLE_MATCH); + saveLink(myLink); + assertEquals(MdmLinkSourceEnum.AUTO, myLink.getLinkSource()); +// myDaoConfig.setExpungeEnabled(true); + + // Add a second patient + createPatientAndUpdateLinks(buildJanePatient()); + + // Add a possible duplicate + StringType myLinkSource = new StringType(MdmLinkSourceEnum.AUTO.name()); + Patient sourcePatient1 = createGoldenPatient(); + StringType myGoldenResource1Id = new StringType(sourcePatient1.getIdElement().toVersionless().getValue()); + Long sourcePatient1Pid = myIdHelperService.getPidOrNull(sourcePatient1); + Patient sourcePatient2 = createGoldenPatient(); + StringType myGoldenResource2Id = new StringType(sourcePatient2.getIdElement().toVersionless().getValue()); + Long sourcePatient2Pid = myIdHelperService.getPidOrNull(sourcePatient2); + + + MdmLink possibleDuplicateMdmLink = myMdmLinkDaoSvc.newMdmLink().setGoldenResourcePid(sourcePatient1Pid).setSourcePid(sourcePatient2Pid).setMatchResult(MdmMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(MdmLinkSourceEnum.AUTO); + saveLink(possibleDuplicateMdmLink); + + logAllLinks(); + + ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class); + assertNotNull(resourceOperationMessage); + assertEquals(sourcePatient2.getId(), resourceOperationMessage.getId()); + } + */ + + private MdmLink getLinkByTargetId(IBaseResource theResource) { + MdmLink example = new MdmLink(); + example.setSourcePid(theResource.getIdElement().getIdPartAsLong()); + return myMdmLinkDao.findAll(Example.of(example)).get(0); + } + + @Test + public void testUpdateLinkChangeEvent() throws InterruptedException { + Patient patient1 = addExternalEID(buildJanePatient(), "eid-1"); + myMdmHelper.createWithLatch(patient1); + + MdmTransactionContext ctx = createContextForCreate("Patient"); + myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx); + ourLog.info(ctx.getMdmLinkEvent().toString()); + assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); + assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); + + Patient patient2 = addExternalEID(buildJanePatient(), "eid-2"); + myMdmHelper.createWithLatch(patient2); + ctx = createContextForCreate("Patient"); + myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx); + ourLog.info(ctx.getMdmLinkEvent().toString()); + assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); + assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); + } + + +} diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index 330e1380bef..30281f7fd90 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -6,12 +6,7 @@ import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; -import ca.uhn.fhir.jpa.mdm.svc.MdmLinkSvcImpl; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.api.IMdmLinkSvc; -import ca.uhn.fhir.mdm.api.MdmLinkEvent; -import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; -import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.rules.config.MdmSettings; @@ -21,7 +16,6 @@ import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.server.TransactionLogMessages; import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException; -import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -29,7 +23,6 @@ import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Medication; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; -import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.SearchParameter; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -55,9 +48,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.slf4j.LoggerFactory.getLogger; @@ -72,8 +63,6 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { public MdmHelperR4 myMdmHelper; @Autowired private IdHelperService myIdHelperService; - @Autowired - private IMdmLinkSvc myMdmLinkSvc; @Test public void testCreatePractitioner() throws InterruptedException { @@ -81,23 +70,6 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { assertLinkCount(1); } - @Test - public void testCreateLinkChangeEvent() throws InterruptedException { - Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC"); - myMdmHelper.createWithLatch(pr); - - ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class); - assertNotNull(resourceOperationMessage); - assertEquals(pr.getId(), resourceOperationMessage.getId()); - - MdmLink link = getLinkByTargetId(pr); - - MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); - assertNotNull(linkChangeEvent); - assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); - assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); - } - private MdmLink getLinkByTargetId(IBaseResource theResource) { MdmLink example = new MdmLink(); example.setSourcePid(theResource.getIdElement().getIdPartAsLong()); @@ -113,7 +85,7 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx); ourLog.info(ctx.getMdmLinkEvent().toString()); assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); + assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); Patient patient2 = addExternalEID(buildJanePatient(), "eid-2"); myMdmHelper.createWithLatch(patient2); @@ -121,7 +93,7 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx); ourLog.info(ctx.getMdmLinkEvent().toString()); assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); + assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); } @Test From c63a5038419e7ce6e549c28711b0f1e4b36ebcbd Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Fri, 3 Sep 2021 16:29:26 -0400 Subject: [PATCH 12/46] Updated link processing for MDM events --- .../java/ca/uhn/fhir/jpa/entity/MdmLink.java | 3 +- .../jpa/mdm/broker/MdmMessageHandler.java | 14 +- .../fhir/jpa/mdm/svc/MdmEidUpdateService.java | 2 - .../uhn/fhir/jpa/mdm/svc/MdmLinkSvcImpl.java | 10 +- .../uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java | 8 - .../jpa/mdm/svc/MdmModelConverterSvcImpl.java | 28 ++-- .../fhir/jpa/mdm/interceptor/MdmEventIT.java | 115 ++++---------- .../interceptor/MdmStorageInterceptorIT.java | 20 --- .../java/ca/uhn/fhir/mdm/api/IMdmLink.java | 24 +++ .../ca/uhn/fhir/mdm/api/MdmLinkEvent.java | 148 ++---------------- .../fhir/mdm/model/MdmTransactionContext.java | 18 ++- 11 files changed, 106 insertions(+), 284 deletions(-) create mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLink.java diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/MdmLink.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/MdmLink.java index cd8cbff422d..4892ed8c1f9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/MdmLink.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/MdmLink.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.entity; * #L% */ +import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.jpa.model.entity.ResourceTable; @@ -47,7 +48,7 @@ import java.util.Date; @Table(name = "MPI_LINK", uniqueConstraints = { @UniqueConstraint(name = "IDX_EMPI_PERSON_TGT", columnNames = {"PERSON_PID", "TARGET_PID"}), }) -public class MdmLink { +public class MdmLink implements IMdmLink { public static final int VERSION_LENGTH = 16; private static final int MATCH_RESULT_LENGTH = 16; private static final int LINK_SOURCE_LENGTH = 16; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java index 6589d6b41e9..7695be8f448 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java @@ -119,17 +119,17 @@ public class MdmMessageHandler implements MessageHandler { ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType()); outgoingMsg.setTransactionId(theMsg.getTransactionId()); - MdmLinkEvent linkChangeEvent = mdmContext.getMdmLinkEvent(); - Optional mdmLinkBySource = myMdmLinkDaoSvc.findMdmLinkBySource(targetResource); - if (!mdmLinkBySource.isPresent()) { - ourLog.warn("Unable to find link by source for {}", targetResource.getIdElement()); - } + MdmLinkEvent linkChangeEvent = new MdmLinkEvent(); + mdmContext.getMdmLinks() + .stream() + .forEach(l -> { + linkChangeEvent.addMdmLink(myModelConverter.toJson((MdmLink) l)); + }); - mdmLinkBySource.ifPresent(link -> linkChangeEvent.setFromLink(myModelConverter.toJson(link))); HookParams params = new HookParams() .add(ResourceOperationMessage.class, outgoingMsg) .add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages()) - .add(MdmLinkEvent.class, mdmContext.getMdmLinkEvent()); + .add(MdmLinkEvent.class, linkChangeEvent); myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params); } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java index 2e035615200..94db6849073 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java @@ -85,8 +85,6 @@ public class MdmEidUpdateService { myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext); myMdmResourceDaoSvc.upsertGoldenResource(updateContext.getMatchedGoldenResource(), theMdmTransactionContext.getResourceType()); } - - theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(updateContext.getExistingGoldenResource()); } private void handleNoEidsInCommon(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext, MdmUpdateContext theUpdateContext) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcImpl.java index 3d744f43d11..7e4b95dad0c 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkSvcImpl.java @@ -53,6 +53,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc { private MdmLinkDaoSvc myMdmLinkDaoSvc; @Autowired private IdHelperService myIdHelperService; + @Autowired + private IMdmModelConverterSvc myMdmModelConverterSvc; @Override @Transactional @@ -69,7 +71,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc { validateRequestIsLegal(theGoldenResource, theSourceResource, matchResultEnum, theLinkSource); myMdmResourceDaoSvc.upsertGoldenResource(theGoldenResource, theMdmTransactionContext.getResourceType()); - createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext); + MdmLink link = createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext); + theMdmTransactionContext.addMdmLink(link); } private boolean goldenResourceLinkedAsNoMatch(IAnyResource theGoldenResource, IAnyResource theSourceResource) { @@ -87,6 +90,7 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc { MdmLink mdmLink = optionalMdmLink.get(); log(theMdmTransactionContext, "Deleting MdmLink [" + theGoldenResource.getIdElement().toVersionless() + " -> " + theSourceResource.getIdElement().toVersionless() + "] with result: " + mdmLink.getMatchResult()); myMdmLinkDaoSvc.deleteLink(mdmLink); + theMdmTransactionContext.addMdmLink(mdmLink); } } @@ -129,8 +133,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc { } } - private void createOrUpdateLinkEntity(IBaseResource theGoldenResource, IBaseResource theSourceResource, MdmMatchOutcome theMatchOutcome, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmTransactionContext) { - myMdmLinkDaoSvc.createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext); + private MdmLink createOrUpdateLinkEntity(IBaseResource theGoldenResource, IBaseResource theSourceResource, MdmMatchOutcome theMatchOutcome, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmTransactionContext) { + return myMdmLinkDaoSvc.createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext); } private void log(MdmTransactionContext theMdmTransactionContext, String theMessage) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index 2c2eba5342e..8eda5742dd2 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -78,8 +78,6 @@ public class MdmMatchLinkSvc { private MdmTransactionContext doMdmUpdate(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) { CandidateList candidateList = myMdmGoldenResourceFindingSvc.findGoldenResourceCandidates(theResource); - theMdmTransactionContext.getMdmLinkEvent().setTargetResourceId(theResource); - if (candidateList.isEmpty()) { handleMdmWithNoCandidates(theResource, theMdmTransactionContext); } else if (candidateList.exactlyOneMatch()) { @@ -115,14 +113,12 @@ public class MdmMatchLinkSvc { //Set all GoldenResources as POSSIBLE_DUPLICATE of the last GoldenResource. IAnyResource firstGoldenResource = goldenResources.get(0); - theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(firstGoldenResource); goldenResources.subList(1, goldenResources.size()) .forEach(possibleDuplicateGoldenResource -> { MdmMatchOutcome outcome = MdmMatchOutcome.POSSIBLE_DUPLICATE; outcome.setEidMatch(theCandidateList.isEidMatch()); myMdmLinkSvc.updateLink(firstGoldenResource, possibleDuplicateGoldenResource, outcome, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); - theMdmTransactionContext.getMdmLinkEvent().addDuplicateGoldenResourceId(possibleDuplicateGoldenResource); }); } } @@ -135,8 +131,6 @@ public class MdmMatchLinkSvc { // 2. Create source resource for the MDM source // 3. UPDATE MDM LINK TABLE myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); - - theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(newGoldenResource); } private void handleMdmCreate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { @@ -146,7 +140,6 @@ public class MdmMatchLinkSvc { if (myGoldenResourceHelper.isPotentialDuplicate(goldenResource, theTargetResource)) { log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs."); IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theTargetResource, theMdmTransactionContext); - theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(newGoldenResource); myMdmLinkSvc.updateLink(newGoldenResource, theTargetResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); myMdmLinkSvc.updateLink(newGoldenResource, goldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); @@ -156,7 +149,6 @@ public class MdmMatchLinkSvc { myEidUpdateService.applySurvivorshipRulesAndSaveGoldenResource(theTargetResource, goldenResource, theMdmTransactionContext); } - theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(goldenResource); myMdmLinkSvc.updateLink(goldenResource, theTargetResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java index 195ac388e68..89a8ae5c34e 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmModelConverterSvcImpl.java @@ -31,22 +31,22 @@ public class MdmModelConverterSvcImpl implements IMdmModelConverterSvc { IdHelperService myIdHelperService; public MdmLinkJson toJson(MdmLink theLink) { - MdmLinkJson retval = new MdmLinkJson(); + MdmLinkJson retVal = new MdmLinkJson(); String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue(); - retval.setSourceId(sourceId); + retVal.setSourceId(sourceId); String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue(); - retval.setGoldenResourceId(goldenResourceId); - retval.setCreated(theLink.getCreated()); - retval.setEidMatch(theLink.getEidMatch()); - retval.setLinkSource(theLink.getLinkSource()); - retval.setMatchResult(theLink.getMatchResult()); - retval.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource()); - retval.setScore(theLink.getScore()); - retval.setUpdated(theLink.getUpdated()); - retval.setVector(theLink.getVector()); - retval.setVersion(theLink.getVersion()); - retval.setRuleCount(theLink.getRuleCount()); - return retval; + retVal.setGoldenResourceId(goldenResourceId); + retVal.setCreated(theLink.getCreated()); + retVal.setEidMatch(theLink.getEidMatch()); + retVal.setLinkSource(theLink.getLinkSource()); + retVal.setMatchResult(theLink.getMatchResult()); + retVal.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource()); + retVal.setScore(theLink.getScore()); + retVal.setUpdated(theLink.getUpdated()); + retVal.setVector(theLink.getVector()); + retVal.setVersion(theLink.getVersion()); + retVal.setRuleCount(theLink.getRuleCount()); + return retVal; } } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java index 1bfdd0c1cb2..39ec89b4c7d 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java @@ -6,7 +6,10 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; import ca.uhn.fhir.jpa.search.HapiLuceneAnalysisConfigurer; +import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.MdmLinkEvent; +import ca.uhn.fhir.mdm.api.MdmLinkJson; +import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage; @@ -29,6 +32,7 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; +import java.util.List; import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -51,53 +55,38 @@ public class MdmEventIT extends BaseMdmR4Test { @Autowired private IdHelperService myIdHelperService; - @Bean - @Primary - public Properties jpaProperties() { - Properties extraProperties = new Properties(); - extraProperties.put("hibernate.format_sql", "true"); - extraProperties.put("hibernate.show_sql", "true"); - extraProperties.put("hibernate.hbm2ddl.auto", "update"); - extraProperties.put("hibernate.dialect", H2Dialect.class.getName()); - - extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene"); - extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER), HapiLuceneAnalysisConfigurer.class.getName()); - extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-heap"); - extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT"); - extraProperties.put(HibernateOrmMapperSettings.ENABLED, "true"); - - return extraProperties; - } - - @Test public void testDuplicateLinkChangeEvent() throws InterruptedException { Patient patient1 = buildJanePatient(); addExternalEID(patient1, "eid-1"); addExternalEID(patient1, "eid-11"); - patient1 = createPatientAndUpdateLinks(patient1); + myMdmHelper.createWithLatch(patient1); Patient patient2 = buildPaulPatient(); addExternalEID(patient2, "eid-2"); addExternalEID(patient2, "eid-22"); - patient2 = createPatientAndUpdateLinks(patient2); + myMdmHelper.createWithLatch(patient2); Patient patient3 = buildPaulPatient(); addExternalEID(patient3, "eid-22"); - patient3 = createPatientAndUpdateLinks(patient3); + myMdmHelper.createWithLatch(patient3); patient2.getIdentifier().clear(); addExternalEID(patient2, "eid-11"); addExternalEID(patient2, "eid-22"); - patient2 = (Patient) myPatientDao.update(patient2).getResource(); - MdmTransactionContext ctx = myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, createContextForUpdate(patient2.getIdElement().getResourceType())); + myMdmHelper.updateWithLatch(patient2); - MdmLinkEvent mdmLinkEvent = ctx.getMdmLinkEvent(); - assertFalse(mdmLinkEvent.getDuplicateGoldenResourceIds().isEmpty()); + MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); + assertNotNull(linkChangeEvent); + + // MdmTransactionContext ctx = myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, createContextForUpdate(patient2.getIdElement().getResourceType())); + + List mdmLinkEvent = linkChangeEvent.getMdmLinks(); + assertEquals(3, mdmLinkEvent.size()); } - // @Test + @Test public void testCreateLinkChangeEvent() throws InterruptedException { Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC"); myMdmHelper.createWithLatch(pr); @@ -110,56 +99,13 @@ public class MdmEventIT extends BaseMdmR4Test { MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); assertNotNull(linkChangeEvent); - assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong()); - assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong()); + + assertEquals(1, linkChangeEvent.getMdmLinks().size()); + MdmLinkJson l = linkChangeEvent.getMdmLinks().get(0); + assertEquals(link.getGoldenResourcePid(), new IdDt(l.getGoldenResourceId()).getIdPartAsLong()); + assertEquals(link.getSourcePid(), new IdDt(l.getSourceId()).getIdPartAsLong()); } - /* - @Test - public void testDuplicateLinkChangeEvent() throws InterruptedException { - logAllLinks(); - for (IBaseResource r : myPatientDao.search(new SearchParameterMap()).getAllResources()) { - ourLog.info("Found {}", r); - } - - Patient myPatient = createPatientAndUpdateLinks(buildPaulPatient()); - StringType myPatientId = new StringType(myPatient.getIdElement().getValue()); - - Patient mySourcePatient = getGoldenResourceFromTargetResource(myPatient); - StringType mySourcePatientId = new StringType(mySourcePatient.getIdElement().getValue()); - StringType myVersionlessGodlenResourceId = new StringType(mySourcePatient.getIdElement().toVersionless().getValue()); - - MdmLink myLink = myMdmLinkDaoSvc.findMdmLinkBySource(myPatient).get(); - // Tests require our initial link to be a POSSIBLE_MATCH - myLink.setMatchResult(MdmMatchResultEnum.POSSIBLE_MATCH); - saveLink(myLink); - assertEquals(MdmLinkSourceEnum.AUTO, myLink.getLinkSource()); -// myDaoConfig.setExpungeEnabled(true); - - // Add a second patient - createPatientAndUpdateLinks(buildJanePatient()); - - // Add a possible duplicate - StringType myLinkSource = new StringType(MdmLinkSourceEnum.AUTO.name()); - Patient sourcePatient1 = createGoldenPatient(); - StringType myGoldenResource1Id = new StringType(sourcePatient1.getIdElement().toVersionless().getValue()); - Long sourcePatient1Pid = myIdHelperService.getPidOrNull(sourcePatient1); - Patient sourcePatient2 = createGoldenPatient(); - StringType myGoldenResource2Id = new StringType(sourcePatient2.getIdElement().toVersionless().getValue()); - Long sourcePatient2Pid = myIdHelperService.getPidOrNull(sourcePatient2); - - - MdmLink possibleDuplicateMdmLink = myMdmLinkDaoSvc.newMdmLink().setGoldenResourcePid(sourcePatient1Pid).setSourcePid(sourcePatient2Pid).setMatchResult(MdmMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(MdmLinkSourceEnum.AUTO); - saveLink(possibleDuplicateMdmLink); - - logAllLinks(); - - ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class); - assertNotNull(resourceOperationMessage); - assertEquals(sourcePatient2.getId(), resourceOperationMessage.getId()); - } - */ - private MdmLink getLinkByTargetId(IBaseResource theResource) { MdmLink example = new MdmLink(); example.setSourcePid(theResource.getIdElement().getIdPartAsLong()); @@ -171,19 +117,14 @@ public class MdmEventIT extends BaseMdmR4Test { Patient patient1 = addExternalEID(buildJanePatient(), "eid-1"); myMdmHelper.createWithLatch(patient1); - MdmTransactionContext ctx = createContextForCreate("Patient"); - myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx); - ourLog.info(ctx.getMdmLinkEvent().toString()); - assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); + MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); + assertNotNull(linkChangeEvent); + assertEquals(1, linkChangeEvent.getMdmLinks().size()); - Patient patient2 = addExternalEID(buildJanePatient(), "eid-2"); - myMdmHelper.createWithLatch(patient2); - ctx = createContextForCreate("Patient"); - myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx); - ourLog.info(ctx.getMdmLinkEvent().toString()); - assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); + MdmLinkJson link = linkChangeEvent.getMdmLinks().get(0); + assertEquals(patient1.getResourceType() + "/" + patient1.getIdElement().getIdPart(), link.getSourceId()); + assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(link.getGoldenResourceId()).getIdPartAsLong()); + assertEquals(MdmMatchResultEnum.MATCH, link.getMatchResult()); } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java index 30281f7fd90..4509b9052da 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmStorageInterceptorIT.java @@ -76,26 +76,6 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test { return myMdmLinkDao.findAll(Example.of(example)).get(0); } - @Test - public void testUpdateLinkChangeEvent() throws InterruptedException { - Patient patient1 = addExternalEID(buildJanePatient(), "eid-1"); - myMdmHelper.createWithLatch(patient1); - - MdmTransactionContext ctx = createContextForCreate("Patient"); - myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx); - ourLog.info(ctx.getMdmLinkEvent().toString()); - assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); - - Patient patient2 = addExternalEID(buildJanePatient(), "eid-2"); - myMdmHelper.createWithLatch(patient2); - ctx = createContextForCreate("Patient"); - myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx); - ourLog.info(ctx.getMdmLinkEvent().toString()); - assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId()); - assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong()); - } - @Test public void testSearchExpandingInterceptorWorks() { SearchParameterMap subject = new SearchParameterMap("subject", new ReferenceParam("Patient/123").setMdmExpand(true)).setLoadSynchronous(true); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLink.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLink.java new file mode 100644 index 00000000000..bf87929d9bd --- /dev/null +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLink.java @@ -0,0 +1,24 @@ +package ca.uhn.fhir.mdm.api; + +/*- + * #%L + * HAPI FHIR - Master Data Management + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +public interface IMdmLink { +} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java index 7eda6f328d8..c65ee1c9e2d 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkEvent.java @@ -25,158 +25,32 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; public class MdmLinkEvent implements IModelJson { - @JsonProperty(value = "matchResult") - private MdmMatchResultEnum myMdmMatchResult; - @JsonProperty(value = "linkSource") - private MdmLinkSourceEnum myMdmLinkSource; - @JsonProperty(value = "eidMatch") - private Boolean myEidMatch; - @JsonProperty(value = "newGoldenResource") - private Boolean myNewGoldenResource; - @JsonProperty(value = "score") - private Double myScore; - @JsonProperty(value = "ruleCount") - private Long myRuleCount; - @JsonProperty(value = "targetResourceId", required = true) - private String myTargetResourceId; - @JsonProperty(value = "goldenResourceId", required = true) - private String myGoldenResourceId; - @JsonProperty(value = "duplicateResourceIds") - private Set myDuplicateGoldenResourceIds = new HashSet<>(); + private List myMdmLinks = new ArrayList<>(); - public String getGoldenResourceId() { - return myGoldenResourceId; + public List getMdmLinks() { + return myMdmLinks; } - public void setGoldenResourceId(IBaseResource theGoldenResourceId) { - setGoldenResourceId(getIdAsString(theGoldenResourceId)); + public void setMdmLinks(List theMdmLinks) { + myMdmLinks = theMdmLinks; } - public void setGoldenResourceId(String theGoldenResourceId) { - myGoldenResourceId = theGoldenResourceId; - } - - private String getIdAsString(IBaseResource theResource) { - if (theResource == null) { - return null; - } - IIdType idElement = theResource.getIdElement(); - if (idElement == null) { - return null; - } - return idElement.getValueAsString(); - } - - public String getTargetResourceId() { - return myTargetResourceId; - } - - public void setTargetResourceId(IBaseResource theTargetResource) { - setTargetResourceId(getIdAsString(theTargetResource)); - } - - public void setTargetResourceId(String theTargetResourceId) { - myTargetResourceId = theTargetResourceId; - } - - public Set getDuplicateGoldenResourceIds() { - return myDuplicateGoldenResourceIds; - } - - public void setDuplicateGoldenResourceIds(Set theDuplicateGoldenResourceIds) { - myDuplicateGoldenResourceIds = theDuplicateGoldenResourceIds; - } - - public MdmLinkEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) { - String id = getIdAsString(theDuplicateGoldenResourceId); - if (id != null) { - getDuplicateGoldenResourceIds().add(id); - } + public MdmLinkEvent addMdmLink(MdmLinkJson theMdmLink) { + getMdmLinks().add(theMdmLink); return this; } - public MdmMatchResultEnum getMdmMatchResult() { - return myMdmMatchResult; - } - - public void setMdmMatchResult(MdmMatchResultEnum theMdmMatchResult) { - myMdmMatchResult = theMdmMatchResult; - } - - public MdmLinkSourceEnum getMdmLinkSource() { - return myMdmLinkSource; - } - - public void setMdmLinkSource(MdmLinkSourceEnum theMdmLinkSource) { - myMdmLinkSource = theMdmLinkSource; - } - - public Boolean getEidMatch() { - return myEidMatch; - } - - public void setEidMatch(Boolean theEidMatch) { - if (theEidMatch == null) { - myEidMatch = Boolean.FALSE; - return; - } - myEidMatch = theEidMatch; - } - - public Boolean getNewGoldenResource() { - return myNewGoldenResource; - } - - public void setNewGoldenResource(Boolean theNewGoldenResource) { - if (theNewGoldenResource == null) { - myNewGoldenResource = Boolean.FALSE; - return; - } - myNewGoldenResource = theNewGoldenResource; - } - - public Double getScore() { - return myScore; - } - - public void setScore(Double theScore) { - myScore = theScore; - } - - public Long getRuleCount() { - return myRuleCount; - } - - public void setRuleCount(Long theRuleCount) { - myRuleCount = theRuleCount; - } - - public void setFromLink(MdmLinkJson theMdmLinkJson) { - setMdmMatchResult(theMdmLinkJson.getMatchResult()); - setMdmLinkSource(theMdmLinkJson.getLinkSource()); - setEidMatch(theMdmLinkJson.getEidMatch()); - setNewGoldenResource(theMdmLinkJson.getLinkCreatedNewResource()); - setScore(theMdmLinkJson.getScore()); - setRuleCount(theMdmLinkJson.getRuleCount()); - } - @Override public String toString() { - return "MdmLinkChangeEvent{" + - "myMdmMatchResult=" + myMdmMatchResult + - ", myMdmLinkSource=" + myMdmLinkSource + - ", myEidMatch=" + myEidMatch + - ", myNewGoldenResource=" + myNewGoldenResource + - ", myScore=" + myScore + - ", myRuleCount=" + myRuleCount + - ", myTargetResourceId='" + myTargetResourceId + '\'' + - ", myGoldenResourceId='" + myGoldenResourceId + '\'' + - ", myDuplicateGoldenResourceIds=" + myDuplicateGoldenResourceIds + + return "MdmLinkEvent{" + + "myMdmLinks=" + myMdmLinks + '}'; } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java index 4f13e7ac706..9047462d50f 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/model/MdmTransactionContext.java @@ -20,9 +20,13 @@ package ca.uhn.fhir.mdm.model; * #L% */ +import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.MdmLinkEvent; import ca.uhn.fhir.rest.server.TransactionLogMessages; +import java.util.ArrayList; +import java.util.List; + public class MdmTransactionContext { public enum OperationType { @@ -46,7 +50,7 @@ public class MdmTransactionContext { private String myResourceType; - private MdmLinkEvent myMdmLinkEvent = new MdmLinkEvent(); + private List myMdmLinkEvents = new ArrayList<>(); public TransactionLogMessages getTransactionLogMessages() { return myTransactionLogMessages; @@ -96,12 +100,16 @@ public class MdmTransactionContext { this.myResourceType = myResourceType; } - public MdmLinkEvent getMdmLinkEvent() { - return myMdmLinkEvent; + public List getMdmLinks() { + return myMdmLinkEvents; } - public void setMdmLinkChangeEvent(MdmLinkEvent theMdmLinkEvent) { - myMdmLinkEvent = theMdmLinkEvent; + public MdmTransactionContext addMdmLink(IMdmLink theMdmLinkEvent) { + getMdmLinks().add(theMdmLinkEvent); + return this; } + public void setMdmLinks(List theMdmLinkEvents) { + myMdmLinkEvents = theMdmLinkEvents; + } } From 010628fa86094000f3bda8b166d212bbd29ef31b Mon Sep 17 00:00:00 2001 From: Nick Goupinets Date: Tue, 7 Sep 2021 11:24:37 -0400 Subject: [PATCH 13/46] Added asserts --- .../fhir/jpa/mdm/interceptor/MdmEventIT.java | 17 ++++++++++++++--- .../java/ca/uhn/fhir/mdm/api/MdmLinkJson.java | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java index 39ec89b4c7d..cafbdebbff2 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmEventIT.java @@ -80,7 +80,19 @@ public class MdmEventIT extends BaseMdmR4Test { MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class); assertNotNull(linkChangeEvent); - // MdmTransactionContext ctx = myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, createContextForUpdate(patient2.getIdElement().getResourceType())); + ourLog.info("Got event: {}", linkChangeEvent); + + long expectTwoPossibleMatchesForPatientTwo = linkChangeEvent.getMdmLinks() + .stream() + .filter(l -> l.getSourceId().equals(patient2.getIdElement().toVersionless().getValueAsString()) && l.getMatchResult() == MdmMatchResultEnum.POSSIBLE_MATCH) + .count(); + assertEquals(2, expectTwoPossibleMatchesForPatientTwo); + + long expectOnePossibleDuplicate = linkChangeEvent.getMdmLinks() + .stream() + .filter(l -> l.getMatchResult() == MdmMatchResultEnum.POSSIBLE_DUPLICATE) + .count(); + assertEquals(1, expectOnePossibleDuplicate); List mdmLinkEvent = linkChangeEvent.getMdmLinks(); assertEquals(3, mdmLinkEvent.size()); @@ -122,10 +134,9 @@ public class MdmEventIT extends BaseMdmR4Test { assertEquals(1, linkChangeEvent.getMdmLinks().size()); MdmLinkJson link = linkChangeEvent.getMdmLinks().get(0); - assertEquals(patient1.getResourceType() + "/" + patient1.getIdElement().getIdPart(), link.getSourceId()); + assertEquals(patient1.getIdElement().toVersionless().getValueAsString(), link.getSourceId()); assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(link.getGoldenResourceId()).getIdPartAsLong()); assertEquals(MdmMatchResultEnum.MATCH, link.getMatchResult()); } - } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java index 424298418b4..d21f8deada6 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/MdmLinkJson.java @@ -175,4 +175,22 @@ public class MdmLinkJson implements IModelJson { public void setRuleCount(Long theRuleCount) { myRuleCount = theRuleCount; } + + @Override + public String toString() { + return "MdmLinkJson{" + + "myGoldenResourceId='" + myGoldenResourceId + '\'' + + ", mySourceId='" + mySourceId + '\'' + + ", myMatchResult=" + myMatchResult + + ", myLinkSource=" + myLinkSource + + ", myCreated=" + myCreated + + ", myUpdated=" + myUpdated + + ", myVersion='" + myVersion + '\'' + + ", myEidMatch=" + myEidMatch + + ", myLinkCreatedNewResource=" + myLinkCreatedNewResource + + ", myVector=" + myVector + + ", myScore=" + myScore + + ", myRuleCount=" + myRuleCount + + '}'; + } } From b224463d35e11e498584d0f2f14e7bc9f95657ce Mon Sep 17 00:00:00 2001 From: Tadgh Date: Fri, 10 Sep 2021 22:46:35 -0400 Subject: [PATCH 14/46] add broken test --- .../fhir/jpa/dao/r4/FhirSystemDaoR4Test.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index 88a0987be86..388d7696427 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -51,7 +51,9 @@ import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.DiagnosticReport; import org.hl7.fhir.r4.model.Encounter; import org.hl7.fhir.r4.model.EpisodeOfCare; +import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Medication; import org.hl7.fhir.r4.model.MedicationRequest; import org.hl7.fhir.r4.model.Meta; @@ -1161,6 +1163,48 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { validate(outcome); } + @Test + public void testConditionalUpdate_forObservationWithNonExistentPatientSubject_shouldCreateLinkedResources() { + Bundle transactionBundle = new Bundle().setType(BundleType.TRANSACTION); + + // Patient + HumanName patientName = new HumanName().setFamily("TEST_LAST_NAME").addGiven("TEST_FIRST_NAME"); + Identifier patientIdentifier = new Identifier().setSystem("http://example.com/mrns").setValue("U1234567890"); + Patient patient = new Patient() + .setName(List.of(patientName)) + .setIdentifier(List.of(patientIdentifier)); + patient.setId(IdType.newRandomUuid()); + + transactionBundle + .addEntry() + .setFullUrl(patient.getId()) + .setResource(patient) + .getRequest() + .setMethod(Bundle.HTTPVerb.PUT) + .setUrl("/Patient?identifier=" + patientIdentifier.getSystem() + "|" + patientIdentifier.getValue()); + + // Observation + Observation observation = new Observation(); + observation.setId(IdType.newRandomUuid()); + observation.getSubject().setReference(patient.getIdElement().toUnqualifiedVersionless().toString()); + + transactionBundle + .addEntry() + .setFullUrl(observation.getId()) + .setResource(observation) + .getRequest() + .setMethod(Bundle.HTTPVerb.PUT) + .setUrl("/Observation?subject=" + patient.getIdElement().toUnqualifiedVersionless().toString()); + + ourLog.info("Patient TEMP UUID: {}", patient.getId()); + String s = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(transactionBundle); + System.out.println(s); + Bundle outcome= mySystemDao.transaction(null, transactionBundle); + String patientLocation = outcome.getEntry().get(0).getResponse().getLocation(); + assertThat(patientLocation, matchesPattern("Patient/[a-z0-9-]+/_history/1")); + String observationLocation = outcome.getEntry().get(1).getResponse().getLocation(); + assertThat(observationLocation, matchesPattern("Observation/[a-z0-9-]+/_history/1")); + } @Test public void testTransactionCreateInlineMatchUrlWithOneMatch() { From 94f157a4ac7b1aef76d7cc5723fc7f24274e5e28 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Sat, 11 Sep 2021 15:13:05 -0400 Subject: [PATCH 15/46] Start refactoring of basetransactionprocessor --- hapi-fhir-jpaserver-base/pom.xml | 10 +- .../jpa/dao/BaseTransactionProcessor.java | 143 ++++++++++-------- .../fhir/jpa/dao/r4/FhirSystemDaoR4Test.java | 28 ++++ 3 files changed, 121 insertions(+), 60 deletions(-) diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index de3950d1860..b915ea16c06 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -815,7 +815,15 @@ - + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + ${project.basedir}/src/main/resources diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index d40d555a8de..ef476ec1d58 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -93,6 +93,7 @@ import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -481,7 +482,7 @@ public abstract class BaseTransactionProcessor { entries.sort(new TransactionSorter(placeholderIds)); // perform all writes - doTransactionWriteOperations(theRequestDetails, theActionName, + prepareThenExecuteTransactionWriteOperations(theRequestDetails, theActionName, transactionDetails, transactionStopWatch, response, originalRequestOrder, entries); @@ -584,38 +585,15 @@ public abstract class BaseTransactionProcessor { * heavy load with lots of concurrent transactions using all available * database connections. */ - private void doTransactionWriteOperations(RequestDetails theRequestDetails, String theActionName, - TransactionDetails theTransactionDetails, StopWatch theTransactionStopWatch, - IBaseBundle theResponse, IdentityHashMap theOriginalRequestOrder, - List theEntries) { + private void prepareThenExecuteTransactionWriteOperations(RequestDetails theRequestDetails, String theActionName, + TransactionDetails theTransactionDetails, StopWatch theTransactionStopWatch, + IBaseBundle theResponse, IdentityHashMap theOriginalRequestOrder, + List theEntries) { + TransactionWriteOperationsDetails writeOperationsDetails = null; - if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE, myInterceptorBroadcaster, theRequestDetails) || - CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_POST, myInterceptorBroadcaster, theRequestDetails)) { - - List updateRequestUrls = new ArrayList<>(); - List conditionalCreateRequestUrls = new ArrayList<>(); - for (IBase nextEntry : theEntries) { - String method = myVersionAdapter.getEntryRequestVerb(myContext, nextEntry); - if ("PUT".equals(method)) { - String requestUrl = myVersionAdapter.getEntryRequestUrl(nextEntry); - if (isNotBlank(requestUrl)) { - updateRequestUrls.add(requestUrl); - } - } else if ("POST".equals(method)) { - String requestUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextEntry); - if (isNotBlank(requestUrl) && requestUrl.contains("?")) { - conditionalCreateRequestUrls.add(requestUrl); - } - } - } - - writeOperationsDetails = new TransactionWriteOperationsDetails(); - writeOperationsDetails.setUpdateRequestUrls(updateRequestUrls); - writeOperationsDetails.setConditionalCreateRequestUrls(conditionalCreateRequestUrls); - HookParams params = new HookParams() - .add(TransactionDetails.class, theTransactionDetails) - .add(TransactionWriteOperationsDetails.class, writeOperationsDetails); - CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE, params); + if (haveWriteOperationsHooks(theRequestDetails)) { + writeOperationsDetails = buildWriteOperationsDetails(theEntries); + callWriteOperationsHook(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE, theRequestDetails, theTransactionDetails, writeOperationsDetails); } TransactionCallback> txCallback = status -> { @@ -636,13 +614,9 @@ public abstract class BaseTransactionProcessor { try { entriesToProcess = myHapiTransactionService.execute(theRequestDetails, theTransactionDetails, txCallback); - } - finally { - if (writeOperationsDetails != null) { - HookParams params = new HookParams() - .add(TransactionDetails.class, theTransactionDetails) - .add(TransactionWriteOperationsDetails.class, writeOperationsDetails); - CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_POST, params); + } finally { + if (haveWriteOperationsHooks(theRequestDetails)) { + callWriteOperationsHook(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_POST, theRequestDetails, theTransactionDetails, writeOperationsDetails); } } @@ -656,6 +630,45 @@ public abstract class BaseTransactionProcessor { } } + private boolean haveWriteOperationsHooks(RequestDetails theRequestDetails) { + return CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE, myInterceptorBroadcaster, theRequestDetails) || + CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_POST, myInterceptorBroadcaster, theRequestDetails); + } + + private void callWriteOperationsHook(Pointcut thePointcut, RequestDetails theRequestDetails, TransactionDetails theTransactionDetails, TransactionWriteOperationsDetails theWriteOperationsDetails) { + HookParams params = new HookParams() + .add(TransactionDetails.class, theTransactionDetails) + .add(TransactionWriteOperationsDetails.class, theWriteOperationsDetails); + CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, thePointcut, params); + } + + @NotNull + private TransactionWriteOperationsDetails buildWriteOperationsDetails(List theEntries) { + TransactionWriteOperationsDetails writeOperationsDetails; + List updateRequestUrls = new ArrayList<>(); + List conditionalCreateRequestUrls = new ArrayList<>(); + //Extract + for (IBase nextEntry : theEntries) { + String method = myVersionAdapter.getEntryRequestVerb(myContext, nextEntry); + if ("PUT".equals(method)) { + String requestUrl = myVersionAdapter.getEntryRequestUrl(nextEntry); + if (isNotBlank(requestUrl)) { + updateRequestUrls.add(requestUrl); + } + } else if ("POST".equals(method)) { + String requestUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextEntry); + if (isNotBlank(requestUrl) && requestUrl.contains("?")) { + conditionalCreateRequestUrls.add(requestUrl); + } + } + } + + writeOperationsDetails = new TransactionWriteOperationsDetails(); + writeOperationsDetails.setUpdateRequestUrls(updateRequestUrls); + writeOperationsDetails.setConditionalCreateRequestUrls(conditionalCreateRequestUrls); + return writeOperationsDetails; + } + private boolean isValidVerb(String theVerb) { try { return org.hl7.fhir.r4.model.Bundle.HTTPVerb.fromCode(theVerb) != null; @@ -704,7 +717,7 @@ public abstract class BaseTransactionProcessor { IBaseResource resource = myVersionAdapter.getResource(nextReqEntry); if (resource != null) { String verb = myVersionAdapter.getEntryRequestVerb(myContext, nextReqEntry); - String entryUrl = myVersionAdapter.getFullUrl(nextReqEntry); + String entryFullUrl = myVersionAdapter.getFullUrl(nextReqEntry); String requestUrl = myVersionAdapter.getEntryRequestUrl(nextReqEntry); String ifNoneExist = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry); String key = verb + "|" + requestUrl + "|" + ifNoneExist; @@ -712,7 +725,7 @@ public abstract class BaseTransactionProcessor { // Conditional UPDATE boolean consolidateEntry = false; if ("PUT".equals(verb)) { - if (isNotBlank(entryUrl) && isNotBlank(requestUrl)) { + if (isNotBlank(entryFullUrl) && isNotBlank(requestUrl)) { int questionMarkIndex = requestUrl.indexOf('?'); if (questionMarkIndex >= 0 && requestUrl.length() > (questionMarkIndex + 1)) { consolidateEntry = true; @@ -722,8 +735,8 @@ public abstract class BaseTransactionProcessor { // Conditional CREATE if ("POST".equals(verb)) { - if (isNotBlank(entryUrl) && isNotBlank(requestUrl) && isNotBlank(ifNoneExist)) { - if (!entryUrl.equals(requestUrl)) { + if (isNotBlank(entryFullUrl) && isNotBlank(requestUrl) && isNotBlank(ifNoneExist)) { + if (!entryFullUrl.equals(requestUrl)) { consolidateEntry = true; } } @@ -731,33 +744,41 @@ public abstract class BaseTransactionProcessor { if (consolidateEntry) { if (!keyToUuid.containsKey(key)) { - keyToUuid.put(key, entryUrl); + keyToUuid.put(key, entryFullUrl); } else { ourLog.info("Discarding transaction bundle entry {} as it contained a duplicate conditional {}", originalIndex, verb); theEntries.remove(index); index--; String existingUuid = keyToUuid.get(key); - for (IBase nextEntry : theEntries) { - IBaseResource nextResource = myVersionAdapter.getResource(nextEntry); - for (IBaseReference nextReference : myContext.newTerser().getAllPopulatedChildElementsOfType(nextResource, IBaseReference.class)) { - // We're interested in any references directly to the placeholder ID, but also - // references that have a resource target that has the placeholder ID. - String nextReferenceId = nextReference.getReferenceElement().getValue(); - if (isBlank(nextReferenceId) && nextReference.getResource() != null) { - nextReferenceId = nextReference.getResource().getIdElement().getValue(); - } - if (entryUrl.equals(nextReferenceId)) { - nextReference.setReference(existingUuid); - nextReference.setResource(null); - } - } - } + replaceReferencesInEntriesWithConsolidatedUUID(theEntries, entryFullUrl, existingUuid); } } } } } + /** + * Iterates over all entries, and if it finds any which have references which match the fullUrl of the entry that was consolidated out + * replace them with our new consolidated UUID + */ + private void replaceReferencesInEntriesWithConsolidatedUUID(List theEntries, String theEntryFullUrl, String existingUuid) { + for (IBase nextEntry : theEntries) { + IBaseResource nextResource = myVersionAdapter.getResource(nextEntry); + for (IBaseReference nextReference : myContext.newTerser().getAllPopulatedChildElementsOfType(nextResource, IBaseReference.class)) { + // We're interested in any references directly to the placeholder ID, but also + // references that have a resource target that has the placeholder ID. + String nextReferenceId = nextReference.getReferenceElement().getValue(); + if (isBlank(nextReferenceId) && nextReference.getResource() != null) { + nextReferenceId = nextReference.getResource().getIdElement().getValue(); + } + if (theEntryFullUrl.equals(nextReferenceId)) { + nextReference.setReference(existingUuid); + nextReference.setResource(null); + } + } + } + } + /** * Retrieves the next resource id (IIdType) from the base resource and next request entry. * @param theBaseResource - base resource @@ -810,12 +831,16 @@ public abstract class BaseTransactionProcessor { return nextResourceId; } + /** After pre-hooks have been called + * + */ protected Map doTransactionWriteOperations(final RequestDetails theRequest, String theActionName, TransactionDetails theTransactionDetails, Set theAllIds, Map theIdSubstitutions, Map theIdToPersistedOutcome, IBaseBundle theResponse, IdentityHashMap theOriginalRequestOrder, List theEntries, StopWatch theTransactionStopWatch) { + // During a transaction, we don't execute hooks, instead, we execute them all post-transaction. theTransactionDetails.beginAcceptingDeferredInterceptorBroadcasts( Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED, Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index 388d7696427..595716b47fb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -1206,6 +1206,34 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { assertThat(observationLocation, matchesPattern("Observation/[a-z0-9-]+/_history/1")); } + @Test + public void testConditionalUrlWhichDoesNotMatcHResource() { + Bundle transactionBundle = new Bundle().setType(BundleType.TRANSACTION); + + // Patient + HumanName patientName = new HumanName().setFamily("TEST_LAST_NAME").addGiven("TEST_FIRST_NAME"); + Identifier patientIdentifier = new Identifier().setSystem("http://example.com/mrns").setValue("U1234567890"); + Patient patient = new Patient() + .setName(List.of(patientName)) + .setIdentifier(List.of(patientIdentifier)); + patient.setId(IdType.newRandomUuid()); + + transactionBundle + .addEntry() + .setFullUrl(patient.getId()) + .setResource(patient) + .getRequest() + .setMethod(Bundle.HTTPVerb.PUT) + .setUrl("/Patient?identifier=" + patientIdentifier.getSystem() + "|" + "zoop"); + + ourLog.info("Patient TEMP UUID: {}", patient.getId()); + String s = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(transactionBundle); + System.out.println(s); + Bundle outcome= mySystemDao.transaction(null, transactionBundle); + String patientLocation = outcome.getEntry().get(0).getResponse().getLocation(); + assertThat(patientLocation, matchesPattern("Patient/[a-z0-9-]+/_history/1")); + } + @Test public void testTransactionCreateInlineMatchUrlWithOneMatch() { String methodName = "testTransactionCreateInlineMatchUrlWithOneMatch"; From 59c8765e6ae9c46559c8d03a3f710a3684571707 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 13:03:44 -0400 Subject: [PATCH 16/46] Add implementation to validate conditional URLs post-transaction --- .../jpa/dao/BaseTransactionProcessor.java | 43 ++++++++++++++++++- .../fhir/jpa/dao/r4/FhirSystemDaoR4Test.java | 23 ++++++---- .../src/test/resources/logback-test.xml | 2 +- .../matcher/InMemoryResourceMatcher.java | 1 + 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index ef476ec1d58..f98e01cb0b5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -44,7 +44,9 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; +import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryMatchResult; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; +import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.parser.DataFormatException; @@ -64,6 +66,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.NotModifiedException; import ca.uhn.fhir.rest.server.exceptions.PayloadTooLargeException; +import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding; @@ -157,6 +160,8 @@ public abstract class BaseTransactionProcessor { private ModelConfig myModelConfig; @Autowired private InMemoryResourceMatcher myInMemoryResourceMatcher; + @Autowired + private SearchParamMatcher mySearchParamMatcher; private TaskExecutor myExecutor ; @@ -852,6 +857,7 @@ public abstract class BaseTransactionProcessor { Map entriesToProcess = new IdentityHashMap<>(); Set nonUpdatedEntities = new HashSet<>(); Set updatedEntities = new HashSet<>(); + Map conditionalUrlToIdMap = new HashMap<>(); List updatedResources = new ArrayList<>(); Map> conditionalRequestUrls = new HashMap<>(); @@ -891,6 +897,7 @@ public abstract class BaseTransactionProcessor { String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry); matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); outcome = resourceDao.create(res, matchUrl, false, theTransactionDetails, theRequest); + conditionalUrlToIdMap.put(matchUrl, outcome.getId()); res.setId(outcome.getId()); if (nextResourceId != null) { handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest); @@ -925,6 +932,7 @@ public abstract class BaseTransactionProcessor { String matchUrl = parts.getResourceType() + '?' + parts.getParams(); matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(matchUrl, deleteConflicts, theRequest); + conditionalUrlToIdMap.put(matchUrl, deleteOutcome.getId()); List allDeleted = deleteOutcome.getDeletedEntities(); for (ResourceTable deleted : allDeleted) { deletedResources.add(deleted.getIdDt().toUnqualifiedVersionless().getValueAsString()); @@ -967,6 +975,7 @@ public abstract class BaseTransactionProcessor { } matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); outcome = resourceDao.update(res, matchUrl, false, false, theRequest, theTransactionDetails); + conditionalUrlToIdMap.put(matchUrl, outcome.getId()); if (Boolean.TRUE.equals(outcome.getCreated())) { conditionalRequestUrls.put(matchUrl, res.getClass()); } @@ -1025,6 +1034,7 @@ public abstract class BaseTransactionProcessor { IFhirResourceDao dao = toDao(parts, verb, url); IIdType patchId = myContext.getVersion().newIdType().setValue(parts.getResourceId()); DaoMethodOutcome outcome = dao.patch(patchId, matchUrl, patchType, patchBody, patchBodyParameters, theRequest); + conditionalUrlToIdMap.put(matchUrl, outcome.getId()); updatedEntities.add(outcome.getEntity()); if (outcome.getResource() != null) { updatedResources.add(outcome.getResource()); @@ -1081,6 +1091,11 @@ public abstract class BaseTransactionProcessor { if (!myDaoConfig.isMassIngestionMode()) { validateNoDuplicates(theRequest, theActionName, conditionalRequestUrls, theIdToPersistedOutcome.values()); } + + if (!myDaoConfig.isMassIngestionMode()) { + validateAllInsertsMatchTheirConditionalUrls(theIdToPersistedOutcome, conditionalUrlToIdMap, theRequest); + } + theTransactionStopWatch.endCurrentTask(); for (IIdType next : theAllIds) { @@ -1119,6 +1134,32 @@ public abstract class BaseTransactionProcessor { } } + /** + * After transaction processing and resolution of indexes and references, we want to validate that the resources that were stored _actually_ + * match the conditional URLs that they were brought in on. + * @param theIdToPersistedOutcome + * @param conditionalUrlToIdMap + */ + private void validateAllInsertsMatchTheirConditionalUrls(Map theIdToPersistedOutcome, Map conditionalUrlToIdMap, RequestDetails theRequest) { + conditionalUrlToIdMap.entrySet().stream() + .forEach(entry -> { + String matchUrl = entry.getKey(); + IIdType value = entry.getValue(); + DaoMethodOutcome daoMethodOutcome = theIdToPersistedOutcome.get(value); + if (daoMethodOutcome != null && daoMethodOutcome.getResource() != null) { + InMemoryMatchResult match = mySearchParamMatcher.match(matchUrl, daoMethodOutcome.getResource(), theRequest); + if (ourLog.isDebugEnabled()) { + ourLog.debug("Checking conditional URL [{}] against resource with ID [{}]: Supported?:[{}], Matched?:[{}]", matchUrl, value, match.supported(), match.matched()); + } + if (match.supported()) { + if (!match.matched()) { + throw new PreconditionFailedException("Invalid conditional URL \"" + matchUrl + "\". The given resource is not matched by this URL."); + }; + } + } + }); + } + /** * Checks for any delete conflicts. * @param theDeleteConflicts - set of delete conflicts @@ -1409,7 +1450,7 @@ public abstract class BaseTransactionProcessor { thePersistedOutcomes .stream() .filter(t -> !t.isNop()) - .filter(t -> t.getEntity() instanceof ResourceTable) + .filter(t -> t.getEntity() instanceof ResourceTable)//N.B. GGG: This validation never occurs for mongo, as nothing is a ResourceTable. .filter(t -> t.getEntity().getDeleted() == null) .filter(t -> t.getResource() != null) .forEach(t -> resourceToIndexedParams.put(t.getResource(), new ResourceIndexedSearchParams((ResourceTable) t.getEntity()))); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index 595716b47fb..a0fdc180f78 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -98,7 +98,9 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.emptyString; import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; @@ -1207,12 +1209,14 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { } @Test - public void testConditionalUrlWhichDoesNotMatcHResource() { + public void testConditionalUrlWhichDoesNotMatchResource() { Bundle transactionBundle = new Bundle().setType(BundleType.TRANSACTION); + String storedIdentifierValue = "woop"; + String conditionalUrlIdentifierValue = "zoop"; // Patient HumanName patientName = new HumanName().setFamily("TEST_LAST_NAME").addGiven("TEST_FIRST_NAME"); - Identifier patientIdentifier = new Identifier().setSystem("http://example.com/mrns").setValue("U1234567890"); + Identifier patientIdentifier = new Identifier().setSystem("http://example.com/mrns").setValue(storedIdentifierValue); Patient patient = new Patient() .setName(List.of(patientName)) .setIdentifier(List.of(patientIdentifier)); @@ -1224,14 +1228,14 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { .setResource(patient) .getRequest() .setMethod(Bundle.HTTPVerb.PUT) - .setUrl("/Patient?identifier=" + patientIdentifier.getSystem() + "|" + "zoop"); + .setUrl("/Patient?identifier=" + patientIdentifier.getSystem() + "|" + conditionalUrlIdentifierValue); - ourLog.info("Patient TEMP UUID: {}", patient.getId()); - String s = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(transactionBundle); - System.out.println(s); - Bundle outcome= mySystemDao.transaction(null, transactionBundle); - String patientLocation = outcome.getEntry().get(0).getResponse().getLocation(); - assertThat(patientLocation, matchesPattern("Patient/[a-z0-9-]+/_history/1")); + try { + mySystemDao.transaction(null, transactionBundle); + fail(); + } catch (PreconditionFailedException e) { + assertThat(e.getMessage(), is(equalTo("Invalid conditional URL \"Patient?identifier=http://example.com/mrns|" + conditionalUrlIdentifierValue +"\". The given resource is not matched by this URL."))); + } } @Test @@ -1267,6 +1271,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { } + @Test public void testTransactionUpdateTwoResourcesWithSameId() { Bundle request = new Bundle(); diff --git a/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml b/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml index ac75e0d04be..36a83af6599 100644 --- a/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml +++ b/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml @@ -42,7 +42,7 @@ - + diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index f6d0027898f..24a0483b823 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -156,6 +156,7 @@ public class InMemoryResourceMatcher { String resourceName = theResourceDefinition.getName(); RuntimeSearchParam paramDef = mySearchParamRegistry.getActiveSearchParam(resourceName, theParamName); InMemoryMatchResult checkUnsupportedResult = checkUnsupportedPrefixes(theParamName, paramDef, theAndOrParams); + if (!checkUnsupportedResult.supported()) { return checkUnsupportedResult; } From 4aa1329e110a17f0b13d7fc82cd8d82354a1c164 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 13:13:28 -0400 Subject: [PATCH 17/46] Fix up changelog --- .../fhir/changelog/5_6_0/2987-validate-conditional-urls.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2987-validate-conditional-urls.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2987-validate-conditional-urls.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2987-validate-conditional-urls.yaml new file mode 100644 index 00000000000..ce1048e8ece --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2987-validate-conditional-urls.yaml @@ -0,0 +1,5 @@ +--- +type: change +jira: SMILE-2927 +title: "During transactions, any resources that were PUT or POSTed with a conditional URL now receive extra validation. There is now a final +storage step which ensures that the stored resource actually matches the conditional URL." From a0cd83398b8e206ffc0dcb5f82179e3536d7edf2 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 20:52:14 -0400 Subject: [PATCH 18/46] Bump test java to 16 --- hapi-fhir-jpaserver-base/pom.xml | 8 -------- pom.xml | 2 ++ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index c37ee56d4e8..428612b17c4 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -815,14 +815,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - diff --git a/pom.xml b/pom.xml index b808fcf355c..841a4eabbea 100644 --- a/pom.xml +++ b/pom.xml @@ -2001,6 +2001,8 @@ 1.8 1.8 + 16 + 16 true UTF-8 true From b2f881cb76f833613e74dff40373994b425ea29d Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 21:09:48 -0400 Subject: [PATCH 19/46] java 16 --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d8ccce15b76..9d968dfed1d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,7 +15,7 @@ pool: jobs: - job: Build timeoutInMinutes: 360 - container: maven:3-openjdk-15 + container: maven:3-openjdk-16 steps: - task: DockerInstaller@0 displayName: Docker Installer @@ -32,7 +32,7 @@ jobs: script: mkdir -p $(MAVEN_CACHE_FOLDER); pwd; ls -al $(MAVEN_CACHE_FOLDER) - task: Maven@3 env: - JAVA_HOME_11_X64: /usr/java/openjdk-15 + JAVA_HOME_11_X64: /usr/java/openjdk-16 inputs: goals: 'clean install' # These are Maven CLI options (and show up in the build logs) - "-nsu"=Don't update snapshots. We can remove this when Maven OSS is more healthy From b4e2679872f30f7310b2e416215ea8551c9c9ffd Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 21:15:23 -0400 Subject: [PATCH 20/46] Remove jetbrains --- .../java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java | 3 +-- .../src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index f98e01cb0b5..8b359bb9229 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -96,7 +96,6 @@ import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; -import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -647,7 +646,7 @@ public abstract class BaseTransactionProcessor { CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, thePointcut, params); } - @NotNull + private TransactionWriteOperationsDetails buildWriteOperationsDetails(List theEntries) { TransactionWriteOperationsDetails writeOperationsDetails; List updateRequestUrls = new ArrayList<>(); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java index 96115a95bf2..055f12a25b7 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java @@ -61,7 +61,6 @@ import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Reference; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; From 1ca313f8ad9b0498ba6071792681dc05e81ca71f Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 21:27:05 -0400 Subject: [PATCH 21/46] lower logging --- hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml b/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml index 36a83af6599..ac75e0d04be 100644 --- a/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml +++ b/hapi-fhir-jpaserver-base/src/test/resources/logback-test.xml @@ -42,7 +42,7 @@ - + From b58d63dc7ccfa1fc1287d4f060dbea1502caae8f Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 21:34:14 -0400 Subject: [PATCH 22/46] Remove usage of 16 --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 841a4eabbea..b808fcf355c 100644 --- a/pom.xml +++ b/pom.xml @@ -2001,8 +2001,6 @@ 1.8 1.8 - 16 - 16 true UTF-8 true From fcf8c434f5ad93277d61baf10e026f6f2debd7f9 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Mon, 13 Sep 2021 21:41:52 -0400 Subject: [PATCH 23/46] jdk --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9d968dfed1d..d8ccce15b76 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,7 +15,7 @@ pool: jobs: - job: Build timeoutInMinutes: 360 - container: maven:3-openjdk-16 + container: maven:3-openjdk-15 steps: - task: DockerInstaller@0 displayName: Docker Installer @@ -32,7 +32,7 @@ jobs: script: mkdir -p $(MAVEN_CACHE_FOLDER); pwd; ls -al $(MAVEN_CACHE_FOLDER) - task: Maven@3 env: - JAVA_HOME_11_X64: /usr/java/openjdk-16 + JAVA_HOME_11_X64: /usr/java/openjdk-15 inputs: goals: 'clean install' # These are Maven CLI options (and show up in the build logs) - "-nsu"=Don't update snapshots. We can remove this when Maven OSS is more healthy From 49debec36a18b281e69016ef01d74a2debdbb465 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Sep 2021 10:48:56 -0400 Subject: [PATCH 24/46] Fix problem with null conditionals --- .../fhir/jpa/dao/BaseTransactionProcessor.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index 8b359bb9229..8e4034f688b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -83,6 +83,7 @@ import ca.uhn.fhir.util.UrlUtil; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.exceptions.FHIRException; @@ -896,8 +897,8 @@ public abstract class BaseTransactionProcessor { String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry); matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); outcome = resourceDao.create(res, matchUrl, false, theTransactionDetails, theRequest); - conditionalUrlToIdMap.put(matchUrl, outcome.getId()); - res.setId(outcome.getId()); + setConditionalUrlToBeValidatedLater(conditionalUrlToIdMap, matchUrl, outcome.getId()); + res.setId(outcome.getId()); if (nextResourceId != null) { handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest); } @@ -931,7 +932,7 @@ public abstract class BaseTransactionProcessor { String matchUrl = parts.getResourceType() + '?' + parts.getParams(); matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(matchUrl, deleteConflicts, theRequest); - conditionalUrlToIdMap.put(matchUrl, deleteOutcome.getId()); + setConditionalUrlToBeValidatedLater(conditionalUrlToIdMap, matchUrl, deleteOutcome.getId()); List allDeleted = deleteOutcome.getDeletedEntities(); for (ResourceTable deleted : allDeleted) { deletedResources.add(deleted.getIdDt().toUnqualifiedVersionless().getValueAsString()); @@ -974,7 +975,7 @@ public abstract class BaseTransactionProcessor { } matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); outcome = resourceDao.update(res, matchUrl, false, false, theRequest, theTransactionDetails); - conditionalUrlToIdMap.put(matchUrl, outcome.getId()); + setConditionalUrlToBeValidatedLater(conditionalUrlToIdMap, matchUrl, outcome.getId()); if (Boolean.TRUE.equals(outcome.getCreated())) { conditionalRequestUrls.put(matchUrl, res.getClass()); } @@ -1033,7 +1034,7 @@ public abstract class BaseTransactionProcessor { IFhirResourceDao dao = toDao(parts, verb, url); IIdType patchId = myContext.getVersion().newIdType().setValue(parts.getResourceId()); DaoMethodOutcome outcome = dao.patch(patchId, matchUrl, patchType, patchBody, patchBodyParameters, theRequest); - conditionalUrlToIdMap.put(matchUrl, outcome.getId()); + setConditionalUrlToBeValidatedLater(conditionalUrlToIdMap, matchUrl, outcome.getId()); updatedEntities.add(outcome.getEntity()); if (outcome.getResource() != null) { updatedResources.add(outcome.getResource()); @@ -1133,6 +1134,12 @@ public abstract class BaseTransactionProcessor { } } + private void setConditionalUrlToBeValidatedLater(Map theConditionalUrlToIdMap, String theMatchUrl, IIdType theId) { + if (!StringUtils.isBlank(theMatchUrl)) { + theConditionalUrlToIdMap.put(theMatchUrl, theId); + } + } + /** * After transaction processing and resolution of indexes and references, we want to validate that the resources that were stored _actually_ * match the conditional URLs that they were brought in on. @@ -1141,6 +1148,7 @@ public abstract class BaseTransactionProcessor { */ private void validateAllInsertsMatchTheirConditionalUrls(Map theIdToPersistedOutcome, Map conditionalUrlToIdMap, RequestDetails theRequest) { conditionalUrlToIdMap.entrySet().stream() + .filter(entry -> entry.getKey() != null) .forEach(entry -> { String matchUrl = entry.getKey(); IIdType value = entry.getValue(); From 9771210553d08ff636ed69534a339056a8836bec Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Sep 2021 13:40:53 -0400 Subject: [PATCH 25/46] Prefer non-lazy outcomes in map --- .../jpa/api/model/LazyDaoMethodOutcome.java | 2 -- .../jpa/dao/BaseTransactionProcessor.java | 26 +++++++++++++++++-- .../fhir/jpa/dao/r4/FhirSystemDaoR4Test.java | 6 ++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java index 0ed9808a84e..07caf13ad19 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java +++ b/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java @@ -52,13 +52,11 @@ public class LazyDaoMethodOutcome extends DaoMethodOutcome { private void tryToRunSupplier() { if (myEntitySupplier != null) { - EntityAndResource entityAndResource = myEntitySupplier.get(); setEntity(entityAndResource.getEntity()); setResource(entityAndResource.getResource()); setId(entityAndResource.getResource().getIdElement()); myEntitySupplierUseCallback.run(); - } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index 8e4034f688b..6804fcb9848 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -35,6 +35,7 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.api.model.DeleteConflict; import ca.uhn.fhir.jpa.api.model.DeleteConflictList; import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome; +import ca.uhn.fhir.jpa.api.model.LazyDaoMethodOutcome; import ca.uhn.fhir.jpa.cache.IResourceVersionSvc; import ca.uhn.fhir.jpa.cache.ResourcePersistentIdMap; import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; @@ -280,7 +281,9 @@ public abstract class BaseTransactionProcessor { idSubstitutions.put(id, newId); } } - idToPersistedOutcome.put(newId, outcome); + + populateIdToPersistedOutcomeMap(idToPersistedOutcome, newId, outcome); + if (outcome.getCreated()) { myVersionAdapter.setResponseStatus(newEntry, toStatusString(Constants.STATUS_HTTP_201_CREATED)); } else { @@ -304,6 +307,21 @@ public abstract class BaseTransactionProcessor { } + /** Method which populates entry in idToPersistedOutcome. + * Will store whatever outcome is sent, unless the key already exists, then we only replace an instance if we find that the instance + * we are replacing with is non-lazy. This allows us to evaluate later more easily, as we _know_ we need access to these. + */ + private void populateIdToPersistedOutcomeMap(Map idToPersistedOutcome, IIdType newId, DaoMethodOutcome outcome) { + //Prefer real method outcomes over lazy ones. + if (idToPersistedOutcome.containsKey(newId)) { + if (!(outcome instanceof LazyDaoMethodOutcome)) { + idToPersistedOutcome.put(newId, outcome); + } + } else { + idToPersistedOutcome.put(newId, outcome); + } + } + private Date getLastModified(IBaseResource theRes) { return theRes.getMeta().getLastUpdated(); } @@ -1092,10 +1110,14 @@ public abstract class BaseTransactionProcessor { validateNoDuplicates(theRequest, theActionName, conditionalRequestUrls, theIdToPersistedOutcome.values()); } + theTransactionStopWatch.endCurrentTask(); + if (conditionalUrlToIdMap.size() > 0) { + theTransactionStopWatch.startTask("Check that all conditionally created/updated entities actually match their conditionals."); + } + if (!myDaoConfig.isMassIngestionMode()) { validateAllInsertsMatchTheirConditionalUrls(theIdToPersistedOutcome, conditionalUrlToIdMap, theRequest); } - theTransactionStopWatch.endCurrentTask(); for (IIdType next : theAllIds) { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index a0fdc180f78..7e7bd26fbd7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -1824,9 +1824,9 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { p.addIdentifier().setSystem("urn:system").setValue(methodName); request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName); - p = new Patient(); - p.addIdentifier().setSystem("urn:system").setValue(methodName); - request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST); +// p = new Patient(); +// p.addIdentifier().setSystem("urn:system").setValue(methodName); +// request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST); try { mySystemDao.transaction(mySrd, request); From b25bdc1169dd8e685cfc6ecdb5a6b16f9471e044 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Sep 2021 13:48:37 -0400 Subject: [PATCH 26/46] Remove crazy double encoding --- .../ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java | 6 +++--- .../src/test/resources/cdr-bundle.json | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index 7e7bd26fbd7..a0fdc180f78 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -1824,9 +1824,9 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { p.addIdentifier().setSystem("urn:system").setValue(methodName); request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName); -// p = new Patient(); -// p.addIdentifier().setSystem("urn:system").setValue(methodName); -// request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST); + p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue(methodName); + request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST); try { mySystemDao.transaction(mySrd, request); diff --git a/hapi-fhir-jpaserver-base/src/test/resources/cdr-bundle.json b/hapi-fhir-jpaserver-base/src/test/resources/cdr-bundle.json index 2e8644593a5..9afb12a7cc8 100644 --- a/hapi-fhir-jpaserver-base/src/test/resources/cdr-bundle.json +++ b/hapi-fhir-jpaserver-base/src/test/resources/cdr-bundle.json @@ -44,7 +44,7 @@ }, "request": { "method": "PUT", - "url": "/Practitioner?identifier=http%253A%252F%252Facme.org%252Fclinicians%257C777" + "url": "/Practitioner?identifier=http%3A%2F%2Facme.org%2Fclinicians%7C777" } }, { @@ -125,7 +125,7 @@ }, "request": { "method": "PUT", - "url": "/Patient?identifier=http%253A%252F%252Facme.org%252Fmrns%257C7000135" + "url": "/Patient?identifier=http%3A%2F%2Facme.org%2Fmrns%7C7000135" } }, { @@ -203,7 +203,7 @@ }, "request": { "method": "PUT", - "url": "/Encounter?identifier=http%253A%252F%252Facme.org%252FvisitNumbers%257C4736455" + "url": "/Encounter?identifier=http%3A%2F%2Facme.org%2FvisitNumbers%7C4736455" } }, { @@ -267,7 +267,7 @@ }, "request": { "method": "PUT", - "url": "/Practitioner?identifier=http%253A%252F%252Facme.org%252Fclinicians%257C3622" + "url": "/Practitioner?identifier=http%3A%2F%2Facme.org%2Fclinicians%7C3622" } }, { @@ -312,8 +312,8 @@ }, "request": { "method": "PUT", - "url": "/Practitioner?identifier=http%253A%252F%252Facme.org%252Fclinicians%257C7452" + "url": "/Practitioner?identifier=http%3A%2F%2Facme.org%2Fclinicians%7C7452" } } ] -} \ No newline at end of file +} From bb5e04e7064c242dd34ff83b6e5c36a1a23fedee Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Sep 2021 17:22:25 -0400 Subject: [PATCH 27/46] Fix broken test --- .../ca/uhn/fhir/jpa/dao/TransactionProcessorTest.java | 3 +++ .../java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/TransactionProcessorTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/TransactionProcessorTest.java index f48b4ede91f..02a797f60f6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/TransactionProcessorTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/TransactionProcessorTest.java @@ -13,6 +13,7 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; +import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import org.hibernate.Session; import org.hibernate.internal.SessionImpl; @@ -72,6 +73,8 @@ public class TransactionProcessorTest { private IRequestPartitionHelperSvc myRequestPartitionHelperSvc; @MockBean private IResourceVersionSvc myResourceVersionSvc; + @MockBean + private SearchParamMatcher mySearchParamMatcher; @MockBean(answer = Answers.RETURNS_DEEP_STUBS) private SessionImpl mySession; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java index a0fdc180f78..fd513807f31 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4Test.java @@ -85,6 +85,7 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -1173,8 +1174,8 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { HumanName patientName = new HumanName().setFamily("TEST_LAST_NAME").addGiven("TEST_FIRST_NAME"); Identifier patientIdentifier = new Identifier().setSystem("http://example.com/mrns").setValue("U1234567890"); Patient patient = new Patient() - .setName(List.of(patientName)) - .setIdentifier(List.of(patientIdentifier)); + .setName(Arrays.asList(patientName)) + .setIdentifier(Arrays.asList(patientIdentifier)); patient.setId(IdType.newRandomUuid()); transactionBundle @@ -1218,8 +1219,8 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { HumanName patientName = new HumanName().setFamily("TEST_LAST_NAME").addGiven("TEST_FIRST_NAME"); Identifier patientIdentifier = new Identifier().setSystem("http://example.com/mrns").setValue(storedIdentifierValue); Patient patient = new Patient() - .setName(List.of(patientName)) - .setIdentifier(List.of(patientIdentifier)); + .setName(Arrays.asList(patientName)) + .setIdentifier(Arrays.asList(patientIdentifier)); patient.setId(IdType.newRandomUuid()); transactionBundle From 9bb1558b714d5266da478dbb967d18806d2111d5 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Sep 2021 17:45:09 -0400 Subject: [PATCH 28/46] Update query count ttest --- .../uhn/fhir/jpa/dao/BaseTransactionProcessor.java | 1 + .../dao/r4/FhirResourceDaoR4QueryCountTest.java | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index 6804fcb9848..d57891839e3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -1175,6 +1175,7 @@ public abstract class BaseTransactionProcessor { String matchUrl = entry.getKey(); IIdType value = entry.getValue(); DaoMethodOutcome daoMethodOutcome = theIdToPersistedOutcome.get(value); + //TODO GGG: daoMethodOutcome.getResource() actually executes a DB select query. Any way to avoid this?? if (daoMethodOutcome != null && daoMethodOutcome.getResource() != null) { InMemoryMatchResult match = mySearchParamMatcher.match(matchUrl, daoMethodOutcome.getResource(), theRequest); if (ourLog.isDebugEnabled()) { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java index 580cb632e94..06a8110de62 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java @@ -964,7 +964,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test outcome = mySystemDao.transaction(mySrd, input.get()); ourLog.info("Resp: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); myCaptureQueriesListener.logSelectQueries(); - assertEquals(11, myCaptureQueriesListener.countSelectQueries()); + assertEquals(12, myCaptureQueriesListener.countSelectQueries()); myCaptureQueriesListener.logInsertQueries(); assertEquals(1, myCaptureQueriesListener.countInsertQueries()); myCaptureQueriesListener.logUpdateQueries(); @@ -1043,7 +1043,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); myCaptureQueriesListener.logSelectQueries(); - assertEquals(1, myCaptureQueriesListener.countSelectQueries()); + assertEquals(3, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1056,7 +1056,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); - assertEquals(0, myCaptureQueriesListener.countSelectQueries()); + assertEquals(2, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1105,7 +1105,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); myCaptureQueriesListener.logSelectQueries(); - assertEquals(2, myCaptureQueriesListener.countSelectQueries()); + assertEquals(4, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1123,7 +1123,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); - assertEquals(1, myCaptureQueriesListener.countSelectQueries()); + assertEquals(3, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1706,7 +1706,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test // Lookup the two existing IDs to make sure they are legit myCaptureQueriesListener.logSelectQueriesForCurrentThread(); - assertEquals(3, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); + assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); assertEquals(3, myCaptureQueriesListener.countInsertQueriesForCurrentThread()); assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread()); assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread()); @@ -1765,7 +1765,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test // Lookup the two existing IDs to make sure they are legit myCaptureQueriesListener.logSelectQueriesForCurrentThread(); - assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); + assertEquals(5, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); assertEquals(3, myCaptureQueriesListener.countInsertQueriesForCurrentThread()); assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread()); assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread()); From 8f0e8b9e51c4b065432d61d4c5b0e06dff095ab8 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Sep 2021 18:44:55 -0400 Subject: [PATCH 29/46] remove useless DB calls --- .../uhn/fhir/jpa/dao/BaseTransactionProcessor.java | 3 +-- .../dao/r4/FhirResourceDaoR4QueryCountTest.java | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java index d57891839e3..a5830be5107 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java @@ -1175,8 +1175,7 @@ public abstract class BaseTransactionProcessor { String matchUrl = entry.getKey(); IIdType value = entry.getValue(); DaoMethodOutcome daoMethodOutcome = theIdToPersistedOutcome.get(value); - //TODO GGG: daoMethodOutcome.getResource() actually executes a DB select query. Any way to avoid this?? - if (daoMethodOutcome != null && daoMethodOutcome.getResource() != null) { + if (daoMethodOutcome != null && !daoMethodOutcome.isNop() && daoMethodOutcome.getResource() != null) { InMemoryMatchResult match = mySearchParamMatcher.match(matchUrl, daoMethodOutcome.getResource(), theRequest); if (ourLog.isDebugEnabled()) { ourLog.debug("Checking conditional URL [{}] against resource with ID [{}]: Supported?:[{}], Matched?:[{}]", matchUrl, value, match.supported(), match.matched()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java index 06a8110de62..580cb632e94 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4QueryCountTest.java @@ -964,7 +964,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test outcome = mySystemDao.transaction(mySrd, input.get()); ourLog.info("Resp: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); myCaptureQueriesListener.logSelectQueries(); - assertEquals(12, myCaptureQueriesListener.countSelectQueries()); + assertEquals(11, myCaptureQueriesListener.countSelectQueries()); myCaptureQueriesListener.logInsertQueries(); assertEquals(1, myCaptureQueriesListener.countInsertQueries()); myCaptureQueriesListener.logUpdateQueries(); @@ -1043,7 +1043,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); myCaptureQueriesListener.logSelectQueries(); - assertEquals(3, myCaptureQueriesListener.countSelectQueries()); + assertEquals(1, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1056,7 +1056,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); - assertEquals(2, myCaptureQueriesListener.countSelectQueries()); + assertEquals(0, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1105,7 +1105,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); myCaptureQueriesListener.logSelectQueries(); - assertEquals(4, myCaptureQueriesListener.countSelectQueries()); + assertEquals(2, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1123,7 +1123,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test myCaptureQueriesListener.clear(); mySystemDao.transaction(mySrd, bundleCreator.get()); - assertEquals(3, myCaptureQueriesListener.countSelectQueries()); + assertEquals(1, myCaptureQueriesListener.countSelectQueries()); assertEquals(3, myCaptureQueriesListener.countInsertQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); @@ -1706,7 +1706,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test // Lookup the two existing IDs to make sure they are legit myCaptureQueriesListener.logSelectQueriesForCurrentThread(); - assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); + assertEquals(3, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); assertEquals(3, myCaptureQueriesListener.countInsertQueriesForCurrentThread()); assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread()); assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread()); @@ -1765,7 +1765,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test // Lookup the two existing IDs to make sure they are legit myCaptureQueriesListener.logSelectQueriesForCurrentThread(); - assertEquals(5, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); + assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); assertEquals(3, myCaptureQueriesListener.countInsertQueriesForCurrentThread()); assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread()); assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread()); From 9070aa357187d6479182dc2b6636dee21816a0ef Mon Sep 17 00:00:00 2001 From: Tadgh Date: Wed, 15 Sep 2021 01:20:46 -0400 Subject: [PATCH 30/46] wip --- .../uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java | 1 - .../rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java index d9557d86ca3..c2f29fa8c85 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java @@ -67,7 +67,6 @@ public interface IAuthRuleBuilder { * and could be shown to the client, but has no semantic meaning within * HAPI FHIR. */ - IAuthRuleBuilderRuleOpClassifierFinished allowAll(String theRuleName); /** * Build the rule list diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java index 94427a2d8fc..c21e9990842 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java @@ -53,7 +53,7 @@ public interface IAuthRuleBuilderRuleOp extends IAuthRuleBuilderAppliesToPatient/123 - Any Patient resource with the ID "123" will be matched *
  • 123 - Any resource of any type with the ID "123" will be matched
  • * - * + >* * @param theId The ID of the resource to apply (e.g. Patient/123) * @throws IllegalArgumentException If theId does not contain an ID with at least an ID part * @throws NullPointerException If theId is null From a0c8cc427937936f572c20785525014e90c2855a Mon Sep 17 00:00:00 2001 From: Tadgh Date: Wed, 15 Sep 2021 01:23:43 -0400 Subject: [PATCH 31/46] fix test --- .../jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java index 0c85f54f0a0..47da8dafd53 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java @@ -467,7 +467,7 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test { Patient patient = new Patient(); patient.setId(IdType.newRandomUuid()); - patient.setActive(true); + patient.setActive(false); builder .addTransactionUpdateEntry(patient) .conditional("Patient?active=false"); From 171f0f8724382a3d5e6e30802cbe27787f7b2ae9 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Wed, 15 Sep 2021 09:04:45 -0400 Subject: [PATCH 32/46] fix rulebuilder --- .../jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java | 3 ++- .../fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java index 47da8dafd53..423c0dadaa6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java @@ -467,6 +467,7 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test { Patient patient = new Patient(); patient.setId(IdType.newRandomUuid()); + patient.addName().setFamily("zoop"); patient.setActive(false); builder .addTransactionUpdateEntry(patient) @@ -488,7 +489,7 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test { assertEquals("1", observationId.getVersionIdPart()); // Make sure we're not introducing any extra DB operations - assertEquals(4, myCaptureQueriesListener.logSelectQueries().size()); + assertEquals(5, myCaptureQueriesListener.logSelectQueries().size()); // Read back and verify that reference is now versioned observation = myObservationDao.read(observationId); diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java index c2f29fa8c85..d9557d86ca3 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilder.java @@ -67,6 +67,7 @@ public interface IAuthRuleBuilder { * and could be shown to the client, but has no semantic meaning within * HAPI FHIR. */ + IAuthRuleBuilderRuleOpClassifierFinished allowAll(String theRuleName); /** * Build the rule list From 724e4b37dac3a34067f098eaee97098ae1099ca2 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Wed, 15 Sep 2021 11:24:01 -0400 Subject: [PATCH 33/46] Fix up test to actually match --- .../jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java index 423c0dadaa6..0975df2548e 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4VersionedReferenceTest.java @@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.util.BundleBuilder; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.BooleanType; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Condition; import org.hl7.fhir.r4.model.Encounter; @@ -467,7 +468,7 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test { Patient patient = new Patient(); patient.setId(IdType.newRandomUuid()); - patient.addName().setFamily("zoop"); + patient.setDeceased(new BooleanType(true)); patient.setActive(false); builder .addTransactionUpdateEntry(patient) @@ -489,7 +490,7 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test { assertEquals("1", observationId.getVersionIdPart()); // Make sure we're not introducing any extra DB operations - assertEquals(5, myCaptureQueriesListener.logSelectQueries().size()); + assertEquals(4, myCaptureQueriesListener.logSelectQueries().size()); // Read back and verify that reference is now versioned observation = myObservationDao.read(observationId); From 16e329e40c7374f4485c49cdf784e5de8c48a018 Mon Sep 17 00:00:00 2001 From: "juan.marchionatto" Date: Wed, 15 Sep 2021 10:29:30 -0400 Subject: [PATCH 34/46] Add version to ValueSet.compose.include when uploading terminology --- .../uhn/fhir/jpa/term/TermLoaderSvcImpl.java | 2 +- .../fhir/jpa/term/loinc/BaseLoincHandler.java | 4 + .../term/loinc/LoincAnswerListHandler.java | 1 + .../term/loinc/LoincRsnaPlaybookHandler.java | 1 + .../jpa/term/loinc/BaseLoincHandlerTest.java | 304 ++++++++++++++++++ 5 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandlerTest.java diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java index 60f2952754c..be31eb190c3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java @@ -723,7 +723,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc { retVal.setPublisher("Regenstrief Institute, Inc."); retVal.setDescription("A value set that includes all LOINC codes"); retVal.setCopyright("This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/"); - retVal.getCompose().addInclude().setSystem(ITermLoaderSvc.LOINC_URI); + retVal.getCompose().addInclude().setSystem(ITermLoaderSvc.LOINC_URI).setVersion(codeSystemVersionId); return retVal; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandler.java index cba3609fa8b..7cd49e97c45 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandler.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandler.java @@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.term.loinc; import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.term.IZipContentsHandlerCsv; +import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.ContactPoint; import org.hl7.fhir.r4.model.Enumerations; @@ -74,6 +75,9 @@ public abstract class BaseLoincHandler implements IZipContentsHandlerCsv { if (include == null) { include = theVs.getCompose().addInclude(); include.setSystem(theCodeSystemUrl); + if (StringUtils.isNotBlank(theVs.getVersion())) { + include.setVersion(theVs.getVersion()); + } } boolean found = false; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincAnswerListHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincAnswerListHandler.java index cdb97ca48d8..037a2fb0e6b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincAnswerListHandler.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincAnswerListHandler.java @@ -104,6 +104,7 @@ public class LoincAnswerListHandler extends BaseLoincHandler { .getCompose() .getIncludeFirstRep() .setSystem(ITermLoaderSvc.LOINC_URI) + .setVersion(codeSystemVersionId) .addConcept() .setCode(answerString) .setDisplay(displayText); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincRsnaPlaybookHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincRsnaPlaybookHandler.java index d0b03f0acc9..d81466f5380 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincRsnaPlaybookHandler.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincRsnaPlaybookHandler.java @@ -120,6 +120,7 @@ public class LoincRsnaPlaybookHandler extends BaseLoincHandler implements IZipCo .getCompose() .getIncludeFirstRep() .setSystem(ITermLoaderSvc.LOINC_URI) + .setVersion(codeSystemVersionId) .addConcept() .setCode(loincNumber) .setDisplay(longCommonName); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandlerTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandlerTest.java new file mode 100644 index 00000000000..9a304b33bbb --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/loinc/BaseLoincHandlerTest.java @@ -0,0 +1,304 @@ +package ca.uhn.fhir.jpa.term.loinc; + +import com.google.common.collect.Maps; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.r4.model.ValueSet; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.StringReader; +import java.util.Map; +import java.util.Properties; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class BaseLoincHandlerTest { + + public static final String LOINC_NUMBER = "test-loinc-number"; + public static final String DISPLAY_NAME = "test-display-name"; + public static final String TEST_VERSION = "2.69"; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private ValueSet myValueSet; + + @Mock + private ValueSet.ConceptSetComponent myInclude; + + @Mock + private ValueSet.ConceptReferenceComponent myConceptReferenceComponent; + + private Map headerMap; + private CSVRecord recordWithHeader; + + + /** + * Need to setup a real parser because we can't mock final classes (without PowerMockito) + */ + private void setupCSVParser(Map headerValues) throws Exception { + final String[] headers = headerValues.keySet().toArray(new String[0]); + final String[] values = headerValues.values().toArray(new String[0]); + final String rowData = StringUtils.join(values, ','); + + try (final CSVParser parser = CSVFormat.DEFAULT.parse(new StringReader(rowData))) { + parser.iterator().next(); + } + try (final CSVParser parser = CSVFormat.DEFAULT.withHeader(headers).parse(new StringReader(rowData))) { + recordWithHeader = parser.iterator().next(); + headerMap = parser.getHeaderMap(); + } + } + + + @Nested + public class WithVersion { + + @Test + void Top2000LabResultsHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LOINC #", "test-loinc-number"); + recordDataMap.put("Long Common Name", "test-Long-Common-Names"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new BaseLoincTop2000LabResultsHandler( + null, Lists.newArrayList(), null, null, null, Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getVersion()).thenReturn(TEST_VERSION); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude).setVersion(Mockito.notNull()); + } + + @Test + void LoincDocumentOntologyHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LoincNumber", "test-LoincNumber"); + recordDataMap.put("PartNumber", "test-PartNumber"); + recordDataMap.put("PartTypeName", "Document.Role"); + recordDataMap.put("PartSequenceOrder", "test-PartSequenceOrder"); + recordDataMap.put("PartName", "test-PartName"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincDocumentOntologyHandler( + Maps.newHashMap(), null, Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getVersion()).thenReturn(TEST_VERSION); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude).setVersion(Mockito.notNull()); + } + + + @Test + void LoincGroupTermsFileHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LoincNumber", "test-LoincNumber"); + recordDataMap.put("GroupId", "test-GroupId"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincGroupTermsFileHandler( + Maps.newHashMap(), Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getVersion()).thenReturn(TEST_VERSION); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude).setVersion(Mockito.notNull()); + } + + + @Test + void LoincImagingDocumentCodeHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LOINC_NUM", "test-loinc-number"); + recordDataMap.put("LONG_COMMON_NAME", "test-Long-Common-Names"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincImagingDocumentCodeHandler( + Maps.newHashMap(), Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getVersion()).thenReturn(TEST_VERSION); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude).setVersion(Mockito.notNull()); + } + + + @Test + void LoincUniversalOrderSetHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LOINC_NUM", "test-loinc-number"); + recordDataMap.put("LONG_COMMON_NAME", "test-Long-Common-Names"); + recordDataMap.put("ORDER_OBS", "test-ORDER_OBS"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincUniversalOrderSetHandler( + Maps.newHashMap(), Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getVersion()).thenReturn(TEST_VERSION); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude).setVersion(Mockito.notNull()); + } } + + @Nested + public class WithoutVersion { + + @Test + void Top2000LabResultsHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LOINC #", "test-loinc-number"); + recordDataMap.put("Long Common Name", "test-Long-Common-Names"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new BaseLoincTop2000LabResultsHandler( + Maps.newHashMap(), Lists.newArrayList(), null, null, null, Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude, never()).setVersion(any()); + } + + @Test + void LoincDocumentOntologyHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LoincNumber", "test-LoincNumber"); + recordDataMap.put("PartNumber", "test-PartNumber"); + recordDataMap.put("PartTypeName", "Document.Role"); + recordDataMap.put("PartSequenceOrder", "test-PartSequenceOrder"); + recordDataMap.put("PartName", "test-PartName"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincDocumentOntologyHandler( + Maps.newHashMap(), null, Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude, never()).setVersion(any()); + } + + @Test + void LoincGroupTermsFileHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LoincNumber", "test-LoincNumber"); + recordDataMap.put("GroupId", "test-GroupId"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincGroupTermsFileHandler( + Maps.newHashMap(), Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude, never()).setVersion(any()); + } + + + @Test + void LoincImagingDocumentCodeHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LOINC_NUM", "test-loinc-number"); + recordDataMap.put("LONG_COMMON_NAME", "test-Long-Common-Names"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincImagingDocumentCodeHandler( + Maps.newHashMap(), Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude, never()).setVersion(any()); + } + + + @Test + void LoincUniversalOrderSetHandlerTest() throws Exception { + Map recordDataMap = Maps.newHashMap(); + recordDataMap.put("LOINC_NUM", "test-loinc-number"); + recordDataMap.put("LONG_COMMON_NAME", "test-Long-Common-Names"); + recordDataMap.put("ORDER_OBS", "test-ORDER_OBS"); + setupCSVParser(recordDataMap); + + BaseLoincHandler loincHandler = new LoincUniversalOrderSetHandler( + Maps.newHashMap(), Lists.newArrayList(), Lists.newArrayList(), new Properties()); + BaseLoincHandler spiedLoincHandler = spy(loincHandler); + + when(spiedLoincHandler.getValueSet(any(), any(), any(), any())).thenReturn(myValueSet); + when(myValueSet.getCompose().addInclude()).thenReturn(myInclude); + when(myInclude.addConcept()).thenReturn(myConceptReferenceComponent); + when(myConceptReferenceComponent.setCode(any())).thenReturn(myConceptReferenceComponent); + + spiedLoincHandler.accept(recordWithHeader); + + Mockito.verify(myInclude, never()).setVersion(any()); + } + + } + + + + +} From 2435d770898c1cfe618e210701b2657e6058e107 Mon Sep 17 00:00:00 2001 From: "juan.marchionatto" Date: Wed, 15 Sep 2021 14:46:33 -0400 Subject: [PATCH 35/46] Add changelog --- ...nclude-version-is-not-set-when-uploading-terminology.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2995-valueset-compose-include-version-is-not-set-when-uploading-terminology.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2995-valueset-compose-include-version-is-not-set-when-uploading-terminology.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2995-valueset-compose-include-version-is-not-set-when-uploading-terminology.yaml new file mode 100644 index 00000000000..8377273cf8c --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2995-valueset-compose-include-version-is-not-set-when-uploading-terminology.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 2995 +title: "CodeSystem version is copied to ValueSet.compose.include.version on loinc terminology upload + to support versioned ValueSet expansion." From a56c85f780b4c1a28b4e348b2553fca9da451869 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Thu, 16 Sep 2021 12:37:34 -0400 Subject: [PATCH 36/46] Eliminate Search Coordinator ThreadPool (#2991) * Add test * Remove search coordinator thread pool * Add changelog * Add docs * Test fixes * Test fixes * Test fixes * Test fix --- ...iminate-search-coordinator-threadpool.yaml | 6 + .../ca/uhn/fhir/jpa/config/BaseConfig.java | 15 +- .../jpa/search/SearchCoordinatorSvcImpl.java | 16 +- ...rResourceDaoR4LegacySearchBuilderTest.java | 2 +- .../FhirResourceDaoR4SearchLastNAsyncIT.java | 12 +- .../r4/FhirResourceDaoR4SearchNoFtTest.java | 2 +- .../FhirResourceDaoR4SearchOptimizedTest.java | 6 +- .../provider/ResourceProviderDstu2Test.java | 3 - .../r4/BaseResourceProviderR4Test.java | 3 + .../r4/ResourceProviderConcurrencyR4Test.java | 202 ++++++++++++++++++ .../provider/r4/ResourceProviderR4Test.java | 2 + .../search/SearchCoordinatorSvcImplTest.java | 48 ++--- 12 files changed, 255 insertions(+), 62 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2991-eliminate-search-coordinator-threadpool.yaml create mode 100644 hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderConcurrencyR4Test.java diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2991-eliminate-search-coordinator-threadpool.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2991-eliminate-search-coordinator-threadpool.yaml new file mode 100644 index 00000000000..638ed8c891b --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/2991-eliminate-search-coordinator-threadpool.yaml @@ -0,0 +1,6 @@ +--- +type: change +issue: 2991 +title: "This PR eliminates the search coordinator threadpool, and executes searches synchronously on the HTTP client + thread. The idea of using a separate pool was supposed to help improve server scalability, but ultimately created + false bottlenecks and reduced the utility of monitoring infrastructure so it has been eliminated." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java index 717e5c3aa0e..72a2535faef 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java @@ -380,17 +380,6 @@ public abstract class BaseConfig { return new TermConceptMappingSvcImpl(); } - @Bean - public ThreadPoolTaskExecutor searchCoordinatorThreadFactory() { - final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); - threadPoolTaskExecutor.setThreadNamePrefix("search_coord_"); - threadPoolTaskExecutor.setCorePoolSize(searchCoordCorePoolSize); - threadPoolTaskExecutor.setMaxPoolSize(searchCoordMaxPoolSize); - threadPoolTaskExecutor.setQueueCapacity(searchCoordQueueCapacity); - threadPoolTaskExecutor.initialize(); - return threadPoolTaskExecutor; - } - @Bean public TaskScheduler taskScheduler() { ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler(); @@ -851,8 +840,8 @@ public abstract class BaseConfig { } @Bean - public ISearchCoordinatorSvc searchCoordinatorSvc(ThreadPoolTaskExecutor searchCoordinatorThreadFactory) { - return new SearchCoordinatorSvcImpl(searchCoordinatorThreadFactory); + public ISearchCoordinatorSvc searchCoordinatorSvc() { + return new SearchCoordinatorSvcImpl(); } @Bean diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index aa67d53c597..a64ba464246 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -82,7 +82,6 @@ import org.springframework.data.domain.Sort; import org.springframework.orm.jpa.JpaDialect; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.vendor.HibernateJpaDialect; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; @@ -111,7 +110,6 @@ import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; @@ -123,7 +121,6 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { public static final Integer INTEGER_0 = 0; private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchCoordinatorSvcImpl.class); private final ConcurrentHashMap myIdToSearchTask = new ConcurrentHashMap<>(); - private final ExecutorService myExecutor; @Autowired private FhirContext myContext; @Autowired @@ -162,8 +159,13 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { * Constructor */ @Autowired - public SearchCoordinatorSvcImpl(ThreadPoolTaskExecutor searchCoordinatorThreadFactory) { - myExecutor = searchCoordinatorThreadFactory.getThreadPoolExecutor(); + public SearchCoordinatorSvcImpl() { + super(); + } + + @VisibleForTesting + Set getActiveSearchIds() { + return myIdToSearchTask.keySet(); } @VisibleForTesting @@ -274,7 +276,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequestDetails, resourceType, params, null); SearchContinuationTask task = new SearchContinuationTask(search, resourceDao, params, resourceType, theRequestDetails, requestPartitionId); myIdToSearchTask.put(search.getUuid(), task); - myExecutor.submit(task); + task.call(); } } @@ -406,7 +408,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { SearchTask task = new SearchTask(theSearch, theCallingDao, theParams, theResourceType, theRequestDetails, theRequestPartitionId); myIdToSearchTask.put(theSearch.getUuid(), task); - myExecutor.submit(task); + task.call(); PersistedJpaSearchFirstPageBundleProvider retVal = myPersistedJpaBundleProviderFactory.newInstanceFirstPage(theRequestDetails, theSearch, task, theSb); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java index 5366efa789c..5c33c51e5ab 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4LegacySearchBuilderTest.java @@ -929,7 +929,7 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test { List actual = toUnqualifiedVersionlessIds(resp); myCaptureQueriesListener.logSelectQueriesForCurrentThread(); assertThat(actual, containsInAnyOrder(orgId, medId, patId, moId, patId2)); - assertEquals(1, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size()); + assertEquals(8, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size()); // Specific patient ID with linked stuff request = mock(HttpServletRequest.class); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNAsyncIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNAsyncIT.java index 5ff05cac158..37661610e44 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNAsyncIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNAsyncIT.java @@ -13,6 +13,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -30,6 +32,7 @@ import static org.mockito.Mockito.when; @ExtendWith(SpringExtension.class) public class FhirResourceDaoR4SearchLastNAsyncIT extends BaseR4SearchLastN { + private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4SearchLastNAsyncIT.class); @Autowired protected DaoConfig myDaoConfig; private List originalPreFetchThresholds; @@ -108,8 +111,11 @@ public class FhirResourceDaoR4SearchLastNAsyncIT extends BaseR4SearchLastN { .map(t -> t.getSql(true, false)) .collect(Collectors.toList()); + ourLog.info("Queries:\n * " + String.join("\n * ", queries)); + + // 3 queries to actually perform the search // 1 query to lookup up Search from cache, and 2 chunked queries to retrieve resources by PID. - assertEquals(3, queries.size()); + assertEquals(6, queries.size()); // The first chunked query should have a full complement of PIDs StringBuilder firstQueryPattern = new StringBuilder(".*RES_ID in \\('[0-9]+'"); @@ -117,7 +123,7 @@ public class FhirResourceDaoR4SearchLastNAsyncIT extends BaseR4SearchLastN { firstQueryPattern.append(" , '[0-9]+'"); } firstQueryPattern.append("\\).*"); - assertThat(queries.get(1), matchesPattern(firstQueryPattern.toString())); + assertThat(queries.get(4), matchesPattern(firstQueryPattern.toString())); // the second chunked query should be padded with "-1". StringBuilder secondQueryPattern = new StringBuilder(".*RES_ID in \\('[0-9]+'"); @@ -128,7 +134,7 @@ public class FhirResourceDaoR4SearchLastNAsyncIT extends BaseR4SearchLastN { secondQueryPattern.append(" , '-1'"); } secondQueryPattern.append("\\).*"); - assertThat(queries.get(2), matchesPattern(secondQueryPattern.toString())); + assertThat(queries.get(5), matchesPattern(secondQueryPattern.toString())); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java index 5ee19c00c8e..2757b30ee0d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java @@ -781,7 +781,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { List actual = toUnqualifiedVersionlessIds(resp); myCaptureQueriesListener.logSelectQueriesForCurrentThread(); assertThat(actual, containsInAnyOrder(orgId, medId, patId, moId, patId2)); - assertEquals(1, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size()); + assertEquals(7, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size()); // Specific patient ID with linked stuff request = mock(HttpServletRequest.class); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java index e726c5254da..a9a9352b66d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java @@ -1177,9 +1177,9 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test { assertEquals(1, myCaptureQueriesListener.countUpdateQueries()); assertEquals(0, myCaptureQueriesListener.countDeleteQueries()); - assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); - assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread()); - assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread()); + assertEquals(4, myCaptureQueriesListener.countSelectQueriesForCurrentThread()); + assertEquals(9, myCaptureQueriesListener.countInsertQueriesForCurrentThread()); + assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread()); assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread()); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java index 98e72802634..a961eafc12f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java @@ -1627,9 +1627,6 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test { .execute(); assertEquals(10, response.getEntry().size()); - if (ourConnectionPoolSize > 1) { - assertEquals(null, response.getTotalElement().getValueAsString(), "Total should be null but was " + response.getTotalElement().getValueAsString() + " in " + sw.toString()); - } assertThat(response.getLink("next").getUrl(), not(emptyString())); // Load page 2 diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java index 6081f5019a5..760542e197f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java @@ -179,9 +179,12 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test { myFhirCtx.getRestfulClientFactory().setSocketTimeout(400000); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + connectionManager.setMaxTotal(10); + connectionManager.setDefaultMaxPerRoute(10); HttpClientBuilder builder = HttpClientBuilder.create(); builder.setConnectionManager(connectionManager); builder.setMaxConnPerRoute(99); + ourHttpClient = builder.build(); ourServer = server; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderConcurrencyR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderConcurrencyR4Test.java new file mode 100644 index 00000000000..9b0ca550c62 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderConcurrencyR4Test.java @@ -0,0 +1,202 @@ +package ca.uhn.fhir.jpa.provider.r4; + +import ca.uhn.fhir.interceptor.api.Hook; +import ca.uhn.fhir.interceptor.api.Interceptor; +import ca.uhn.fhir.interceptor.api.Pointcut; +import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Patient; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.awaitility.Awaitility.await; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SuppressWarnings("Duplicates") +public class ResourceProviderConcurrencyR4Test extends BaseResourceProviderR4Test { + + private static final Logger ourLog = LoggerFactory.getLogger(ResourceProviderConcurrencyR4Test.class); + private ExecutorService myExecutor; + private List myReceivedNames = Collections.synchronizedList(new ArrayList<>()); + private List myExceptions = Collections.synchronizedList(new ArrayList<>()); + + @Override + @BeforeEach + public void before() throws Exception { + super.before(); + + myExecutor = Executors.newFixedThreadPool(10); + myReceivedNames.clear(); + myExceptions.clear(); + } + + @Override + @AfterEach + public void after() throws Exception { + super.after(); + + myInterceptorRegistry.unregisterInterceptorsIf(t -> t instanceof SearchBlockingInterceptor); + myExecutor.shutdown(); + + assertThat(myExceptions, empty()); + } + + /** + * This test is intended to verify that we are in fact executing searches in parallel + * when two different searches come in. + * + * We execute two identical searches (which should result in only one actual + * execution that will be reused by both) and one other search. We use an + * interceptor to artifically delay the execution of the first search in order + * to verify that the last search completes before the first one can finish. + */ + @Test + public void testSearchesExecuteConcurrently() { + createPatient(withFamily("FAMILY1")); + createPatient(withFamily("FAMILY2")); + createPatient(withFamily("FAMILY3")); + + SearchBlockingInterceptor searchBlockingInterceptorFamily1 = new SearchBlockingInterceptor("FAMILY1"); + myInterceptorRegistry.registerInterceptor(searchBlockingInterceptorFamily1); + + // Submit search 1 (should block because of interceptor semaphore) + { + String uri = ourServerBase + "/Patient?_format=json&family=FAMILY1"; + ourLog.info("Submitting GET " + uri); + HttpGet get = new HttpGet(uri); + myExecutor.submit(() -> { + try (CloseableHttpResponse outcome = ourHttpClient.execute(get)) { + assertEquals(200, outcome.getStatusLine().getStatusCode()); + String outcomeString = IOUtils.toString(outcome.getEntity().getContent(), StandardCharsets.UTF_8); + Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, outcomeString); + assertEquals(1, bundle.getEntry().size()); + Patient pt = (Patient) bundle.getEntry().get(0).getResource(); + String family = pt.getNameFirstRep().getFamily(); + ourLog.info("Received response with family name: {}", family); + myReceivedNames.add(family); + } catch (Exception e) { + ourLog.error("Client failure", e); + myExceptions.add(e); + } + }); + } + + await().until(() -> searchBlockingInterceptorFamily1.getHits(), equalTo(1)); + + // Submit search 2 (should also block because it will reuse the first search - same name being searched) + { + String uri = ourServerBase + "/Patient?_format=json&family=FAMILY1"; + HttpGet get = new HttpGet(uri); + myExecutor.submit(() -> { + ourLog.info("Submitting GET " + uri); + try (CloseableHttpResponse outcome = ourHttpClient.execute(get)) { + assertEquals(200, outcome.getStatusLine().getStatusCode()); + String outcomeString = IOUtils.toString(outcome.getEntity().getContent(), StandardCharsets.UTF_8); + Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, outcomeString); + assertEquals(1, bundle.getEntry().size()); + Patient pt = (Patient) bundle.getEntry().get(0).getResource(); + String family = pt.getNameFirstRep().getFamily(); + ourLog.info("Received response with family name: {}", family); + myReceivedNames.add(family); + } catch (Exception e) { + ourLog.error("Client failure", e); + myExceptions.add(e); + } + }); + } + + // Submit search 3 (should not block - different name being searched, so it should actually finish first) + { + String uri = ourServerBase + "/Patient?_format=json&family=FAMILY3"; + HttpGet get = new HttpGet(uri); + myExecutor.submit(() -> { + ourLog.info("Submitting GET " + uri); + try (CloseableHttpResponse outcome = ourHttpClient.execute(get)) { + assertEquals(200, outcome.getStatusLine().getStatusCode()); + String outcomeString = IOUtils.toString(outcome.getEntity().getContent(), StandardCharsets.UTF_8); + Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, outcomeString); + assertEquals(1, bundle.getEntry().size()); + Patient pt = (Patient) bundle.getEntry().get(0).getResource(); + String family = pt.getNameFirstRep().getFamily(); + ourLog.info("Received response with family name: {}", family); + myReceivedNames.add(family); + } catch (Exception e) { + ourLog.error("Client failure", e); + myExceptions.add(e); + } + }); + } + + ourLog.info("About to wait for FAMILY3 to complete"); + await().until(() -> myReceivedNames, contains("FAMILY3")); + ourLog.info("Got FAMILY3"); + + searchBlockingInterceptorFamily1.getLatch().countDown(); + + ourLog.info("About to wait for FAMILY1 to complete"); + await().until(() -> myReceivedNames, contains("FAMILY3", "FAMILY1", "FAMILY1")); + ourLog.info("Got FAMILY1"); + + assertEquals(1, searchBlockingInterceptorFamily1.getHits()); + } + + + @Interceptor + public static class SearchBlockingInterceptor { + + private final CountDownLatch myLatch = new CountDownLatch(1); + private final String myFamily; + private AtomicInteger myHits = new AtomicInteger(0); + + SearchBlockingInterceptor(String theFamily) { + myFamily = theFamily; + } + + @Hook(Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED) + public void firstResultLoaded(RequestDetails theRequestDetails) { + String family = theRequestDetails.getParameters().get("family")[0]; + ourLog.info("See a hit for: {}", family); + if (family.equals(myFamily)) { + try { + myHits.incrementAndGet(); + if (!myLatch.await(1, TimeUnit.MINUTES)) { + throw new InternalErrorException("Timed out waiting for " + Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED); + } + } catch (InterruptedException e) { + throw new InternalErrorException(e); + } + } + } + + public Integer getHits() { + return myHits.get(); + } + + public CountDownLatch getLatch() { + return myLatch; + } + } + + +} diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java index b939c4b1536..9e9978072e9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java @@ -4808,6 +4808,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { } @Test + @Disabled("Not useful with the search coordinator thread pool removed") public void testSearchWithCountNotSet() { mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(1); mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(200); @@ -4876,6 +4877,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { } @Test + @Disabled("Not useful with the search coordinator thread pool removed") public void testSearchWithCountSearchResultsUpTo5() { mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(1); mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(200); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java index 830f77ba0f5..c6af09b5281 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java @@ -6,7 +6,6 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; -import ca.uhn.fhir.jpa.config.dstu3.BaseDstu3Config; import ca.uhn.fhir.jpa.dao.IResultIterator; import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.LegacySearchBuilder; @@ -29,6 +28,7 @@ import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import com.google.common.collect.Lists; +import org.hamcrest.Matchers; import org.hl7.fhir.instance.model.api.IBaseResource; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -126,7 +126,7 @@ public class SearchCoordinatorSvcImplTest { myCurrentSearch = null; - mySvc = new SearchCoordinatorSvcImpl(new BaseDstu3Config().searchCoordinatorThreadFactory()); + mySvc = new SearchCoordinatorSvcImpl(); mySvc.setEntityManagerForUnitTest(myEntityManager); mySvc.setTransactionManagerForUnitTest(myTxManager); mySvc.setContextForUnitTest(ourCtx); @@ -174,12 +174,8 @@ public class SearchCoordinatorSvcImplTest { IResultIterator iter = new FailAfterNIterator(new SlowIterator(pids.iterator(), 2), 300); when(mySearchBuilder.createQuery(same(params), any(), any(), nullable(RequestPartitionId.class))).thenReturn(iter); - IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions()); - assertNotNull(result.getUuid()); - assertEquals(null, result.size()); - try { - result.getResources(0, 100000); + mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions()); } catch (InternalErrorException e) { assertThat(e.getMessage(), containsString("FAILED")); assertThat(e.getMessage(), containsString("at ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImplTest")); @@ -220,7 +216,7 @@ public class SearchCoordinatorSvcImplTest { IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions()); assertNotNull(result.getUuid()); - assertEquals(null, result.size()); + assertEquals(790, result.size()); List resources = result.getResources(0, 100000); assertEquals(790, resources.size()); @@ -297,7 +293,7 @@ public class SearchCoordinatorSvcImplTest { IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions()); assertNotNull(result.getUuid()); - assertEquals(null, result.size()); + assertEquals(790, result.size()); List resources; @@ -337,16 +333,19 @@ public class SearchCoordinatorSvcImplTest { SlowIterator iter = new SlowIterator(pids.iterator(), 500); when(mySearchBuilder.createQuery(same(params), any(), any(), nullable(RequestPartitionId.class))).thenReturn(iter); - IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions()); - assertNotNull(result.getUuid()); + ourLog.info("Registering the first search"); + new Thread(() -> mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions())).start(); + await().until(()->iter.getCountReturned(), Matchers.greaterThan(0)); + String searchId = mySvc.getActiveSearchIds().iterator().next(); CountDownLatch completionLatch = new CountDownLatch(1); Runnable taskStarter = () -> { try { + assertNotNull(searchId); ourLog.info("About to pull the first resource"); - List resources = result.getResources(0, 1); + List resources = mySvc.getResources(searchId, 0, 1, null); ourLog.info("Done pulling the first resource"); - assertEquals(1, resources.size()); + assertEquals(1, resources.size()); } finally { completionLatch.countDown(); } @@ -360,10 +359,9 @@ public class SearchCoordinatorSvcImplTest { ourLog.info("Done cancelling all searches"); try { - result.getResources(10, 20); - } catch (InternalErrorException e) { - assertThat(e.getMessage(), containsString("Abort has been requested")); - assertThat(e.getMessage(), containsString("at ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl")); + mySvc.getResources(searchId, 0, 1, null); + } catch (ResourceGoneException e) { + // good } completionLatch.await(10, TimeUnit.SECONDS); @@ -391,7 +389,7 @@ public class SearchCoordinatorSvcImplTest { IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null, RequestPartitionId.allPartitions()); assertNotNull(result.getUuid()); - assertEquals(null, result.size()); + assertEquals(790, result.size()); ArgumentCaptor searchCaptor = ArgumentCaptor.forClass(Search.class); verify(mySearchCacheSvc, atLeast(1)).save(searchCaptor.capture()); @@ -402,23 +400,11 @@ public class SearchCoordinatorSvcImplTest { PersistedJpaBundleProvider provider; resources = result.getResources(0, 10); - assertNull(result.size()); + assertEquals(790, result.size()); assertEquals(10, resources.size()); assertEquals("10", resources.get(0).getIdElement().getValueAsString()); assertEquals("19", resources.get(9).getIdElement().getValueAsString()); - when(mySearchCacheSvc.fetchByUuid(eq(result.getUuid()))).thenReturn(Optional.of(search)); - - /* - * Now call from a new bundle provider. This simulates a separate HTTP - * client request coming in. - */ - provider = newPersistedJpaBundleProvider(result.getUuid()); - resources = provider.getResources(10, 20); - assertEquals(10, resources.size()); - assertEquals("20", resources.get(0).getIdElement().getValueAsString()); - assertEquals("29", resources.get(9).getIdElement().getValueAsString()); - myExpectedNumberOfSearchBuildersCreated = 4; } From 756af63993c2539d19049b48b2cf44fc51d6c4aa Mon Sep 17 00:00:00 2001 From: Daron McIntosh Date: Thu, 16 Sep 2021 17:33:04 +0000 Subject: [PATCH 37/46] Add scope to unit test dependency --- hapi-fhir-structures-dstu2.1/pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index 203d9759eb9..3910f44e72a 100644 --- a/hapi-fhir-structures-dstu2.1/pom.xml +++ b/hapi-fhir-structures-dstu2.1/pom.xml @@ -176,8 +176,9 @@ commons-lang - commons-lang - 2.5 + commons-lang + 2.5 + test net.sf.json-lib From 528690fe6cd8db13f2813b9f18aaa27bf0120e83 Mon Sep 17 00:00:00 2001 From: Daron McIntosh Date: Thu, 16 Sep 2021 18:26:53 +0000 Subject: [PATCH 38/46] add commons-lang dep to hapi-fhir-validation pom --- hapi-fhir-validation/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index 81b1b0d0aa9..8158acb5ba3 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -261,6 +261,13 @@ test + + commons-lang + commons-lang + 2.5 + test + + com.helger From 56920149bc842e1c502965ef1cc95ccb92667e2b Mon Sep 17 00:00:00 2001 From: Jason Roberts Date: Fri, 17 Sep 2021 09:48:39 -0400 Subject: [PATCH 39/46] add support for OIDC authentication to Swagger API --- .../uhn/fhir/rest/openapi/OpenApiInterceptor.java | 15 ++++++++++++++- .../resources/ca/uhn/fhir/rest/openapi/index.css | 2 +- .../resources/ca/uhn/fhir/rest/openapi/index.html | 4 +++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java b/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java index 7caad2dbb78..13a3107cc02 100644 --- a/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java +++ b/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java @@ -262,6 +262,13 @@ public class OpenApiInterceptor { return true; } + if (resourcePath.endsWith(".html")) { + theResponse.setContentType(Constants.CT_HTML); + theResponse.setStatus(200); + IOUtils.copy(resource, theResponse.getOutputStream()); + theResponse.getOutputStream().close(); + return true; + } } return false; } @@ -336,12 +343,18 @@ public class OpenApiInterceptor { String page = extractPageName(theRequestDetails, PAGE_SYSTEM); context.setVariable("PAGE", page); + populateOIDCVariables(context); + String outcome = myTemplateEngine.process("index.html", context); theResponse.getWriter().write(outcome); theResponse.getWriter().close(); } + protected void populateOIDCVariables(WebContext context) { + context.setVariable("OAUTH2_REDIRECT_URL_PROPERTY", ""); + } + private String extractPageName(ServletRequestDetails theRequestDetails, String theDefault) { String[] pageValues = theRequestDetails.getParameters().get("page"); String page = null; @@ -354,7 +367,7 @@ public class OpenApiInterceptor { return page; } - private OpenAPI generateOpenApi(ServletRequestDetails theRequestDetails) { + protected OpenAPI generateOpenApi(ServletRequestDetails theRequestDetails) { String page = extractPageName(theRequestDetails, null); CapabilityStatement cs = getCapabilityStatement(theRequestDetails); diff --git a/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.css b/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.css index a94d230ed3c..b921df6148a 100644 --- a/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.css +++ b/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.css @@ -18,7 +18,7 @@ body background: #fafafa; } -.scheme-container, .information-container +.information-container { display: none } diff --git a/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.html b/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.html index a1e0d16659d..f3ff503295f 100644 --- a/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.html +++ b/hapi-fhir-server-openapi/src/main/resources/ca/uhn/fhir/rest/openapi/index.html @@ -1,3 +1,4 @@ + @@ -55,7 +56,8 @@ plugins: [ // SwaggerUIBundle.plugins.DownloadUrl ], - // layout: "StandaloneLayout" + // layout: "StandaloneLayout", + oauth2RedirectUrl: "[[${OAUTH2_REDIRECT_URL_PROPERTY}]]" }); // End Swagger UI call region From a866feb730945c96d289209a8723a58e206b7f6f Mon Sep 17 00:00:00 2001 From: Jason Roberts Date: Fri, 17 Sep 2021 11:41:51 -0400 Subject: [PATCH 40/46] changelog --- .../fhir/changelog/5_6_0/3005-oidc-support-in-swagger.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3005-oidc-support-in-swagger.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3005-oidc-support-in-swagger.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3005-oidc-support-in-swagger.yaml new file mode 100644 index 00000000000..7a924a3fd8f --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3005-oidc-support-in-swagger.yaml @@ -0,0 +1,5 @@ +--- +type: add +issue: 3005 +jira: SMILE-723 +title: "Open up the visibility of some methods in the generation of the Open API definition files to allow extenders to add support for OIDC authorization." From 4051fe084937e728f8ebd027cff76ae40af62f8e Mon Sep 17 00:00:00 2001 From: Jason Roberts Date: Fri, 17 Sep 2021 14:17:33 -0400 Subject: [PATCH 41/46] code review feedback --- .../ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java | 6 +++--- .../uhn/fhir/rest/openapi/OpenApiInterceptorTest.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java b/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java index 13a3107cc02..9a3117c0d2f 100644 --- a/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java +++ b/hapi-fhir-server-openapi/src/main/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptor.java @@ -343,7 +343,7 @@ public class OpenApiInterceptor { String page = extractPageName(theRequestDetails, PAGE_SYSTEM); context.setVariable("PAGE", page); - populateOIDCVariables(context); + populateOIDCVariables(theRequestDetails, context); String outcome = myTemplateEngine.process("index.html", context); @@ -351,8 +351,8 @@ public class OpenApiInterceptor { theResponse.getWriter().close(); } - protected void populateOIDCVariables(WebContext context) { - context.setVariable("OAUTH2_REDIRECT_URL_PROPERTY", ""); + protected void populateOIDCVariables(ServletRequestDetails theRequestDetails, WebContext theContext) { + theContext.setVariable("OAUTH2_REDIRECT_URL_PROPERTY", ""); } private String extractPageName(ServletRequestDetails theRequestDetails, String theDefault) { diff --git a/hapi-fhir-server-openapi/src/test/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptorTest.java b/hapi-fhir-server-openapi/src/test/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptorTest.java index c7afe2ad42a..66d649cbfb1 100644 --- a/hapi-fhir-server-openapi/src/test/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptorTest.java +++ b/hapi-fhir-server-openapi/src/test/java/ca/uhn/fhir/rest/openapi/OpenApiInterceptorTest.java @@ -213,6 +213,17 @@ public class OpenApiInterceptorTest { assertEquals(null, url); } + @Test + public void testStandardRedirectScriptIsAccessible() throws IOException { + myServer.getRestfulServer().registerInterceptor(new AddResourceCountsInterceptor()); + myServer.getRestfulServer().registerInterceptor(new OpenApiInterceptor()); + + HttpGet get = new HttpGet("http://localhost:" + myServer.getPort() + "/fhir/swagger-ui/oauth2-redirect.html"); + try (CloseableHttpResponse response = myClient.execute(get)) { + assertEquals(200, response.getStatusLine().getStatusCode()); + } + } + private String fetchSwaggerUi(String url) throws IOException { String resp; HttpGet get = new HttpGet(url); From f1f9c672ad1fed877b7c23c32812dfa5d8827ff0 Mon Sep 17 00:00:00 2001 From: Johnson Lu <71754637+lu-wenhua@users.noreply.github.com> Date: Mon, 20 Sep 2021 12:40:56 -0700 Subject: [PATCH 42/46] 3110 zh disallow unknown extensions (#3009) * Added allowKnownExtensionsOnly() method such which calls setAnyExtensionsAllowed() to set myAnyExtensionsAllowed to false and modified changelogs to add entry for this ticket. * Modified docs to remove description for .allowAnyExtensions() and included it within a description for .allowKnownExtensionsOnly() and also added test for .allowKnownExtensionsOnly() * refactored allowKnownExtensionsOnly() to rejectUnknownExtensions() --- ...positoryValidatingInterceptorExamples.java | 7 ++--- ...add-toggle-to-deny-unknown-extensions.yaml | 4 +++ .../RepositoryValidatingRuleBuilder.java | 9 +++++++ ...RepositoryValidatingInterceptorR4Test.java | 27 +++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3110-add-toggle-to-deny-unknown-extensions.yaml diff --git a/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/RepositoryValidatingInterceptorExamples.java b/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/RepositoryValidatingInterceptorExamples.java index 896f021375e..babae3507e8 100644 --- a/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/RepositoryValidatingInterceptorExamples.java +++ b/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/RepositoryValidatingInterceptorExamples.java @@ -28,7 +28,6 @@ import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder; import ca.uhn.fhir.validation.ResultSeverityEnum; import org.springframework.context.ApplicationContext; -import javax.annotation.Nonnull; import java.util.List; @SuppressWarnings("unused") @@ -121,8 +120,10 @@ public class RepositoryValidatingInterceptorExamples { .forResourcesOfType("Patient") .requireValidationToDeclaredProfiles() - // Configure the validator to never reject extensions - .allowAnyExtensions() + // Configure the validator to reject unknown extensions + // by default, all extensions are accepted and to undo this rejection + // call allowAnyExtensions() + .rejectUnknownExtensions() // Configure the validator to not perform terminology validation .disableTerminologyChecks() diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3110-add-toggle-to-deny-unknown-extensions.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3110-add-toggle-to-deny-unknown-extensions.yaml new file mode 100644 index 00000000000..4dab26e6393 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3110-add-toggle-to-deny-unknown-extensions.yaml @@ -0,0 +1,4 @@ +--- +type: add +issue: 3110 +title: "Added a functionality to deny unknown extensions." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingRuleBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingRuleBuilder.java index aff7afb1677..f1d2241eec3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingRuleBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingRuleBuilder.java @@ -305,6 +305,15 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot { return this; } + /** + * Configure the validator to reject unknown extensions + */ + @Nonnull + public FinalizedRequireValidationRule rejectUnknownExtensions() { + myRule.getValidator().setAnyExtensionsAllowed(false); + return this; + } + /** * Configure the validator to not perform terminology validation */ diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptorR4Test.java index d48e9cbe61f..ca49294dcda 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptorR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/interceptor/validation/RepositoryValidatingInterceptorR4Test.java @@ -291,6 +291,33 @@ public class RepositoryValidatingInterceptorR4Test extends BaseJpaR4Test { } } + @Test + public void testRequireValidation_AdditionalOptions_Reject_UnKnown_Extensions() { + List rules = newRuleBuilder() + .forResourcesOfType("Observation") + .requireValidationToDeclaredProfiles() + .withBestPracticeWarningLevel("IGNORE") + .rejectUnknownExtensions() + .disableTerminologyChecks() + .errorOnUnknownProfiles() + .suppressNoBindingMessage() + .suppressWarningForExtensibleValueSetValidation() + .build(); + + myValInterceptor.setRules(rules); + + Observation obs = new Observation(); + obs.getCode().addCoding().setSystem("http://foo").setCode("123").setDisplay("help im a bug"); + obs.setStatus(Observation.ObservationStatus.AMENDED); + try { + IIdType id = myObservationDao.create(obs).getId(); + assertEquals("1", id.getVersionIdPart()); + } catch (PreconditionFailedException e) { + // should not happen + fail(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome())); + } + } + @Test public void testRequireValidation_FailNoRejectAndTag() { List rules = newRuleBuilder() From b6c8658f8ceb355b6ab6c456167683fdfb07cc8e Mon Sep 17 00:00:00 2001 From: Jason Roberts Date: Tue, 21 Sep 2021 10:42:59 -0400 Subject: [PATCH 43/46] Fix MS SQLServer database migration --- .../changelog/5_6_0/3012-mssql-database-migration.yaml | 4 ++++ .../src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java | 8 ++++++++ .../src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java | 7 +++++++ .../java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java | 5 +++++ 4 files changed, 24 insertions(+) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml new file mode 100644 index 00000000000..899aacb26a5 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml @@ -0,0 +1,4 @@ +--- +type: fix +issue: 3012 +title: "Fixes some recent database schema migration failures on MS SQLServer." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java index 3b1ed6553fd..20bd94a1586 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java @@ -221,6 +221,14 @@ public class TestUtil { } + for (Class innerClass : theClazz.getDeclaredClasses()) { + Embeddable embeddable = innerClass.getAnnotation(Embeddable.class); + if (embeddable != null) { + scanClassOrSuperclass(theNames, innerClass, false, columnNameToLength); + } + + } + if (theClazz.getSuperclass().equals(Object.class)) { return; } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java index fb4af862dd6..ec0d881b699 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java +++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java @@ -254,6 +254,13 @@ public class JdbcUtils { return new ColumnType(ColumnTypeEnum.DATE_TIMESTAMP, length); case Types.BLOB: return new ColumnType(ColumnTypeEnum.BLOB, length); + case Types.VARBINARY: + if (theConnectionProperties.getDriverType().equals(DriverTypeEnum.MSSQL_2012)) { + // MS SQLServer seems to be mapping BLOB to VARBINARY under the covers, so we need to reverse that mapping + return new ColumnType(ColumnTypeEnum.BLOB, length); + } else { + throw new IllegalArgumentException("Don't know how to handle datatype " + dataType + " for column " + theColumnName + " on table " + theTableName); + } case Types.CLOB: return new ColumnType(ColumnTypeEnum.CLOB, length); case Types.DOUBLE: diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java index 34c8805de97..259a1e6f8c5 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java +++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java @@ -148,6 +148,11 @@ public class Builder { super.addTask(theTask); } } + + public BuilderAddTableByColumns failureAllowed() { + myTask.setFailureAllowed(true); + return this; + } } public static class BuilderWithTableName implements BaseMigrationTasks.IAcceptsTasks { From 060791aeb4f098c81a4beb1cd914dd24de9a8238 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Tue, 21 Sep 2021 11:36:08 -0400 Subject: [PATCH 44/46] hapi-fhir-storage-api (#3006) * rename hapi-fhir-jpaserver-migrate to hapi-fhir-sql-migrate and move hapi-tasks into jpaserver-persistence * rename hapi-fhir-jpaserver-api to hapi-fhir-storage-api * move bulk import apis * create hapi-fhir-jpa * create hapi-fhir-jpa * move CircularQueueCaptureQueriesListener to japi-fhir-jpa * move mdm logs to storage-api * move gziputil to storage-api * move quartz scheduling to hapi-fhir-jpa * move default subscription channel factory to storage-api * consolidated batch constants * correct accidental Logs change * remove dependency of cdr-api on cdr-persistence * fix javadoc * pom descriptions * review feedback --- hapi-deployable-pom/pom.xml | 2 +- hapi-fhir-android/pom.xml | 2 +- hapi-fhir-base/pom.xml | 5 +- .../main/java/ca/uhn/fhir/util/TestUtil.java | 22 +++ .../pom.xml | 15 +- .../jpa/batch/api/IBatchJobSubmitter.java | 2 +- .../fhir/jpa/batch/config/BatchConstants.java | 81 ++++++++ .../config/NonPersistedBatchConfigurer.java | 1 - .../jpa/batch/svc/BatchJobSubmitterImpl.java | 2 +- .../uhn/fhir/jpa/batch/BaseBatchR4Test.java | 0 .../fhir/jpa/batch/config/BatchJobConfig.java | 1 - .../jpa/batch/config/SampleItemReader.java | 0 .../fhir/jpa/batch/config/SampleTasklet.java | 0 .../jpa/batch/config/TestBatchConfig.java | 1 + .../uhn/fhir/jpa/batch/svc/BatchSvcTest.java | 0 .../src/test/resources/logback-test.xml | 32 ++-- hapi-fhir-bom/pom.xml | 6 +- hapi-fhir-cli/hapi-fhir-cli-api/pom.xml | 4 +- hapi-fhir-cli/hapi-fhir-cli-app/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml | 2 +- hapi-fhir-cli/pom.xml | 2 +- hapi-fhir-client-okhttp/pom.xml | 2 +- hapi-fhir-client/pom.xml | 2 +- hapi-fhir-converter/pom.xml | 2 +- hapi-fhir-dist/pom.xml | 2 +- hapi-fhir-docs/pom.xml | 2 +- ...-resolved-placeholder-identifier-true.yaml | 2 +- .../uhn/hapi/fhir/docs/appendix/javadocs.md | 2 +- .../fhir/docs/server_jpa/configuration.md | 12 +- .../ca/uhn/hapi/fhir/docs/server_jpa/lastn.md | 8 +- .../uhn/hapi/fhir/docs/server_jpa/schema.md | 13 +- .../fhir/docs/server_jpa_mdm/mdm_expansion.md | 5 +- .../docs/server_jpa_mdm/mdm_operations.md | 2 +- .../server_jpa_partitioning/partitioning.md | 7 +- hapi-fhir-jacoco/pom.xml | 4 +- hapi-fhir-jaxrsserver-base/pom.xml | 2 +- hapi-fhir-jpa/pom.xml | 119 ++++++++++++ ...ocalContainerEntityManagerFactoryBean.java | 3 +- .../ca/uhn/fhir/jpa/model/sched/HapiJob.java | 2 +- .../fhir/jpa/model/sched/IHapiScheduler.java | 2 +- .../jpa/model/sched/ISchedulerService.java | 2 +- .../jpa/model/sched/ISmartLifecyclePhase.java | 2 +- .../model/sched/ScheduledJobDefinition.java | 2 +- .../sched/AutowiringSpringBeanJobFactory.java | 5 +- .../uhn/fhir/jpa/sched/BaseHapiScheduler.java | 16 +- .../jpa/sched/BaseSchedulerServiceImpl.java | 2 +- .../jpa/sched/ClusteredHapiScheduler.java | 2 +- .../uhn/fhir/jpa/sched/HapiNullScheduler.java | 2 +- .../jpa/sched/HapiSchedulerServiceImpl.java | 2 +- .../fhir/jpa/sched/LocalHapiScheduler.java | 2 +- .../jpa/util/BaseCaptureQueriesListener.java | 2 +- .../CircularQueueCaptureQueriesListener.java | 4 +- .../CurrentThreadCaptureQueriesListener.java | 2 +- .../util/DerbyTenSevenHapiFhirDialect.java | 2 +- .../java/ca/uhn/fhir/jpa/util/SqlQuery.java | 2 +- .../ca/uhn/fhir/jpa/util/SqlQueryList.java | 2 +- .../java/ca/uhn/fhir/jpa/util/TestUtil.java | 9 +- hapi-fhir-jpaserver-base/pom.xml | 85 +-------- .../uhn/fhir/jpa/batch/BatchJobsConfig.java | 60 ------ .../job/MultiUrlJobParameterValidator.java | 7 +- .../batch/mdm/MdmClearJobSubmitterImpl.java | 4 +- .../jpa/batch/mdm/job/MdmClearJobConfig.java | 2 +- ...BaseReverseCronologicalBatchPidReader.java | 36 ++-- .../bulk/export/job/BaseBulkItemReader.java | 3 +- ...portGenerateResourceFilesStepListener.java | 5 +- .../bulk/export/job/BulkExportJobConfig.java | 13 +- .../job/BulkExportJobParameterValidator.java | 5 +- .../job/CreateBulkExportEntityTasklet.java | 31 +-- .../export/job/ResourceTypePartitioner.java | 3 +- .../export/svc/BulkDataExportSvcImpl.java | 12 +- .../ActivateBulkImportEntityStepListener.java | 5 +- .../bulk/imprt/job/BulkImportFileReader.java | 4 +- .../bulk/imprt/job/BulkImportFileWriter.java | 4 +- .../bulk/imprt/job/BulkImportJobCloser.java | 4 +- .../bulk/imprt/job/BulkImportJobConfig.java | 7 +- .../job/BulkImportJobParameterValidator.java | 4 +- .../bulk/imprt/job/BulkImportPartitioner.java | 6 +- .../imprt/job/BulkImportStepListener.java | 6 +- .../job/CreateBulkImportEntityTasklet.java | 6 +- .../bulk/imprt/svc/BulkDataImportSvcImpl.java | 6 +- .../ca/uhn/fhir/jpa/config/BaseConfig.java | 2 +- .../jpa/dao/tx/HapiTransactionService.java | 21 +-- .../delete/DeleteExpungeJobSubmitterImpl.java | 4 +- .../delete/job/DeleteExpungeJobConfig.java | 4 +- .../MdmSearchExpandingInterceptor.java | 4 - .../tasks/HapiFhirJpaMigrationTasks.java | 2 +- .../jpa/provider/BaseJpaSystemProvider.java | 4 +- .../jpa/reindex/ReindexJobSubmitterImpl.java | 6 +- .../job/ReindexEverythingJobConfig.java | 2 +- .../jpa/reindex/job/ReindexJobConfig.java | 6 +- .../jpa/bulk/BulkDataExportSvcImplR4Test.java | 18 +- .../bulk/imprt/svc/BulkDataImportR4Test.java | 6 +- .../FhirResourceDaoR4SearchNoHashesTest.java | 4 +- ...FhirResourceDaoR4SearchPageExpiryTest.java | 8 +- .../uhn/fhir/jpa/dao/r4/JpaHistoryR4Test.java | 2 +- .../jpa/dao/r4/PartitioningSqlR4Test.java | 2 +- .../jpa/delete/job/DeleteExpungeJobTest.java | 4 +- .../fhir/jpa/delete/job/ReindexJobTest.java | 6 +- .../migrate/taskdef/ArbitrarySqlTaskTest.java | 0 .../fhir/jpa/migrate/taskdef/BaseTest.java | 161 ++++++++++++++++ .../migrate/taskdef/CalculateHashesTest.java | 0 .../fhir/jpa/migrate/taskdef/HashTest.java | 0 .../tasks/HapiFhirJpaMigrationTasksTest.java | 0 .../r4/MultitenantBatchOperationR4Test.java | 4 +- .../provider/r4/ResourceProviderR4Test.java | 178 +++++++++--------- .../r4/StaleSearchDeletingSvcR4Test.java | 2 +- .../jpa/provider/r4/SystemProviderR4Test.java | 4 +- .../jpa/sched/SchedulerServiceImplTest.java | 2 +- .../search/SearchCoordinatorSvcImplTest.java | 2 +- .../ca/uhn/fhir/jpa/batch/BatchConstants.java | 32 ---- .../InMemoryJobRepositoryBatchConfig.java | 85 --------- hapi-fhir-jpaserver-cql/pom.xml | 2 +- hapi-fhir-jpaserver-mdm/pom.xml | 2 +- .../jpa/mdm/broker/MdmMessageHandler.java | 2 - .../mdm/broker/MdmQueueConsumerLoader.java | 4 +- .../MdmSubmitterInterceptorLoader.java | 6 +- .../candidate/FindCandidateByExampleSvc.java | 8 +- .../svc/candidate/FindCandidateByLinkSvc.java | 2 +- .../MdmGoldenResourceFindingSvc.java | 2 +- .../ColumnTypeToDriverTypeToSqlType.java | 124 ------------ hapi-fhir-jpaserver-model/pom.xml | 30 +-- hapi-fhir-jpaserver-searchparam/pom.xml | 2 +- hapi-fhir-jpaserver-subscription/pom.xml | 4 +- hapi-fhir-jpaserver-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 2 +- hapi-fhir-server-mdm/pom.xml | 7 +- hapi-fhir-server-openapi/pom.xml | 2 +- hapi-fhir-server/pom.xml | 10 +- .../server/provider/ProviderConstants.java | 9 + .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../hapi-fhir-spring-boot-samples/pom.xml | 2 +- .../hapi-fhir-spring-boot-starter/pom.xml | 2 +- hapi-fhir-spring-boot/pom.xml | 2 +- .../pom.xml | 26 ++- .../ca/uhn/fhir/jpa/migrate/BaseMigrator.java | 2 +- .../uhn/fhir/jpa/migrate/DriverTypeEnum.java | 20 +- .../fhir/jpa/migrate/FlywayMigrationTask.java | 1 - .../uhn/fhir/jpa/migrate/FlywayMigrator.java | 0 .../ca/uhn/fhir/jpa/migrate/IMigrator.java | 0 .../ca/uhn/fhir/jpa/migrate/JdbcUtils.java | 156 ++++++++------- .../jpa/migrate/MigrationTaskSkipper.java | 0 .../ca/uhn/fhir/jpa/migrate/Migrator.java | 0 .../uhn/fhir/jpa/migrate/SchemaMigrator.java | 0 .../fhir/jpa/migrate/TaskOnlyMigrator.java | 0 .../jpa/migrate/taskdef/AddColumnTask.java | 0 .../migrate/taskdef/AddForeignKeyTask.java | 0 .../migrate/taskdef/AddIdGeneratorTask.java | 0 .../jpa/migrate/taskdef/AddIndexTask.java | 7 +- .../migrate/taskdef/AddTableByColumnTask.java | 0 .../migrate/taskdef/AddTableRawSqlTask.java | 0 .../jpa/migrate/taskdef/ArbitrarySqlTask.java | 36 ++-- .../taskdef/BaseColumnCalculatorTask.java | 67 ++++--- .../migrate/taskdef/BaseTableColumnTask.java | 17 +- .../taskdef/BaseTableColumnTypeTask.java | 0 .../jpa/migrate/taskdef/BaseTableTask.java | 1 - .../fhir/jpa/migrate/taskdef/BaseTask.java | 0 .../migrate/taskdef/CalculateHashesTask.java | 18 +- .../taskdef/CalculateOrdinalDatesTask.java | 0 .../jpa/migrate/taskdef/ColumnTypeEnum.java | 0 .../ColumnTypeToDriverTypeToSqlType.java | 124 ++++++++++++ .../jpa/migrate/taskdef/DropColumnTask.java | 21 +-- .../migrate/taskdef/DropForeignKeyTask.java | 44 ++--- .../migrate/taskdef/DropIdGeneratorTask.java | 0 .../jpa/migrate/taskdef/DropIndexTask.java | 116 ++++++------ .../jpa/migrate/taskdef/DropTableTask.java | 0 .../migrate/taskdef/ExecuteRawSqlTask.java | 0 .../migrate/taskdef/InitializeSchemaTask.java | 0 .../jpa/migrate/taskdef/ModifyColumnTask.java | 16 +- .../uhn/fhir/jpa/migrate/taskdef/NopTask.java | 0 .../jpa/migrate/taskdef/RenameColumnTask.java | 6 +- .../jpa/migrate/taskdef/RenameIndexTask.java | 66 +++---- .../tasks/SchemaInitializationProvider.java | 7 +- .../migrate/tasks/api/BaseMigrationTasks.java | 4 +- .../fhir/jpa/migrate/tasks/api/Builder.java | 122 +++++++----- .../api/ISchemaInitializationProvider.java | 0 .../jpa/migrate/FlywayMigrationTaskTest.java | 3 +- .../uhn/fhir/jpa/migrate/JdbcUtilsTest.java | 2 +- .../jpa/migrate/MigrationTaskSkipperTest.java | 6 +- .../fhir/jpa/migrate/SchemaMigratorTest.java | 0 .../jpa/migrate/taskdef/AddColumnTest.java | 0 .../taskdef/AddForeignKeyTaskTest.java | 3 +- .../taskdef/AddIdGeneratorTaskTest.java | 3 +- .../jpa/migrate/taskdef/AddIndexTest.java | 0 .../taskdef/AddTableByColumnTaskTest.java | 5 +- .../jpa/migrate/taskdef/AddTableTest.java | 2 +- .../jpa/migrate/taskdef/BaseTaskTest.java | 0 .../fhir/jpa/migrate/taskdef/BaseTest.java | 100 +++++----- .../jpa/migrate/taskdef/DropColumnTest.java | 6 +- .../taskdef/DropForeignKeyTaskTest.java | 0 .../taskdef/DropIdGeneratorTaskTest.java | 3 +- .../jpa/migrate/taskdef/DropIndexTest.java | 2 - .../jpa/migrate/taskdef/DropTableTest.java | 1 - .../taskdef/ExecuteRawSqlTaskTest.java | 0 .../taskdef/InitializeSchemaTaskTest.java | 3 +- .../jpa/migrate/taskdef/ModifyColumnTest.java | 1 - .../RenameColumnTaskDbSpecificTest.java | 0 .../migrate/taskdef/RenameColumnTaskTest.java | 7 +- .../tasks/api/BaseMigrationTasksTest.java | 6 +- .../src/test/resources/logback-test.xml | 2 +- .../pom.xml | 15 +- .../ca/uhn/fhir/jpa/api/config/DaoConfig.java | 52 +++-- .../ca/uhn/fhir/jpa/api/dao/DaoRegistry.java | 1 + .../java/ca/uhn/fhir/jpa/api/dao/IDao.java | 0 .../fhir/jpa/api/dao/IFhirResourceDao.java | 0 .../api/dao/IFhirResourceDaoCodeSystem.java | 0 .../api/dao/IFhirResourceDaoComposition.java | 0 .../api/dao/IFhirResourceDaoConceptMap.java | 2 +- .../api/dao/IFhirResourceDaoEncounter.java | 0 .../dao/IFhirResourceDaoMessageHeader.java | 0 .../api/dao/IFhirResourceDaoObservation.java | 7 +- .../jpa/api/dao/IFhirResourceDaoPatient.java | 0 .../dao/IFhirResourceDaoSearchParameter.java | 0 .../IFhirResourceDaoStructureDefinition.java | 0 .../api/dao/IFhirResourceDaoSubscription.java | 0 .../jpa/api/dao/IFhirResourceDaoValueSet.java | 0 .../uhn/fhir/jpa/api/dao/IFhirSystemDao.java | 0 .../java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java | 2 +- .../dao/MetadataKeyCurrentlyReindexing.java | 0 .../jpa/api/dao/MetadataKeyResourcePid.java | 0 .../fhir/jpa/api/model/DaoMethodOutcome.java | 8 +- .../fhir/jpa/api/model/DeleteConflict.java | 0 .../jpa/api/model/DeleteConflictList.java | 0 .../jpa/api/model/DeleteMethodOutcome.java | 0 .../fhir/jpa/api/model/ExpungeOptions.java | 0 .../fhir/jpa/api/model/ExpungeOutcome.java | 0 .../jpa/api/model/HistoryCountModeEnum.java | 0 .../jpa/api/model/LazyDaoMethodOutcome.java | 0 ...urceVersionConflictResolutionStrategy.java | 0 .../fhir/jpa/api/model/TranslationQuery.java | 2 +- .../jpa/api/model/TranslationRequest.java | 24 +-- .../fhir/jpa/api/model/WarmCacheEntry.java | 0 .../jpa/api/svc/ISearchCoordinatorSvc.java | 2 +- .../bulk/imprt/api/IBulkDataImportSvc.java | 2 +- .../imprt/model/BulkImportJobFileJson.java | 2 +- .../bulk/imprt/model/BulkImportJobJson.java | 2 +- .../imprt/model/BulkImportJobStatusEnum.java | 2 +- .../model/JobFileRowProcessingModeEnum.java | 2 +- .../imprt/model/ParsedBulkImportRecord.java | 2 +- .../java/ca/uhn/fhir/jpa/dao/GZipUtil.java | 9 +- .../channel/api/BaseChannelSettings.java | 2 +- .../channel/api/ChannelConsumerSettings.java | 2 +- .../channel/api/ChannelProducerSettings.java | 2 +- .../channel/api/IChannelFactory.java | 2 +- .../channel/api/IChannelProducer.java | 2 +- .../channel/api/IChannelReceiver.java | 2 +- .../channel/api/IChannelSettings.java | 2 +- .../config/SubscriptionChannelConfig.java | 2 +- .../channel/impl/LinkedBlockingChannel.java | 2 +- .../impl/LinkedBlockingChannelFactory.java | 2 +- ...roadcastingSubscribableChannelWrapper.java | 2 +- .../channel/subscription/IChannelNamer.java | 2 +- .../SubscriptionChannelFactory.java | 2 +- .../matching/IResourceModifiedConsumer.java | 2 +- .../SubscriptionMatchingStrategy.java | 2 +- .../registry/SubscriptionCanonicalizer.java | 3 +- .../match/registry/SubscriptionConstants.java | 2 +- .../model/CanonicalSubscription.java | 2 +- .../CanonicalSubscriptionChannelType.java | 2 +- .../model/ResourceDeliveryJsonMessage.java | 2 +- .../model/ResourceDeliveryMessage.java | 2 +- .../model/ResourceModifiedJsonMessage.java | 2 +- .../model/ResourceModifiedMessage.java | 2 +- .../main/java/ca/uhn/fhir/mdm/log/Logs.java | 2 +- .../src/main/resources/.keep-jpaserver-api | 0 .../src/test/java/.keep | 0 .../src/test/resources/.keep | 0 hapi-fhir-structures-dstu2.1/pom.xml | 2 +- hapi-fhir-structures-dstu2/pom.xml | 2 +- hapi-fhir-structures-dstu3/pom.xml | 2 +- hapi-fhir-structures-hl7org-dstu2/pom.xml | 2 +- hapi-fhir-structures-r4/pom.xml | 2 +- hapi-fhir-structures-r5/pom.xml | 2 +- hapi-fhir-test-utilities/pom.xml | 2 +- hapi-fhir-testpage-overlay/pom.xml | 2 +- .../pom.xml | 2 +- hapi-fhir-validation-resources-dstu2/pom.xml | 2 +- hapi-fhir-validation-resources-dstu3/pom.xml | 2 +- hapi-fhir-validation-resources-r4/pom.xml | 2 +- hapi-fhir-validation-resources-r5/pom.xml | 2 +- hapi-fhir-validation/pom.xml | 2 +- hapi-tinder-plugin/pom.xml | 16 +- hapi-tinder-test/pom.xml | 2 +- pom.xml | 33 +++- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- 289 files changed, 1489 insertions(+), 1375 deletions(-) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/pom.xml (86%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java (97%) create mode 100644 hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/BatchConstants.java rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java (98%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java (98%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/java/ca/uhn/fhir/jpa/batch/BaseBatchR4Test.java (100%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java (99%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleItemReader.java (100%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleTasklet.java (100%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java (99%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/java/ca/uhn/fhir/jpa/batch/svc/BatchSvcTest.java (100%) rename {hapi-fhir-jpaserver-batch => hapi-fhir-batch}/src/test/resources/logback-test.xml (82%) create mode 100644 hapi-fhir-jpa/pom.xml rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java (97%) rename {hapi-fhir-jpaserver-model => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java (97%) rename {hapi-fhir-jpaserver-model => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java (97%) rename {hapi-fhir-jpaserver-model => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java (98%) rename {hapi-fhir-jpaserver-model => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java (97%) rename {hapi-fhir-jpaserver-model => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java (98%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java (95%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java (93%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java (99%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java (97%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java (98%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java (97%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java (97%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java (99%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java (99%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java (99%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java (98%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java (99%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java (97%) rename {hapi-fhir-jpaserver-base => hapi-fhir-jpa}/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-jpaserver-base}/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-jpaserver-base}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ArbitrarySqlTaskTest.java (100%) create mode 100644 hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java rename {hapi-fhir-jpaserver-migrate => hapi-fhir-jpaserver-base}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-jpaserver-base}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/HashTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-jpaserver-base}/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasksTest.java (100%) delete mode 100644 hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/BatchConstants.java delete mode 100644 hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/InMemoryJobRepositoryBatchConfig.java delete mode 100644 hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/pom.xml (86%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/IMigrator.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java (96%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipper.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/Migrator.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/SchemaMigrator.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java (95%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableRawSqlTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ArbitrarySqlTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java (95%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java (74%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeEnum.java (100%) create mode 100644 hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java (89%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java (94%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/NopTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java (97%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java (93%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/ISchemaInitializationProvider.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java (97%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java (97%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java (97%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTaskTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java (96%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTaskTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTaskTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java (99%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskDbSpecificTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java (98%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java (100%) rename {hapi-fhir-jpaserver-migrate => hapi-fhir-sql-migrate}/src/test/resources/logback-test.xml (89%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/pom.xml (92%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java (99%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java (99%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IDao.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDao.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoComposition.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoEncounter.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoMessageHeader.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java (81%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoPatient.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSearchParameter.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoStructureDefinition.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSubscription.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyCurrentlyReindexing.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyResourcePid.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflict.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflictList.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteMethodOutcome.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOptions.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOutcome.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/HistoryCountModeEnum.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/ResourceVersionConflictResolutionStrategy.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java (99%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java (99%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/model/WarmCacheEntry.java (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java (100%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java (99%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java (98%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java (98%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java (97%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java (97%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java (98%) rename {hapi-fhir-jpaserver-base => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java (98%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java (98%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java (96%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java (96%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java (95%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java (98%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java (98%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java (99%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java (98%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java (99%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java (96%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java (99%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java (98%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java (99%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java (99%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java (99%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java (97%) rename {hapi-fhir-jpaserver-subscription => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java (98%) rename {hapi-fhir-server-mdm => hapi-fhir-storage-api}/src/main/java/ca/uhn/fhir/mdm/log/Logs.java (96%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/main/resources/.keep-jpaserver-api (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/test/java/.keep (100%) rename {hapi-fhir-jpaserver-api => hapi-fhir-storage-api}/src/test/resources/.keep (100%) diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index e70a9982ec0..575868e3c45 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index fcc0073c6c9..2526578113b 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 4250734be2e..b4dba9128fd 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -18,6 +18,9 @@ + + com.fasterxml.jackson.datatype diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java index 8edd16ce7fd..936ed1fc12b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java @@ -192,4 +192,26 @@ public class TestUtil { return stripReturns(theString).replace(" ", ""); } + public static void sleepAtLeast(long theMillis) { + sleepAtLeast(theMillis, true); + } + + + @SuppressWarnings("BusyWait") + public static void sleepAtLeast(long theMillis, boolean theLogProgress) { + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() <= start + theMillis) { + try { + long timeSinceStarted = System.currentTimeMillis() - start; + long timeToSleep = Math.max(0, theMillis - timeSinceStarted); + if (theLogProgress) { + ourLog.info("Sleeping for {}ms", timeToSleep); + } + Thread.sleep(timeToSleep); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + ourLog.error("Interrupted", e); + } + } + } } diff --git a/hapi-fhir-jpaserver-batch/pom.xml b/hapi-fhir-batch/pom.xml similarity index 86% rename from hapi-fhir-jpaserver-batch/pom.xml rename to hapi-fhir-batch/pom.xml index cf0abe606d6..97d413f1a3c 100644 --- a/hapi-fhir-jpaserver-batch/pom.xml +++ b/hapi-fhir-batch/pom.xml @@ -1,19 +1,22 @@ - 4.0.0 ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml - hapi-fhir-jpaserver-batch + hapi-fhir-batch jar HAPI FHIR JPA Server - Batch Task Processor + Default implementation of batch job submitter along with constants used by the different hapi-fhir batch + jobs. + @@ -24,10 +27,6 @@ org.springframework.batch spring-batch-infrastructure - - org.springframework.data - spring-data-jpa - javax.annotation javax.annotation-api diff --git a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java similarity index 97% rename from hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java rename to hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java index 299ded644fd..172a8d57555 100644 --- a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java +++ b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/api/IBatchJobSubmitter.java @@ -30,7 +30,7 @@ public interface IBatchJobSubmitter { /** * Given a {@link Job} and a {@link JobParameters}, execute the job with the given parameters. * - * @param theJob the job to run. + * @param theJob the job to run. * @param theJobParameters A collection of key-value pairs that are used to parameterize the job. * @return A {@link JobExecution} representing the job. * @throws JobParametersInvalidException If validation on the parameters fails. diff --git a/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/BatchConstants.java b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/BatchConstants.java new file mode 100644 index 00000000000..6071b7679b5 --- /dev/null +++ b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/BatchConstants.java @@ -0,0 +1,81 @@ +package ca.uhn.fhir.jpa.batch.config; + +/*- + * #%L + * HAPI FHIR JPA Server - Batch Task Processor + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public final class BatchConstants { + public static final String JOB_PARAM_REQUEST_LIST = "url-list"; + public static final String JOB_PARAM_BATCH_SIZE = "batch-size"; + public static final String JOB_PARAM_START_TIME = "start-time"; + public static final String CURRENT_URL_INDEX = "current.url-index"; + public static final String CURRENT_THRESHOLD_HIGH = "current.threshold-high"; + public static final String JOB_UUID_PARAMETER = "jobUUID"; + public static final String JOB_LAUNCHING_TASK_EXECUTOR = "jobLaunchingTaskExecutor"; + public static final String BULK_EXPORT_JOB_NAME = "bulkExportJob"; + public static final String GROUP_BULK_EXPORT_JOB_NAME = "groupBulkExportJob"; + public static final String PATIENT_BULK_EXPORT_JOB_NAME = "patientBulkExportJob"; + public static final String BULK_EXPORT_GENERATE_RESOURCE_FILES_STEP = "bulkExportGenerateResourceFilesStep"; + public static final String BULK_IMPORT_JOB_NAME = "bulkImportJob"; + public static final String BULK_IMPORT_PROCESSING_STEP = "bulkImportProcessingStep"; + /** + * Delete Expunge + */ + public static final String DELETE_EXPUNGE_JOB_NAME = "deleteExpungeJob"; + /** + * Reindex + */ + public static final String REINDEX_JOB_NAME = "reindexJob"; + /** + * Reindex Everything + */ + public static final String REINDEX_EVERYTHING_JOB_NAME = "reindexEverythingJob"; + /** + * MDM Clear + */ + public static final String MDM_CLEAR_JOB_NAME = "mdmClearJob"; + /** + * This Set contains the step names across all job types that are appropriate for + * someone to look at the write count for that given step in order to determine the + * number of processed records. + *

    + * This is provided since a job might have multiple steps that the same data passes + * through, so you can't just sum up the total of all of them. + *

    + * For any given batch job type, there should only be one step name in this set + */ + public static Set RECORD_PROCESSING_STEP_NAMES; + + static { + HashSet recordProcessingStepNames = new HashSet<>(); + recordProcessingStepNames.add(BatchConstants.BULK_IMPORT_PROCESSING_STEP); + recordProcessingStepNames.add(BatchConstants.BULK_EXPORT_GENERATE_RESOURCE_FILES_STEP); + BatchConstants.RECORD_PROCESSING_STEP_NAMES = Collections.unmodifiableSet(recordProcessingStepNames); + } + + /** + * v * Non instantiable + */ + private BatchConstants() { + } +} diff --git a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java similarity index 98% rename from hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java rename to hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java index 27eb2518893..00234d7c447 100644 --- a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java +++ b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/NonPersistedBatchConfigurer.java @@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.batch.config; * #L% */ -import ca.uhn.fhir.jpa.batch.BatchConstants; import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean; diff --git a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java similarity index 98% rename from hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java rename to hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java index 60f588d2e14..52625ec2c12 100644 --- a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java +++ b/hapi-fhir-batch/src/main/java/ca/uhn/fhir/jpa/batch/svc/BatchJobSubmitterImpl.java @@ -46,7 +46,7 @@ public class BatchJobSubmitterImpl implements IBatchJobSubmitter { private JobRepository myJobRepository; @Override - public JobExecution runJob(Job theJob, JobParameters theJobParameters) throws JobParametersInvalidException{ + public JobExecution runJob(Job theJob, JobParameters theJobParameters) throws JobParametersInvalidException { try { return myJobLauncher.run(theJob, theJobParameters); } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException e) { diff --git a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/BaseBatchR4Test.java b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/BaseBatchR4Test.java similarity index 100% rename from hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/BaseBatchR4Test.java rename to hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/BaseBatchR4Test.java diff --git a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java similarity index 99% rename from hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java rename to hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java index 7acf3590585..3de13fe7a66 100644 --- a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java +++ b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/BatchJobConfig.java @@ -22,7 +22,6 @@ public class BatchJobConfig { private StepBuilderFactory myStepBuilderFactory; - @Bean public Job testJob() { return myJobBuilderFactory.get("testJob") diff --git a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleItemReader.java b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleItemReader.java similarity index 100% rename from hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleItemReader.java rename to hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleItemReader.java diff --git a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleTasklet.java b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleTasklet.java similarity index 100% rename from hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleTasklet.java rename to hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/SampleTasklet.java diff --git a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java similarity index 99% rename from hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java rename to hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java index ca0fd6edbea..62e56a3b7a4 100644 --- a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java +++ b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/config/TestBatchConfig.java @@ -28,6 +28,7 @@ public class TestBatchConfig { asyncTaskExecutor.initialize(); return asyncTaskExecutor; } + @Bean public BatchConfigurer batchConfigurer() { return new NonPersistedBatchConfigurer(); diff --git a/hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/svc/BatchSvcTest.java b/hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/svc/BatchSvcTest.java similarity index 100% rename from hapi-fhir-jpaserver-batch/src/test/java/ca/uhn/fhir/jpa/batch/svc/BatchSvcTest.java rename to hapi-fhir-batch/src/test/java/ca/uhn/fhir/jpa/batch/svc/BatchSvcTest.java diff --git a/hapi-fhir-jpaserver-batch/src/test/resources/logback-test.xml b/hapi-fhir-batch/src/test/resources/logback-test.xml similarity index 82% rename from hapi-fhir-jpaserver-batch/src/test/resources/logback-test.xml rename to hapi-fhir-batch/src/test/resources/logback-test.xml index 161f3ef0359..90a11833d3b 100644 --- a/hapi-fhir-jpaserver-batch/src/test/resources/logback-test.xml +++ b/hapi-fhir-batch/src/test/resources/logback-test.xml @@ -8,47 +8,50 @@ - - + + - + - + - + - + - + - + - + - + - + - INFO + + INFO + ${smile.basedir}/log/batch-troubleshooting.log ${smile.basedir}/log/batch-troubleshooting.log.%i.gz @@ -59,7 +62,8 @@ 5MB - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n${log.stackfilter.pattern} + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n${log.stackfilter.pattern} + @@ -68,7 +72,7 @@ - + diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index 8fe5cf9a5b4..0ef10754ac7 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -3,14 +3,14 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT pom HAPI FHIR BOM ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -133,7 +133,7 @@ ${project.groupId} - hapi-fhir-jpaserver-migrate + hapi-fhir-sql-migrate ${project.version} diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index c03744e91ea..59e3eea4001 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../hapi-deployable-pom/pom.xml @@ -35,7 +35,7 @@ ca.uhn.hapi.fhir - hapi-fhir-jpaserver-migrate + hapi-fhir-sql-migrate ${project.version} diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index 5e11c79536a..66280895c25 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir-cli - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml index a53adf1d7b4..bc64a5bba36 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../hapi-deployable-pom diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index 1944f4105b2..887b3a49219 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index b12089d304e..d81caa143c1 100644 --- a/hapi-fhir-client-okhttp/pom.xml +++ b/hapi-fhir-client-okhttp/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index 50382d3feb9..0f6c971115a 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index ca9ac09d67d..e7127e92765 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index 7bd546d13d0..e3236999149 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index 5f99f8bd00b..ff4b66f1152 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2446-issues-with-placeholder-reference-targets-need-to-be-resolved-placeholder-identifier-true.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2446-issues-with-placeholder-reference-targets-need-to-be-resolved-placeholder-identifier-true.yaml index 47398526684..51ac0bab5bb 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2446-issues-with-placeholder-reference-targets-need-to-be-resolved-placeholder-identifier-true.yaml +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2446-issues-with-placeholder-reference-targets-need-to-be-resolved-placeholder-identifier-true.yaml @@ -1,5 +1,5 @@ --- type: change issue: 2446 -title: "DaoConfig setting for [Populate Identifier In Auto Created Placeholder Reference Targets](https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(boolean)) +title: "DaoConfig setting for [Populate Identifier In Auto Created Placeholder Reference Targets](https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(boolean)) now defaults to `true`." diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/appendix/javadocs.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/appendix/javadocs.md index 55175502942..00491ff2338 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/appendix/javadocs.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/appendix/javadocs.md @@ -9,7 +9,7 @@ See the [Modules Page](/docs/getting_started/modules.html) for more information * [Model API (R5)](/apidocs/hapi-fhir-structures-r5/) - hapi-fhir-structures-r5 * [Client API](/apidocs/hapi-fhir-client/) - hapi-fhir-client * [Plain Server API](/apidocs/hapi-fhir-server/) - hapi-fhir-server -* [JPA Server - API](/apidocs/hapi-fhir-jpaserver-api/) - hapi-fhir-jpaserver-api +* [JPA Server - API](/apidocs/hapi-fhir-storage-api/) - hapi-fhir-storage-api * [JPA Server - Model](/apidocs/hapi-fhir-jpaserver-model/) - hapi-fhir-jpaserver-model * [JPA Server - Base](/apidocs/hapi-fhir-jpaserver-base/) - hapi-fhir-jpaserver-base * [Version Converter API](/apidocs/hapi-fhir-converter/) - hapi-fhir-converter diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md index 932befb6f1a..1e3fe814321 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md @@ -54,9 +54,15 @@ In some cases, you may have references which are Logical References, which means that they act as an identifier and not necessarily as a literal web address. -A common use for logical references is in references to conformance resources, such as ValueSets, StructureDefinitions, etc. For example, you might refer to the ValueSet `http://hl7.org/fhir/ValueSet/quantity-comparator` from your own resources. In this case, you are not necessarily telling the server that this is a real address that it should resolve, but rather that this is an identifier for a ValueSet where `ValueSet.url` has the given URI/URL. +A common use for logical references is in references to conformance resources, such as ValueSets, StructureDefinitions, +etc. For example, you might refer to the ValueSet `http://hl7.org/fhir/ValueSet/quantity-comparator` from your own +resources. In this case, you are not necessarily telling the server that this is a real address that it should resolve, +but rather that this is an identifier for a ValueSet where `ValueSet.url` has the given URI/URL. -HAPI can be configured to treat certain URI/URL patterns as logical by using the DaoConfig#setTreatReferencesAsLogical property (see [JavaDoc](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setTreatReferencesAsLogical(java.util.Set))). +HAPI can be configured to treat certain URI/URL patterns as logical by using the DaoConfig#setTreatReferencesAsLogical +property ( +see [JavaDoc](/hapi-fhir/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setTreatReferencesAsLogical(java.util.Set))) +. For example: @@ -131,5 +137,5 @@ X-Retry-On-Version-Conflict: retry; max-retries=100 Delete with expunge submits a job to delete and expunge the requested resources. This is done in batches. If the DELETE ?_expunge=true syntax is used to trigger the delete expunge, then the batch size will be determined by the value -of [Expunge Batch Size](/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#getExpungeBatchSize()) +of [Expunge Batch Size](/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#getExpungeBatchSize()) property. diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/lastn.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/lastn.md index 0848298ee66..1dbc3476d61 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/lastn.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/lastn.md @@ -24,9 +24,13 @@ The grouping of Observation resources by `Observation.code` means that the `$las # Deployment and Configuration -The `$lastn` operation is disabled by default. The operation can be enabled by setting the DaoConfig#setLastNEnabled property (see [JavaDoc](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setLastNEnabled(boolean))). +The `$lastn` operation is disabled by default. The operation can be enabled by setting the DaoConfig#setLastNEnabled +property ( +see [JavaDoc](/hapi-fhir/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setLastNEnabled(boolean))) +. -In addition, the Elasticsearch client service, `ElasticsearchSvcImpl` will need to be instantiated with parameters specifying how to connect to the Elasticsearch server, for e.g.: +In addition, the Elasticsearch client service, `ElasticsearchSvcImpl` will need to be instantiated with parameters +specifying how to connect to the Elasticsearch server, for e.g.: ```java @Bean() diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/schema.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/schema.md index 17499751bb8..dc167281c69 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/schema.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/schema.md @@ -240,9 +240,18 @@ The complete raw contents of the resource is stored in the `RES_TEXT` column, us By default, the **HFJ_RESOURCE.RES_ID** column is used as the resource ID for all server-assigned IDs. For example, if a Patient resource is created in a completely empty database, it will be assigned the ID `Patient/1` by the server and RES_ID will have a value of 1. -However, when client-assigned IDs are used, these may contain text values to allow a client to create an ID such as `Patient/ABC`. When a client-assigned ID is given to a resource, a row is created in the **HFJ_RESOURCE** table. When an **HFJ_FORCED_ID** row exists corresponding to the equivalent **HFJ_RESOURCE** row, the RES_ID value is no longer visible or usable by FHIR clients and it becomes purely an internal ID to the JPA server. +However, when client-assigned IDs are used, these may contain text values to allow a client to create an ID such +as `Patient/ABC`. When a client-assigned ID is given to a resource, a row is created in the **HFJ_RESOURCE** table. When +an **HFJ_FORCED_ID** row exists corresponding to the equivalent **HFJ_RESOURCE** row, the RES_ID value is no longer +visible or usable by FHIR clients and it becomes purely an internal ID to the JPA server. -If the server has been configured with a [Resource Server ID Strategy](/apidocs/hapi-fhir-jpaserver-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setResourceServerIdStrategy(ca.uhn.fhir.jpa.api.config.DaoConfig.IdStrategyEnum)) of [UUID](/apidocs/hapi-fhir-jpaserver-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.IdStrategyEnum.html#UUID), or the server has been configured with a [Resource Client ID Strategy](/apidocs/hapi-fhir-jpaserver-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setResourceClientIdStrategy(ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum)) of [ANY](/apidocs/hapi-fhir-jpaserver-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.ClientIdStrategyEnum.html#ANY) the server will create a Forced ID for all resources (not only resources having textual IDs). +If the server has been configured with +a [Resource Server ID Strategy](/apidocs/hapi-fhir-storage-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setResourceServerIdStrategy(ca.uhn.fhir.jpa.api.config.DaoConfig.IdStrategyEnum)) +of [UUID](/apidocs/hapi-fhir-storage-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.IdStrategyEnum.html#UUID), or +the server has been configured with +a [Resource Client ID Strategy](/apidocs/hapi-fhir-storage-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setResourceClientIdStrategy(ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum)) +of [ANY](/apidocs/hapi-fhir-storage-api/undefined/ca/uhn/fhir/jpa/api/config/DaoConfig.ClientIdStrategyEnum.html#ANY) +the server will create a Forced ID for all resources (not only resources having textual IDs). ## Columns diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_expansion.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_expansion.md index 42302e38332..d5f4747ed07 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_expansion.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_expansion.md @@ -25,7 +25,10 @@ One important caveat is that chaining is currently not supported when using this ## Enabling MDM Expansion -On top of needing to instantiate an MDM module, you must enable this feature in the [DaoConfig](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html) bean, using the [Allow MDM Expansion](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setAllowMdmExpansion(boolean)) property. +On top of needing to instantiate an MDM module, you must enable this feature in +the [DaoConfig](/hapi-fhir/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html) bean, using +the [Allow MDM Expansion](/hapi-fhir/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setAllowMdmExpansion(boolean)) +property.

    It is important to note that enabling this functionality can lead to incorrect data being returned by a request, if your MDM links are incorrect. Use with caution. diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md index 7679c532977..8a291853cf2 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md @@ -601,7 +601,7 @@ This operation takes two optional Parameters. 0..1 The number of links that should be deleted at a time. If ommitted, then the batch size will be determined by the value -of [Expunge Batch Size](/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#getExpungeBatchSize()) +of [Expunge Batch Size](/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#getExpungeBatchSize()) property. diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_partitioning/partitioning.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_partitioning/partitioning.md index 2bb299f0bcd..5fda22365d2 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_partitioning/partitioning.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_partitioning/partitioning.md @@ -53,9 +53,12 @@ In a partitioned repository, it is important to understand that only a single po This fact can have security implications: -* A client might be blocked from creating `Patient/ABC` in the partition they have access to because this ID is already in use in another partition. +* A client might be blocked from creating `Patient/ABC` in the partition they have access to because this ID is already + in use in another partition. -* In a server using the default configuration of SEQUENTIAL_NUMERIC [Server ID Strategy](/hapi-fhir/apidocs/hapi-fhir-jpaserver-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setResourceServerIdStrategy(ca.uhn.fhir.jpa.api.config.DaoConfig.IdStrategyEnum)) a client may be able to infer the IDs of resources in other partitions based on the ID they were assigned. +* In a server using the default configuration of + SEQUENTIAL_NUMERIC [Server ID Strategy](/hapi-fhir/apidocs/hapi-fhir-storage-api/ca/uhn/fhir/jpa/api/config/DaoConfig.html#setResourceServerIdStrategy(ca.uhn.fhir.jpa.api.config.DaoConfig.IdStrategyEnum)) + a client may be able to infer the IDs of resources in other partitions based on the ID they were assigned. These considerations can be addressed by using UUID Server ID Strategy, and disallowing client-assigned IDs. diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index e9b53373037..b3b32b8b321 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -118,7 +118,7 @@ ca.uhn.hapi.fhir - hapi-fhir-jpaserver-api + hapi-fhir-storage-api ${project.version} diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 2887333a9c8..4e860ecd4b0 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml new file mode 100644 index 00000000000..149ee8cb261 --- /dev/null +++ b/hapi-fhir-jpa/pom.xml @@ -0,0 +1,119 @@ + + + + ca.uhn.hapi.fhir + hapi-deployable-pom + 5.6.0-PRE6-SNAPSHOT + ../hapi-deployable-pom/pom.xml + + 4.0.0 + + hapi-fhir-jpa + This project contains utility classes for working with spring-hibernate jpa and the Quartz Scheduler. + + + + + ca.uhn.hapi.fhir + hapi-fhir-base + ${project.version} + + + + javax.annotation + javax.annotation-api + + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r4 + ${project.version} + + + + + org.hibernate + hibernate-entitymanager + + + org.hibernate + hibernate-java8 + + + org.hibernate + hibernate-ehcache + + + net.sf.ehcache + ehcache-core + + + + + org.hibernate.validator + hibernate-validator + + + com.fasterxml + classmate + + + org.jboss.logging + jboss-logging + + + + + org.hibernate.search + hibernate-search-mapper-orm + + + org.apache.logging.log4j + log4j-api + + + + + + org.springframework + spring-beans + + + org.springframework + spring-orm + + + org.springframework + spring-context + + + xml-apis + xml-apis + + + + + org.springframework + spring-context-support + + + net.ttddyy + datasource-proxy + + + + + + org.quartz-scheduler + quartz + + + + + org.apache.commons + commons-collections4 + + + diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java index c0e3fcc1cf6..139d8056459 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/config/HapiFhirLocalContainerEntityManagerFactoryBean.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.config; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -23,7 +23,6 @@ package ca.uhn.fhir.jpa.config; import org.hibernate.cfg.AvailableSettings; import org.hibernate.query.criteria.LiteralHandlingMode; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.orm.hibernate5.SpringBeanContainer; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java similarity index 97% rename from hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java index 54b21244673..55c9bd14974 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/HapiJob.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.model.sched; /*- * #%L - * HAPI FHIR JPA Model + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java similarity index 97% rename from hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java index 28490808079..e3c7f5f211c 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/IHapiScheduler.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.model.sched; /*- * #%L - * HAPI FHIR JPA Model + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java similarity index 98% rename from hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java index d4de58c1427..ca61f336722 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ISchedulerService.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.model.sched; /*- * #%L - * HAPI FHIR JPA Model + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java similarity index 97% rename from hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java index 203f0d7039a..3b13fcc6c30 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ISmartLifecyclePhase.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.model.sched; /*- * #%L - * HAPI FHIR JPA Model + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java similarity index 98% rename from hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java index 6abfe39b8e5..65b41be9597 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/sched/ScheduledJobDefinition.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.model.sched; /*- * #%L - * HAPI FHIR JPA Model + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java similarity index 95% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java index 24c70a77d68..b29631b2ab9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/AutowiringSpringBeanJobFactory.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -20,8 +20,7 @@ package ca.uhn.fhir.jpa.sched; * #L% */ -import org.hl7.fhir.r5.model.InstantType; -import org.hl7.fhir.utilities.DateTimeUtil; +import org.hl7.fhir.r4.model.InstantType; import org.quartz.JobKey; import org.quartz.spi.TriggerFiredBundle; import org.slf4j.Logger; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java similarity index 93% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java index 49edd277ed0..288ea5a8605 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/BaseHapiScheduler.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -27,7 +27,15 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; import org.apache.commons.lang3.Validate; -import org.quartz.*; +import org.quartz.JobDataMap; +import org.quartz.JobKey; +import org.quartz.ScheduleBuilder; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SimpleScheduleBuilder; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; +import org.quartz.TriggerKey; import org.quartz.impl.JobDetailImpl; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.matchers.GroupMatcher; @@ -41,8 +49,6 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import static org.quartz.impl.StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME; - public abstract class BaseHapiScheduler implements IHapiScheduler { private static final Logger ourLog = LoggerFactory.getLogger(BaseHapiScheduler.class); @@ -96,7 +102,7 @@ public abstract class BaseHapiScheduler implements IHapiScheduler { protected void setProperties() { addProperty("org.quartz.threadPool.threadCount", "4"); - myProperties.setProperty(PROP_SCHED_INSTANCE_NAME, myInstanceName + "-" + nextSchedulerId()); + myProperties.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, myInstanceName + "-" + nextSchedulerId()); addProperty("org.quartz.threadPool.threadNamePrefix", getThreadPrefix()); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java similarity index 99% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java index 7b7e5cef61f..71f9664e1ac 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/BaseSchedulerServiceImpl.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java index b1ec4812aa5..e2738e8cdfc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/ClusteredHapiScheduler.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java index 44d89110ff6..4141a76f63e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/HapiNullScheduler.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java index 2bfb5ec83ba..cea59c2c120 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/HapiSchedulerServiceImpl.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java index 41b90d503f7..d3ee459d268 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/sched/LocalHapiScheduler.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.sched; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java similarity index 99% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java index ee05a385b97..e4d9a11f4d5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/BaseCaptureQueriesListener.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java similarity index 99% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java index 1dc3a47ee17..68239b01831 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -24,7 +24,7 @@ import ca.uhn.fhir.util.StopWatch; import com.google.common.collect.Queues; import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder; import org.apache.commons.collections4.queue.CircularFifoQueue; -import org.hl7.fhir.dstu3.model.InstantType; +import org.hl7.fhir.r4.model.InstantType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java similarity index 99% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java index 7c55cc6884c..36d01eb7c49 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CurrentThreadCaptureQueriesListener.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java index c0b3f22e008..5d869400e11 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/DerbyTenSevenHapiFhirDialect.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java similarity index 99% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java index d2221bd8eec..30e39105a8e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/SqlQuery.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java index e8dddd1ff81..ff83ab7f61e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/SqlQueryList.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java index 3b1ed6553fd..92282e69fcc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.util; /*- * #%L - * HAPI FHIR JPA Server + * hapi-fhir-jpa * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.util; * #L% */ -import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import com.google.common.collect.ImmutableSet; @@ -347,16 +346,12 @@ public class TestUtil { } } - public static void sleepAtLeast(long theMillis) { - HapiTransactionService.sleepAtLeast(theMillis, true); - } - public static InstantType getTimestamp(IBaseResource resource) { return new InstantType(new Date(resource.getMeta().getLastUpdated().getTime())); } public static void sleepOneClick() { - sleepAtLeast(1); + ca.uhn.fhir.util.TestUtil.sleepAtLeast(1); } diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index 428612b17c4..807371d55f8 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -90,6 +90,11 @@ hapi-fhir-jpaserver-searchparam ${project.version} + + ca.uhn.hapi.fhir + hapi-fhir-sql-migrate + ${project.version} + ca.uhn.hapi.fhir hapi-fhir-jpaserver-model @@ -147,13 +152,9 @@ ca.uhn.hapi.fhir - hapi-fhir-jpaserver-batch + hapi-fhir-batch ${project.version} - - net.ttddyy - datasource-proxy - ch.qos.logback @@ -307,12 +308,6 @@ provided - - org.quartz-scheduler - quartz - - - org.springframework @@ -324,24 +319,6 @@ - - org.springframework - spring-orm - - - org.springframework - spring-context - - - xml-apis - xml-apis - - - - - org.springframework - spring-beans - org.springframework.data spring-data-jpa @@ -376,40 +353,6 @@ org.springframework spring-websocket - - - - org.hibernate - hibernate-entitymanager - - - org.hibernate - hibernate-java8 - - - org.hibernate - hibernate-ehcache - - - net.sf.ehcache - ehcache-core - - - - - org.hibernate.validator - hibernate-validator - - - com.fasterxml - classmate - - - org.jboss.logging - jboss-logging - - - javax.el javax.el-api @@ -426,16 +369,6 @@ log4j-to-slf4j - - org.hibernate.search - hibernate-search-mapper-orm - - - org.apache.logging.log4j - log4j-api - - - org.elasticsearch.client elasticsearch-rest-high-level-client @@ -467,10 +400,6 @@ com.google.guava guava - - org.apache.commons - commons-collections4 - org.eclipse.jetty diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/BatchJobsConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/BatchJobsConfig.java index 9e96243d45c..f95d515ad18 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/BatchJobsConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/BatchJobsConfig.java @@ -29,10 +29,6 @@ import ca.uhn.fhir.jpa.reindex.job.ReindexJobConfig; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - @Configuration //When you define a new batch job, add it here. @Import({ @@ -45,60 +41,4 @@ import java.util.Set; MdmClearJobConfig.class }) public class BatchJobsConfig { - - /* - * Bulk Export - */ - - public static final String BULK_EXPORT_JOB_NAME = "bulkExportJob"; - public static final String GROUP_BULK_EXPORT_JOB_NAME = "groupBulkExportJob"; - public static final String PATIENT_BULK_EXPORT_JOB_NAME = "patientBulkExportJob"; - public static final String BULK_EXPORT_GENERATE_RESOURCE_FILES_STEP = "bulkExportGenerateResourceFilesStep"; - - /* - * Bulk Import - */ - - public static final String BULK_IMPORT_JOB_NAME = "bulkImportJob"; - public static final String BULK_IMPORT_PROCESSING_STEP = "bulkImportProcessingStep"; - - /** - * This Set contains the step names across all job types that are appropriate for - * someone to look at the write count for that given step in order to determine the - * number of processed records. - * - * This is provided since a job might have multiple steps that the same data passes - * through, so you can't just sum up the total of all of them. - * - * For any given batch job type, there should only be one step name in this set - */ - public static final Set RECORD_PROCESSING_STEP_NAMES; - - static { - HashSet recordProcessingStepNames = new HashSet<>(); - recordProcessingStepNames.add(BULK_IMPORT_PROCESSING_STEP); - recordProcessingStepNames.add(BULK_EXPORT_GENERATE_RESOURCE_FILES_STEP); - RECORD_PROCESSING_STEP_NAMES = Collections.unmodifiableSet(recordProcessingStepNames); - } - - /** - * Delete Expunge - */ - public static final String DELETE_EXPUNGE_JOB_NAME = "deleteExpungeJob"; - - /** - * Reindex - */ - public static final String REINDEX_JOB_NAME = "reindexJob"; - - /** - * Reindex Everything - */ - public static final String REINDEX_EVERYTHING_JOB_NAME = "reindexEverythingJob"; - - /** - * MDM Clear - */ - public static final String MDM_CLEAR_JOB_NAME = "mdmClearJob"; - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/job/MultiUrlJobParameterValidator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/job/MultiUrlJobParameterValidator.java index 57b77ea52ac..69774c7ac70 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/job/MultiUrlJobParameterValidator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/job/MultiUrlJobParameterValidator.java @@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.batch.job; */ import ca.uhn.fhir.jpa.api.dao.DaoRegistry; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.model.PartitionedUrl; import ca.uhn.fhir.jpa.batch.job.model.RequestListJson; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; @@ -29,8 +30,6 @@ import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersInvalidException; import org.springframework.batch.core.JobParametersValidator; -import static ca.uhn.fhir.jpa.batch.reader.ReverseCronologicalBatchResourcePidReader.JOB_PARAM_REQUEST_LIST; - /** * This class will prevent a job from running any of the provided URLs are not valid on this server. */ @@ -50,7 +49,7 @@ public class MultiUrlJobParameterValidator implements JobParametersValidator { throw new JobParametersInvalidException("This job requires Parameters: [urlList]"); } - RequestListJson requestListJson = RequestListJson.fromJson(theJobParameters.getString(JOB_PARAM_REQUEST_LIST)); + RequestListJson requestListJson = RequestListJson.fromJson(theJobParameters.getString(BatchConstants.JOB_PARAM_REQUEST_LIST)); for (PartitionedUrl partitionedUrl : requestListJson.getPartitionedUrls()) { String url = partitionedUrl.getUrl(); try { @@ -60,7 +59,7 @@ public class MultiUrlJobParameterValidator implements JobParametersValidator { throw new JobParametersInvalidException("The resource type " + resourceName + " is not supported on this server."); } } catch (UnsupportedOperationException e) { - throw new JobParametersInvalidException("Failed to parse " + theJobParameters.getString(JOB_PARAM_OPERATION_NAME) + " " + JOB_PARAM_REQUEST_LIST + " item " + url + ": " + e.getMessage()); + throw new JobParametersInvalidException("Failed to parse " + theJobParameters.getString(JOB_PARAM_OPERATION_NAME) + " " + BatchConstants.JOB_PARAM_REQUEST_LIST + " item " + url + ": " + e.getMessage()); } } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/MdmClearJobSubmitterImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/MdmClearJobSubmitterImpl.java index 90bee86b963..246bebac7c4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/MdmClearJobSubmitterImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/MdmClearJobSubmitterImpl.java @@ -24,8 +24,8 @@ import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.PartitionedUrlValidator; import ca.uhn.fhir.jpa.batch.job.model.RequestListJson; import ca.uhn.fhir.jpa.batch.mdm.job.ReverseCronologicalBatchMdmLinkPidReader; @@ -55,7 +55,7 @@ public class MdmClearJobSubmitterImpl implements IMdmClearJobSubmitter { @Autowired private IBatchJobSubmitter myBatchJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.MDM_CLEAR_JOB_NAME) + @Qualifier(BatchConstants.MDM_CLEAR_JOB_NAME) private Job myMdmClearJob; @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/job/MdmClearJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/job/MdmClearJobConfig.java index b2786f7cc84..9f8f339191b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/job/MdmClearJobConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/mdm/job/MdmClearJobConfig.java @@ -41,7 +41,7 @@ import org.springframework.context.annotation.Lazy; import java.util.ArrayList; import java.util.List; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.MDM_CLEAR_JOB_NAME; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.MDM_CLEAR_JOB_NAME; /** * Spring batch Job configuration file. Contains all necessary plumbing to run a diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/reader/BaseReverseCronologicalBatchPidReader.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/reader/BaseReverseCronologicalBatchPidReader.java index 46c5e91c22f..d32a3c6cae3 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/reader/BaseReverseCronologicalBatchPidReader.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch/reader/BaseReverseCronologicalBatchPidReader.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.batch.CommonBatchJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.MultiUrlJobParameterValidator; import ca.uhn.fhir.jpa.batch.job.model.PartitionedUrl; import ca.uhn.fhir.jpa.batch.job.model.RequestListJson; @@ -58,22 +59,17 @@ import java.util.function.Function; /** * This Spring Batch reader takes 4 parameters: - * {@link #JOB_PARAM_REQUEST_LIST}: A list of URLs to search for along with the partitions those searches should be performed on - * {@link #JOB_PARAM_BATCH_SIZE}: The number of resources to return with each search. If ommitted, {@link DaoConfig#getExpungeBatchSize} will be used. - * {@link #JOB_PARAM_START_TIME}: The latest timestamp of entities to search for + * {@link BatchConstants#JOB_PARAM_REQUEST_LIST}: A list of URLs to search for along with the partitions those searches should be performed on + * {@link BatchConstants#JOB_PARAM_BATCH_SIZE}: The number of resources to return with each search. If ommitted, {@link DaoConfig#getExpungeBatchSize} will be used. + * {@link BatchConstants#JOB_PARAM_START_TIME}: The latest timestamp of entities to search for *

    - * The reader will return at most {@link #JOB_PARAM_BATCH_SIZE} pids every time it is called, or null + * The reader will return at most {@link BatchConstants#JOB_PARAM_BATCH_SIZE} pids every time it is called, or null * once no more matching entities are available. It returns the resources in reverse chronological order - * and stores where it's at in the Spring Batch execution context with the key {@link #CURRENT_THRESHOLD_HIGH} + * and stores where it's at in the Spring Batch execution context with the key {@link BatchConstants#CURRENT_THRESHOLD_HIGH} * appended with "." and the index number of the url list item it has gotten up to. This is to permit * restarting jobs that use this reader so it can pick up where it left off. */ public abstract class BaseReverseCronologicalBatchPidReader implements ItemReader>, ItemStream { - public static final String JOB_PARAM_REQUEST_LIST = "url-list"; - public static final String JOB_PARAM_BATCH_SIZE = "batch-size"; - public static final String JOB_PARAM_START_TIME = "start-time"; - public static final String CURRENT_URL_INDEX = "current.url-index"; - public static final String CURRENT_THRESHOLD_HIGH = "current.threshold-high"; private static final Logger ourLog = LoggerFactory.getLogger(ReverseCronologicalBatchResourcePidReader.class); private final BatchDateThresholdUpdater myBatchDateThresholdUpdater = new BatchDateThresholdUpdater(); private final Map myThresholdHighByUrlIndex = new HashMap<>(); @@ -88,30 +84,30 @@ public abstract class BaseReverseCronologicalBatchPidReader implements ItemReade private Date myStartTime; private static String highKey(int theIndex) { - return CURRENT_THRESHOLD_HIGH + "." + theIndex; + return BatchConstants.CURRENT_THRESHOLD_HIGH + "." + theIndex; } @Nonnull public static JobParameters buildJobParameters(String theOperationName, Integer theBatchSize, RequestListJson theRequestListJson) { Map map = new HashMap<>(); map.put(MultiUrlJobParameterValidator.JOB_PARAM_OPERATION_NAME, new JobParameter(theOperationName)); - map.put(ReverseCronologicalBatchResourcePidReader.JOB_PARAM_REQUEST_LIST, new JobParameter(theRequestListJson.toJson())); - map.put(ReverseCronologicalBatchResourcePidReader.JOB_PARAM_START_TIME, new JobParameter(DateUtils.addMinutes(new Date(), CommonBatchJobConfig.MINUTES_IN_FUTURE_TO_PROCESS_FROM))); + map.put(BatchConstants.JOB_PARAM_REQUEST_LIST, new JobParameter(theRequestListJson.toJson())); + map.put(BatchConstants.JOB_PARAM_START_TIME, new JobParameter(DateUtils.addMinutes(new Date(), CommonBatchJobConfig.MINUTES_IN_FUTURE_TO_PROCESS_FROM))); if (theBatchSize != null) { - map.put(ReverseCronologicalBatchResourcePidReader.JOB_PARAM_BATCH_SIZE, new JobParameter(theBatchSize.longValue())); + map.put(BatchConstants.JOB_PARAM_BATCH_SIZE, new JobParameter(theBatchSize.longValue())); } JobParameters parameters = new JobParameters(map); return parameters; } @Autowired - public void setRequestListJson(@Value("#{jobParameters['" + JOB_PARAM_REQUEST_LIST + "']}") String theRequestListJson) { + public void setRequestListJson(@Value("#{jobParameters['" + BatchConstants.JOB_PARAM_REQUEST_LIST + "']}") String theRequestListJson) { RequestListJson requestListJson = RequestListJson.fromJson(theRequestListJson); myPartitionedUrls = requestListJson.getPartitionedUrls(); } @Autowired - public void setStartTime(@Value("#{jobParameters['" + JOB_PARAM_START_TIME + "']}") Date theStartTime) { + public void setStartTime(@Value("#{jobParameters['" + BatchConstants.JOB_PARAM_START_TIME + "']}") Date theStartTime) { myStartTime = theStartTime; } @@ -166,8 +162,8 @@ public abstract class BaseReverseCronologicalBatchPidReader implements ItemReade @Override public void open(ExecutionContext executionContext) throws ItemStreamException { - if (executionContext.containsKey(CURRENT_URL_INDEX)) { - myUrlIndex = new Long(executionContext.getLong(CURRENT_URL_INDEX)).intValue(); + if (executionContext.containsKey(BatchConstants.CURRENT_URL_INDEX)) { + myUrlIndex = new Long(executionContext.getLong(BatchConstants.CURRENT_URL_INDEX)).intValue(); } for (int index = 0; index < myPartitionedUrls.size(); ++index) { String key = highKey(index); @@ -181,7 +177,7 @@ public abstract class BaseReverseCronologicalBatchPidReader implements ItemReade @Override public void update(ExecutionContext executionContext) throws ItemStreamException { - executionContext.putLong(CURRENT_URL_INDEX, myUrlIndex); + executionContext.putLong(BatchConstants.CURRENT_URL_INDEX, myUrlIndex); for (int index = 0; index < myPartitionedUrls.size(); ++index) { Date date = myThresholdHighByUrlIndex.get(index); if (date != null) { @@ -199,7 +195,7 @@ public abstract class BaseReverseCronologicalBatchPidReader implements ItemReade } @Autowired - public void setBatchSize(@Value("#{jobParameters['" + JOB_PARAM_BATCH_SIZE + "']}") Integer theBatchSize) { + public void setBatchSize(@Value("#{jobParameters['" + BatchConstants.JOB_PARAM_BATCH_SIZE + "']}") Integer theBatchSize) { myBatchSize = theBatchSize; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BaseBulkItemReader.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BaseBulkItemReader.java index 7f934cfb248..6f647bd0e58 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BaseBulkItemReader.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BaseBulkItemReader.java @@ -25,6 +25,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.log.Logs; import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; @@ -57,7 +58,7 @@ public abstract class BaseBulkItemReader implements ItemReader, List>chunk(CHUNK_SIZE) //1000 resources per generated file, as the reader returns 10 resources at a time. .reader(bulkItemReader()) .processor(myPidToIBaseResourceProcessor) @@ -217,7 +216,7 @@ public class BulkExportJobConfig { @Bean public Step bulkExportPartitionStep() { return myStepBuilderFactory.get("partitionStep") - .partitioner(BatchJobsConfig.BULK_EXPORT_GENERATE_RESOURCE_FILES_STEP, bulkExportResourceTypePartitioner()) + .partitioner(BatchConstants.BULK_EXPORT_GENERATE_RESOURCE_FILES_STEP, bulkExportResourceTypePartitioner()) .step(bulkExportGenerateResourceFilesStep()) .build(); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobParameterValidator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobParameterValidator.java index 64d06052d43..300a26c8c1f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobParameterValidator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobParameterValidator.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.bulk.export.job; * #L% */ +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.dao.data.IBulkExportJobDao; import ca.uhn.fhir.jpa.entity.BulkExportJobEntity; import ca.uhn.fhir.rest.api.Constants; @@ -34,8 +35,6 @@ import org.springframework.transaction.support.TransactionTemplate; import java.util.Arrays; import java.util.Optional; -import static org.slf4j.LoggerFactory.getLogger; - /** * This class will prevent a job from running if the UUID does not exist or is invalid. */ @@ -59,7 +58,7 @@ public class BulkExportJobParameterValidator implements JobParametersValidator { if (readChunkSize == null || readChunkSize < 1) { errorBuilder.append("There must be a valid number for readChunkSize, which is at least 1. "); } - String jobUUID = theJobParameters.getString(BulkExportJobConfig.JOB_UUID_PARAMETER); + String jobUUID = theJobParameters.getString(BatchConstants.JOB_UUID_PARAMETER); Optional oJob = myBulkExportJobDao.findByJobId(jobUUID); if (!StringUtils.isBlank(jobUUID) && !oJob.isPresent()) { errorBuilder.append("There is no persisted job that exists with UUID: " + jobUUID + ". "); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/CreateBulkExportEntityTasklet.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/CreateBulkExportEntityTasklet.java index 9c10bcecba8..8be17cb3b4d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/CreateBulkExportEntityTasklet.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/CreateBulkExportEntityTasklet.java @@ -20,10 +20,11 @@ package ca.uhn.fhir.jpa.bulk.export.job; * #L% */ -import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportSvc; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions; import org.apache.commons.lang3.StringUtils; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; @@ -42,18 +43,27 @@ public class CreateBulkExportEntityTasklet implements Tasklet { @Autowired private IBulkDataExportSvc myBulkDataExportSvc; + public static void addUUIDToJobContext(ChunkContext theChunkContext, String theJobUUID) { + theChunkContext + .getStepContext() + .getStepExecution() + .getJobExecution() + .getExecutionContext() + .putString(BatchConstants.JOB_UUID_PARAMETER, theJobUUID); + } + @Override public RepeatStatus execute(StepContribution theStepContribution, ChunkContext theChunkContext) throws Exception { Map jobParameters = theChunkContext.getStepContext().getJobParameters(); //We can leave early if they provided us with an existing job. - if (jobParameters.containsKey(BulkExportJobConfig.JOB_UUID_PARAMETER)) { - addUUIDToJobContext(theChunkContext, (String)jobParameters.get(BulkExportJobConfig.JOB_UUID_PARAMETER)); + if (jobParameters.containsKey(BatchConstants.JOB_UUID_PARAMETER)) { + addUUIDToJobContext(theChunkContext, (String) jobParameters.get(BatchConstants.JOB_UUID_PARAMETER)); return RepeatStatus.FINISHED; } else { - String resourceTypes = (String)jobParameters.get("resourceTypes"); - Date since = (Date)jobParameters.get("since"); - String filters = (String)jobParameters.get("filters"); + String resourceTypes = (String) jobParameters.get("resourceTypes"); + Date since = (Date) jobParameters.get("since"); + String filters = (String) jobParameters.get("filters"); Set filterSet; if (StringUtils.isBlank(filters)) { filterSet = null; @@ -86,13 +96,4 @@ public class CreateBulkExportEntityTasklet implements Tasklet { return RepeatStatus.FINISHED; } } - - public static void addUUIDToJobContext(ChunkContext theChunkContext, String theJobUUID) { - theChunkContext - .getStepContext() - .getStepExecution() - .getJobExecution() - .getExecutionContext() - .putString(BulkExportJobConfig.JOB_UUID_PARAMETER, theJobUUID); - } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/ResourceTypePartitioner.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/ResourceTypePartitioner.java index 7eb612d2211..f341d25ffdc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/ResourceTypePartitioner.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/ResourceTypePartitioner.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.bulk.export.job; * #L% */ +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.export.svc.BulkExportDaoSvc; import org.slf4j.Logger; import org.springframework.batch.core.partition.support.Partitioner; @@ -60,7 +61,7 @@ public class ResourceTypePartitioner implements Partitioner { // The worker step needs to know which parent job it is processing for, and which collection entity it will be // attaching its results to. - context.putString(BulkExportJobConfig.JOB_UUID_PARAMETER, myJobUUID); + context.putString(BatchConstants.JOB_UUID_PARAMETER, myJobUUID); context.putLong("bulkExportCollectionEntityId", collectionEntityId); // Name the partition based on the resource type diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/BulkDataExportSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/BulkDataExportSvcImpl.java index ab862ce44f2..2caa72135bc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/BulkDataExportSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/BulkDataExportSvcImpl.java @@ -30,9 +30,8 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.model.ExpungeOptions; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; -import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportSvc; import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; import ca.uhn.fhir.jpa.bulk.export.model.BulkExportJobStatusEnum; @@ -49,6 +48,7 @@ import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; @@ -114,15 +114,15 @@ public class BulkDataExportSvcImpl implements IBulkDataExportSvc { private IBatchJobSubmitter myJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.BULK_EXPORT_JOB_NAME) + @Qualifier(BatchConstants.BULK_EXPORT_JOB_NAME) private org.springframework.batch.core.Job myBulkExportJob; @Autowired - @Qualifier(BatchJobsConfig.GROUP_BULK_EXPORT_JOB_NAME) + @Qualifier(BatchConstants.GROUP_BULK_EXPORT_JOB_NAME) private org.springframework.batch.core.Job myGroupBulkExportJob; @Autowired - @Qualifier(BatchJobsConfig.PATIENT_BULK_EXPORT_JOB_NAME) + @Qualifier(BatchConstants.PATIENT_BULK_EXPORT_JOB_NAME) private org.springframework.batch.core.Job myPatientBulkExportJob; private Set myCompartmentResources; @@ -243,7 +243,7 @@ public class BulkDataExportSvcImpl implements IBulkDataExportSvc { private void processJob(BulkExportJobEntity theBulkExportJobEntity) { String theJobUuid = theBulkExportJobEntity.getJobId(); JobParametersBuilder parameters = new JobParametersBuilder() - .addString(BulkExportJobConfig.JOB_UUID_PARAMETER, theJobUuid) + .addString(BatchConstants.JOB_UUID_PARAMETER, theJobUuid) .addLong(BulkExportJobConfig.READ_CHUNK_PARAMETER, READ_CHUNK_SIZE); ourLog.info("Submitting bulk export job {} to job scheduler", theJobUuid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/ActivateBulkImportEntityStepListener.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/ActivateBulkImportEntityStepListener.java index 52520edf6b3..994aea3796e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/ActivateBulkImportEntityStepListener.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/ActivateBulkImportEntityStepListener.java @@ -20,10 +20,9 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; * #L% */ -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; import ca.uhn.fhir.jpa.bulk.imprt.model.BulkImportJobStatusEnum; -import org.elasticsearch.client.enrich.ExecutePolicyResponse; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecutionListener; @@ -39,7 +38,7 @@ public class ActivateBulkImportEntityStepListener implements StepExecutionListen @Override public void beforeStep(StepExecution theStepExecution) { - String jobUuid = theStepExecution.getJobExecution().getJobParameters().getString(BulkExportJobConfig.JOB_UUID_PARAMETER); + String jobUuid = theStepExecution.getJobExecution().getJobParameters().getString(BatchConstants.JOB_UUID_PARAMETER); if (jobUuid != null) { myBulkImportDaoSvc.setJobToStatus(jobUuid, BulkImportJobStatusEnum.RUNNING); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileReader.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileReader.java index c16e7c3f67c..c1e4bec40fd 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileReader.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileReader.java @@ -21,8 +21,8 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; */ import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.log.Logs; -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; import ca.uhn.fhir.jpa.bulk.imprt.model.BulkImportJobFileJson; import ca.uhn.fhir.jpa.bulk.imprt.model.ParsedBulkImportRecord; @@ -42,7 +42,7 @@ public class BulkImportFileReader implements ItemReader private IBulkDataImportSvc myBulkDataImportSvc; @Autowired private FhirContext myFhirContext; - @Value("#{stepExecutionContext['" + BulkExportJobConfig.JOB_UUID_PARAMETER + "']}") + @Value("#{stepExecutionContext['" + BatchConstants.JOB_UUID_PARAMETER + "']}") private String myJobUuid; @Value("#{stepExecutionContext['" + BulkImportPartitioner.FILE_INDEX + "']}") private int myFileIndex; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java index 37a49ca2a95..5edc7ef9e23 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportFileWriter.java @@ -22,7 +22,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.imprt.model.JobFileRowProcessingModeEnum; import ca.uhn.fhir.jpa.bulk.imprt.model.ParsedBulkImportRecord; import ca.uhn.fhir.jpa.partition.SystemRequestDetails; @@ -39,7 +39,7 @@ import java.util.List; public class BulkImportFileWriter implements ItemWriter { private static final Logger ourLog = LoggerFactory.getLogger(BulkImportFileWriter.class); - @Value("#{stepExecutionContext['" + BulkExportJobConfig.JOB_UUID_PARAMETER + "']}") + @Value("#{stepExecutionContext['" + BatchConstants.JOB_UUID_PARAMETER + "']}") private String myJobUuid; @Value("#{stepExecutionContext['" + BulkImportPartitioner.FILE_INDEX + "']}") private int myFileIndex; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobCloser.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobCloser.java index 504874e327d..3866829bf16 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobCloser.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobCloser.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; * #L% */ -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; import ca.uhn.fhir.jpa.bulk.imprt.model.BulkImportJobStatusEnum; import org.springframework.batch.core.BatchStatus; @@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.Value; */ public class BulkImportJobCloser implements Tasklet { - @Value("#{jobParameters['" + BulkExportJobConfig.JOB_UUID_PARAMETER + "']}") + @Value("#{jobParameters['" + BatchConstants.JOB_UUID_PARAMETER + "']}") private String myJobUUID; @Autowired diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java index b235c81ea2b..019b5db8ed1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobConfig.java @@ -21,14 +21,13 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; */ import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchConstants; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.imprt.model.ParsedBulkImportRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobParametersValidator; import org.springframework.batch.core.Step; -import org.springframework.batch.core.configuration.JobRegistry; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.JobScope; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; @@ -50,8 +49,8 @@ import org.springframework.retry.policy.TimeoutRetryPolicy; import javax.batch.api.chunk.listener.RetryProcessListener; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.BULK_IMPORT_JOB_NAME; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.BULK_IMPORT_PROCESSING_STEP; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.BULK_IMPORT_JOB_NAME; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.BULK_IMPORT_PROCESSING_STEP; /** * Spring batch Job configuration file. Contains all necessary plumbing to run a diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobParameterValidator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobParameterValidator.java index a46405fec31..c26673665ed 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobParameterValidator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportJobParameterValidator.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; * #L% */ -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.dao.data.IBulkImportJobDao; import ca.uhn.fhir.jpa.entity.BulkImportJobEntity; import org.apache.commons.lang3.StringUtils; @@ -52,7 +52,7 @@ public class BulkImportJobParameterValidator implements JobParametersValidator { TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager); String errorMessage = txTemplate.execute(tx -> { StringBuilder errorBuilder = new StringBuilder(); - String jobUUID = theJobParameters.getString(BulkExportJobConfig.JOB_UUID_PARAMETER); + String jobUUID = theJobParameters.getString(BatchConstants.JOB_UUID_PARAMETER); Optional oJob = myBulkImportJobDao.findByJobId(jobUUID); if (!StringUtils.isBlank(jobUUID) && !oJob.isPresent()) { errorBuilder.append("There is no persisted job that exists with UUID: "); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportPartitioner.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportPartitioner.java index 6a88cfbecab..6df34a9571d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportPartitioner.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportPartitioner.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; * #L% */ -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; import ca.uhn.fhir.jpa.bulk.imprt.model.BulkImportJobJson; import org.slf4j.Logger; @@ -43,7 +43,7 @@ public class BulkImportPartitioner implements Partitioner { private static final Logger ourLog = getLogger(BulkImportPartitioner.class); - @Value("#{jobParameters['" + BulkExportJobConfig.JOB_UUID_PARAMETER + "']}") + @Value("#{jobParameters['" + BatchConstants.JOB_UUID_PARAMETER + "']}") private String myJobUUID; @Autowired @@ -61,7 +61,7 @@ public class BulkImportPartitioner implements Partitioner { String fileDescription = myBulkDataImportSvc.getFileDescription(myJobUUID, i); ExecutionContext context = new ExecutionContext(); - context.putString(BulkExportJobConfig.JOB_UUID_PARAMETER, myJobUUID); + context.putString(BatchConstants.JOB_UUID_PARAMETER, myJobUUID); context.putInt(FILE_INDEX, i); context.put(ROW_PROCESSING_MODE, job.getProcessingMode()); context.put(JOB_DESCRIPTION, job.getJobDescription()); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java index 2861780a4ff..014ec74a92b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/BulkImportStepListener.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; * #L% */ -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; import ca.uhn.fhir.jpa.bulk.imprt.model.BulkImportJobStatusEnum; import org.springframework.batch.core.ExitStatus; @@ -52,9 +52,9 @@ public class BulkImportStepListener implements StepExecutionListener, RetryListe public ExitStatus afterStep(StepExecution theStepExecution) { if (theStepExecution.getExitStatus().getExitCode().equals(ExitStatus.FAILED.getExitCode())) { //Try to fetch it from the parameters first, and if it doesn't exist, fetch it from the context. - String jobUuid = theStepExecution.getJobExecution().getJobParameters().getString(BulkExportJobConfig.JOB_UUID_PARAMETER); + String jobUuid = theStepExecution.getJobExecution().getJobParameters().getString(BatchConstants.JOB_UUID_PARAMETER); if (jobUuid == null) { - jobUuid = theStepExecution.getJobExecution().getExecutionContext().getString(BulkExportJobConfig.JOB_UUID_PARAMETER); + jobUuid = theStepExecution.getJobExecution().getExecutionContext().getString(BatchConstants.JOB_UUID_PARAMETER); } assert isNotBlank(jobUuid); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/CreateBulkImportEntityTasklet.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/CreateBulkImportEntityTasklet.java index c543ba4961f..2d93b98c98f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/CreateBulkImportEntityTasklet.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/job/CreateBulkImportEntityTasklet.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.job; * #L% */ -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.export.job.CreateBulkExportEntityTasklet; import ca.uhn.fhir.util.ValidateUtil; import org.springframework.batch.core.StepContribution; @@ -37,8 +37,8 @@ public class CreateBulkImportEntityTasklet implements Tasklet { Map jobParameters = theChunkContext.getStepContext().getJobParameters(); //We can leave early if they provided us with an existing job. - ValidateUtil.isTrueOrThrowInvalidRequest(jobParameters.containsKey(BulkExportJobConfig.JOB_UUID_PARAMETER), "Job doesn't have a UUID"); - CreateBulkExportEntityTasklet.addUUIDToJobContext(theChunkContext, (String) jobParameters.get(BulkExportJobConfig.JOB_UUID_PARAMETER)); + ValidateUtil.isTrueOrThrowInvalidRequest(jobParameters.containsKey(BatchConstants.JOB_UUID_PARAMETER), "Job doesn't have a UUID"); + CreateBulkExportEntityTasklet.addUUIDToJobContext(theChunkContext, (String) jobParameters.get(BatchConstants.JOB_UUID_PARAMETER)); return RepeatStatus.FINISHED; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportSvcImpl.java index 7c162ea8aca..3124eb43dbf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportSvcImpl.java @@ -21,8 +21,8 @@ package ca.uhn.fhir.jpa.bulk.imprt.svc; */ import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.log.Logs; import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; @@ -79,7 +79,7 @@ public class BulkDataImportSvcImpl implements IBulkDataImportSvc { @Autowired private IBatchJobSubmitter myJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.BULK_IMPORT_JOB_NAME) + @Qualifier(BatchConstants.BULK_IMPORT_JOB_NAME) private org.springframework.batch.core.Job myBulkImportJob; @Autowired private DaoConfig myDaoConfig; @@ -271,7 +271,7 @@ public class BulkDataImportSvcImpl implements IBulkDataImportSvc { ValidateUtil.isTrueOrThrowInvalidRequest(batchSize > 0, "Batch size must be positive"); JobParametersBuilder parameters = new JobParametersBuilder() - .addString(BulkExportJobConfig.JOB_UUID_PARAMETER, jobId) + .addString(BatchConstants.JOB_UUID_PARAMETER, jobId) .addLong(BulkImportJobConfig.JOB_PARAM_COMMIT_INTERVAL, (long) batchSize); if (isNotBlank(theBulkExportJobEntity.getJobDescription())) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java index 72a2535faef..f2a6ccfe046 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java @@ -11,9 +11,9 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IDao; import ca.uhn.fhir.jpa.api.model.ExpungeOptions; import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc; -import ca.uhn.fhir.jpa.batch.BatchConstants; import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.config.NonPersistedBatchConfigurer; import ca.uhn.fhir.jpa.batch.job.PartitionedUrlValidator; import ca.uhn.fhir.jpa.batch.mdm.MdmBatchJobSubmitterFactoryImpl; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/tx/HapiTransactionService.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/tx/HapiTransactionService.java index 4a9c94376c8..200ac7a6861 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/tx/HapiTransactionService.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/tx/HapiTransactionService.java @@ -32,6 +32,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster; +import ca.uhn.fhir.util.TestUtil; import com.google.common.annotations.VisibleForTesting; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.slf4j.Logger; @@ -118,7 +119,7 @@ public class HapiTransactionService { theTransactionDetails.clearUserData(BaseHapiFhirDao.XACT_USERDATA_KEY_EXISTING_SEARCH_PARAMS); double sleepAmount = (250.0d * i) * Math.random(); long sleepAmountLong = (long) sleepAmount; - sleepAtLeast(sleepAmountLong, false); + TestUtil.sleepAtLeast(sleepAmountLong, false); ourLog.info("About to start a transaction retry due to conflict or constraint error. Sleeping {}ms first.", sleepAmountLong); continue; @@ -164,22 +165,4 @@ public class HapiTransactionService { super(theThrowable); } } - - @SuppressWarnings("BusyWait") - public static void sleepAtLeast(long theMillis, boolean theLogProgress) { - long start = System.currentTimeMillis(); - while (System.currentTimeMillis() <= start + theMillis) { - try { - long timeSinceStarted = System.currentTimeMillis() - start; - long timeToSleep = Math.max(0, theMillis - timeSinceStarted); - if (theLogProgress) { - ourLog.info("Sleeping for {}ms", timeToSleep); - } - Thread.sleep(timeToSleep); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - ourLog.error("Interrupted", e); - } - } - } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteExpungeJobSubmitterImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteExpungeJobSubmitterImpl.java index 73e561d1dd1..deb926ab426 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteExpungeJobSubmitterImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/DeleteExpungeJobSubmitterImpl.java @@ -25,8 +25,8 @@ import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.PartitionedUrlValidator; import ca.uhn.fhir.jpa.batch.job.model.RequestListJson; import ca.uhn.fhir.jpa.batch.reader.ReverseCronologicalBatchResourcePidReader; @@ -52,7 +52,7 @@ public class DeleteExpungeJobSubmitterImpl implements IDeleteExpungeJobSubmitter @Autowired private IBatchJobSubmitter myBatchJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.DELETE_EXPUNGE_JOB_NAME) + @Qualifier(BatchConstants.DELETE_EXPUNGE_JOB_NAME) private Job myDeleteExpungeJob; @Autowired FhirContext myFhirContext; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobConfig.java index 756aab743e4..4ab6c91bea4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobConfig.java @@ -20,12 +20,10 @@ package ca.uhn.fhir.jpa.delete.job; * #L% */ -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.batch.job.MultiUrlJobParameterValidator; import ca.uhn.fhir.jpa.batch.listener.PidReaderCounterListener; import ca.uhn.fhir.jpa.batch.reader.ReverseCronologicalBatchResourcePidReader; import ca.uhn.fhir.jpa.batch.writer.SqlExecutorWriter; -import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; @@ -39,7 +37,7 @@ import org.springframework.context.annotation.Lazy; import java.util.List; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.DELETE_EXPUNGE_JOB_NAME; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.DELETE_EXPUNGE_JOB_NAME; /** * Spring batch Job configuration file. Contains all necessary plumbing to run a diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/MdmSearchExpandingInterceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/MdmSearchExpandingInterceptor.java index 1ec7b3593c9..5eb66b5aab2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/MdmSearchExpandingInterceptor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/MdmSearchExpandingInterceptor.java @@ -29,9 +29,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.ReferenceParam; -import joptsimple.internal.Strings; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -39,8 +37,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -import static org.slf4j.LoggerFactory.getLogger; - /** * This interceptor replaces the auto-generated CapabilityStatement that is generated * by the HAPI FHIR Server with a static hard-coded resource. diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java rename to hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java index 5cd1eb78135..2229c43cb64 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.migrate.tasks; /*- * #%L - * HAPI FHIR JPA Server - Migration + * HAPI FHIR JPA Server * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProvider.java index 05c695f6b47..876bae329fe 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProvider.java @@ -50,13 +50,13 @@ public class BaseJpaSystemProvider extends BaseJpaProvider implements IJp * @deprecated */ @Deprecated - public static final String MARK_ALL_RESOURCES_FOR_REINDEXING = "$mark-all-resources-for-reindexing"; + public static final String MARK_ALL_RESOURCES_FOR_REINDEXING = ProviderConstants.MARK_ALL_RESOURCES_FOR_REINDEXING; /** * @see ProviderConstants#OPERATION_REINDEX * @deprecated */ @Deprecated - public static final String PERFORM_REINDEXING_PASS = "$perform-reindexing-pass"; + public static final String PERFORM_REINDEXING_PASS = ProviderConstants.PERFORM_REINDEXING_PASS; private IFhirSystemDao myDao; @Autowired diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/ReindexJobSubmitterImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/ReindexJobSubmitterImpl.java index 582eba93e23..572d2f5e409 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/ReindexJobSubmitterImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/ReindexJobSubmitterImpl.java @@ -22,8 +22,8 @@ package ca.uhn.fhir.jpa.reindex; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.PartitionedUrlValidator; import ca.uhn.fhir.jpa.batch.job.model.RequestListJson; import ca.uhn.fhir.jpa.batch.reader.CronologicalBatchAllResourcePidReader; @@ -53,10 +53,10 @@ public class ReindexJobSubmitterImpl implements IReindexJobSubmitter { @Autowired private IBatchJobSubmitter myBatchJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.REINDEX_JOB_NAME) + @Qualifier(BatchConstants.REINDEX_JOB_NAME) private Job myReindexJob; @Autowired - @Qualifier(BatchJobsConfig.REINDEX_EVERYTHING_JOB_NAME) + @Qualifier(BatchConstants.REINDEX_EVERYTHING_JOB_NAME) private Job myReindexEverythingJob; @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexEverythingJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexEverythingJobConfig.java index 33fdfaf8ece..48b9c3683c0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexEverythingJobConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexEverythingJobConfig.java @@ -35,7 +35,7 @@ import org.springframework.context.annotation.Lazy; import java.util.List; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.REINDEX_EVERYTHING_JOB_NAME; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.REINDEX_EVERYTHING_JOB_NAME; /** * Spring batch Job configuration file. Contains all necessary plumbing to run a diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexJobConfig.java index c5465ec3533..d3aa68c8fda 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexJobConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/reindex/job/ReindexJobConfig.java @@ -20,18 +20,14 @@ package ca.uhn.fhir.jpa.reindex.job; * #L% */ -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.batch.job.MultiUrlJobParameterValidator; import ca.uhn.fhir.jpa.batch.listener.PidReaderCounterListener; import ca.uhn.fhir.jpa.batch.reader.ReverseCronologicalBatchResourcePidReader; -import ca.uhn.fhir.jpa.batch.writer.SqlExecutorWriter; -import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.listener.ExecutionContextPromotionListener; -import org.springframework.batch.item.ItemReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,7 +35,7 @@ import org.springframework.context.annotation.Lazy; import java.util.List; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.REINDEX_JOB_NAME; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.REINDEX_JOB_NAME; /** * Spring batch Job configuration file. Contains all necessary plumbing to run a diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java index 019e799e760..2aea7021f12 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/BulkDataExportSvcImplR4Test.java @@ -6,8 +6,8 @@ import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportSvc; import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobParametersBuilder; import ca.uhn.fhir.jpa.bulk.export.job.GroupBulkExportJobParametersBuilder; @@ -102,15 +102,15 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test { private BatchJobHelper myBatchJobHelper; @Autowired - @Qualifier(BatchJobsConfig.BULK_EXPORT_JOB_NAME) + @Qualifier(BatchConstants.BULK_EXPORT_JOB_NAME) private Job myBulkJob; @Autowired - @Qualifier(BatchJobsConfig.GROUP_BULK_EXPORT_JOB_NAME) + @Qualifier(BatchConstants.GROUP_BULK_EXPORT_JOB_NAME) private Job myGroupBulkJob; @Autowired - @Qualifier(BatchJobsConfig.PATIENT_BULK_EXPORT_JOB_NAME) + @Qualifier(BatchConstants.PATIENT_BULK_EXPORT_JOB_NAME) private Job myPatientBulkJob; private IIdType myPatientGroupId; @@ -328,11 +328,11 @@ public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test { private void awaitAllBulkJobCompletions() { myBatchJobHelper.awaitAllBulkJobCompletions( - BatchJobsConfig.BULK_EXPORT_JOB_NAME, - BatchJobsConfig.PATIENT_BULK_EXPORT_JOB_NAME, - BatchJobsConfig.GROUP_BULK_EXPORT_JOB_NAME, - BatchJobsConfig.DELETE_EXPUNGE_JOB_NAME, - BatchJobsConfig.MDM_CLEAR_JOB_NAME + BatchConstants.BULK_EXPORT_JOB_NAME, + BatchConstants.PATIENT_BULK_EXPORT_JOB_NAME, + BatchConstants.GROUP_BULK_EXPORT_JOB_NAME, + BatchConstants.DELETE_EXPUNGE_JOB_NAME, + BatchConstants.MDM_CLEAR_JOB_NAME ); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java index e34f63b3985..3eeb2fbea3c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/imprt/svc/BulkDataImportR4Test.java @@ -5,7 +5,7 @@ import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IAnonymousInterceptor; import ca.uhn.fhir.interceptor.api.Interceptor; import ca.uhn.fhir.interceptor.api.Pointcut; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc; import ca.uhn.fhir.jpa.bulk.imprt.model.BulkImportJobFileJson; @@ -44,7 +44,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import static ca.uhn.fhir.jpa.batch.BatchJobsConfig.BULK_IMPORT_JOB_NAME; +import static ca.uhn.fhir.jpa.batch.config.BatchConstants.BULK_IMPORT_JOB_NAME; import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -212,7 +212,7 @@ public class BulkDataImportR4Test extends BaseJpaR4Test implements ITestDataBuil } protected List awaitAllBulkImportJobCompletion() { - return myBatchJobHelper.awaitAllBulkJobCompletions(BatchJobsConfig.BULK_IMPORT_JOB_NAME); + return myBatchJobHelper.awaitAllBulkJobCompletions(BatchConstants.BULK_IMPORT_JOB_NAME); } @Interceptor diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java index 86220f8281d..23a9385d684 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java @@ -1451,9 +1451,9 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { id1b = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - TestUtil.sleepAtLeast(1100); + ca.uhn.fhir.util.TestUtil.sleepAtLeast(1100); DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); - TestUtil.sleepAtLeast(1100); + ca.uhn.fhir.util.TestUtil.sleepAtLeast(1100); IIdType id2; { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java index 2ea2fac62a0..64c22c667d6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java @@ -6,11 +6,11 @@ import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.util.StopWatch; +import ca.uhn.fhir.util.TestUtil; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.time.DateUtils; import org.hl7.fhir.instance.model.api.IIdType; @@ -116,7 +116,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { } assertEquals(searchUuid1, searchUuid2); - TestUtil.sleepAtLeast(reuseCachedSearchResultsForMillis + 1); + ca.uhn.fhir.util.TestUtil.sleepAtLeast(reuseCachedSearchResultsForMillis + 1); // We're now past reuseCachedSearchResultsForMillis so we shouldn't reuse the search @@ -291,7 +291,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { } assertEquals(searchUuid1, searchUuid2); - TestUtil.sleepAtLeast(reuseCachedSearchResultsForMillis + 1); + ca.uhn.fhir.util.TestUtil.sleepAtLeast(reuseCachedSearchResultsForMillis + 1); myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem(); // We're now past reuseCachedSearchResultsForMillis so we shouldn't reuse the search @@ -376,7 +376,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { } }); if (search == null) { - TestUtil.sleepAtLeast(100); + ca.uhn.fhir.util.TestUtil.sleepAtLeast(100); } } assertNotNull(search, "Search " + bundleProvider.getUuid() + " not found on disk after 10 seconds"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/JpaHistoryR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/JpaHistoryR4Test.java index 8c9ec09fda1..096e37a461b 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/JpaHistoryR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/JpaHistoryR4Test.java @@ -22,7 +22,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; +import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java index 150e795a5be..24bb7903c64 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java @@ -72,7 +72,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.stream.Collectors; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; +import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; import static org.apache.commons.lang3.StringUtils.countMatches; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobTest.java index 442102c0973..3931f4abb62 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/DeleteExpungeJobTest.java @@ -1,7 +1,7 @@ package ca.uhn.fhir.jpa.delete.job; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.MultiUrlJobParameterUtil; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; @@ -23,7 +23,7 @@ public class DeleteExpungeJobTest extends BaseJpaR4Test { @Autowired private IBatchJobSubmitter myBatchJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.DELETE_EXPUNGE_JOB_NAME) + @Qualifier(BatchConstants.DELETE_EXPUNGE_JOB_NAME) private Job myDeleteExpungeJob; @Autowired private BatchJobHelper myBatchJobHelper; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/ReindexJobTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/ReindexJobTest.java index 61018ef82b1..8df82b52b93 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/ReindexJobTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/delete/job/ReindexJobTest.java @@ -1,8 +1,8 @@ package ca.uhn.fhir.jpa.delete.job; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; import ca.uhn.fhir.jpa.batch.CommonBatchJobConfig; import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.batch.job.MultiUrlJobParameterUtil; import ca.uhn.fhir.jpa.batch.reader.CronologicalBatchAllResourcePidReader; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; @@ -37,10 +37,10 @@ public class ReindexJobTest extends BaseJpaR4Test { @Autowired private IBatchJobSubmitter myBatchJobSubmitter; @Autowired - @Qualifier(BatchJobsConfig.REINDEX_JOB_NAME) + @Qualifier(BatchConstants.REINDEX_JOB_NAME) private Job myReindexJob; @Autowired - @Qualifier(BatchJobsConfig.REINDEX_EVERYTHING_JOB_NAME) + @Qualifier(BatchConstants.REINDEX_EVERYTHING_JOB_NAME) private Job myReindexEverythingJob; @Autowired private BatchJobHelper myBatchJobHelper; diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ArbitrarySqlTaskTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ArbitrarySqlTaskTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ArbitrarySqlTaskTest.java rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ArbitrarySqlTaskTest.java diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java new file mode 100644 index 00000000000..878cc32cdbf --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java @@ -0,0 +1,161 @@ +package ca.uhn.fhir.jpa.migrate.taskdef; + +import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; +import ca.uhn.fhir.jpa.migrate.FlywayMigrator; +import ca.uhn.fhir.jpa.migrate.JdbcUtils; +import ca.uhn.fhir.jpa.migrate.SchemaMigrator; +import org.apache.commons.dbcp2.BasicDataSource; +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.AfterEach; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.ColumnMapRowMapper; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Stream; + +// TODO KHS copied from hapi-fhir-sql-migrate +public abstract class BaseTest { + + private static final String DATABASE_NAME = "DATABASE"; + private static final Logger ourLog = LoggerFactory.getLogger(BaseTest.class); + private static int ourDatabaseUrl = 0; + private BasicDataSource myDataSource; + private String myUrl; + private FlywayMigrator myMigrator; + private DriverTypeEnum.ConnectionProperties myConnectionProperties; + + public static Stream> data() { + ourLog.info("H2: {}", org.h2.Driver.class.toString()); + + ArrayList> retVal = new ArrayList<>(); + + // H2 + retVal.add(new Supplier() { + @Override + public TestDatabaseDetails get() { + String url = "jdbc:h2:mem:" + DATABASE_NAME + ourDatabaseUrl++; + DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.H2_EMBEDDED.newConnectionProperties(url, "SA", "SA"); + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl(url); + dataSource.setUsername("SA"); + dataSource.setPassword("SA"); + dataSource.setDriverClassName(DriverTypeEnum.H2_EMBEDDED.getDriverClassName()); + FlywayMigrator migrator = new FlywayMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, DriverTypeEnum.H2_EMBEDDED); + return new TestDatabaseDetails(url, connectionProperties, dataSource, migrator); + } + + @Override + public String toString() { + return "H2"; + } + }); + + // Derby + retVal.add(new Supplier() { + @Override + public TestDatabaseDetails get() { + String url = "jdbc:derby:memory:" + DATABASE_NAME + ourDatabaseUrl++ + ";create=true"; + DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.DERBY_EMBEDDED.newConnectionProperties(url, "SA", "SA"); + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl(url); + dataSource.setUsername("SA"); + dataSource.setPassword("SA"); + dataSource.setDriverClassName(DriverTypeEnum.DERBY_EMBEDDED.getDriverClassName()); + FlywayMigrator migrator = new FlywayMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, DriverTypeEnum.DERBY_EMBEDDED); + return new TestDatabaseDetails(url, connectionProperties, dataSource, migrator); + } + + @Override + public String toString() { + return "Derby"; + } + }); + + return retVal.stream(); + } + + public void before(Supplier theTestDatabaseDetails) { + TestDatabaseDetails testDatabaseDetails = theTestDatabaseDetails.get(); + myUrl = testDatabaseDetails.myUrl; + myConnectionProperties = testDatabaseDetails.myConnectionProperties; + myDataSource = testDatabaseDetails.myDataSource; + myMigrator = testDatabaseDetails.myMigrator; + } + + public String getUrl() { + return myUrl; + } + + public DriverTypeEnum.ConnectionProperties getConnectionProperties() { + return myConnectionProperties; + } + + protected BasicDataSource getDataSource() { + return myDataSource; + } + + @AfterEach + public void resetMigrationVersion() throws SQLException { + if (getConnectionProperties() != null) { + Set tableNames = JdbcUtils.getTableNames(getConnectionProperties()); + if (tableNames.contains(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME)) { + executeSql("DELETE from " + SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME + " where \"installed_rank\" > 0"); + } + } + } + + protected void executeSql(@Language("SQL") String theSql, Object... theArgs) { + myConnectionProperties.getTxTemplate().execute(t -> { + myConnectionProperties.newJdbcTemplate().update(theSql, theArgs); + return null; + }); + } + + protected List> executeQuery(@Language("SQL") String theSql, Object... theArgs) { + return myConnectionProperties.getTxTemplate().execute(t -> { + return myConnectionProperties.newJdbcTemplate().query(theSql, theArgs, new ColumnMapRowMapper()); + }); + } + + public FlywayMigrator getMigrator() { + return myMigrator; + } + + @AfterEach + public void after() { + if (myConnectionProperties != null) { + myConnectionProperties.close(); + } + } + + protected DriverTypeEnum getDriverType() { + return myConnectionProperties.getDriverType(); + } + + public static class TestDatabaseDetails { + + private final String myUrl; + private final DriverTypeEnum.ConnectionProperties myConnectionProperties; + private final BasicDataSource myDataSource; + private final FlywayMigrator myMigrator; + + public TestDatabaseDetails(String theUrl, DriverTypeEnum.ConnectionProperties theConnectionProperties, BasicDataSource theDataSource, FlywayMigrator theMigrator) { + myUrl = theUrl; + myConnectionProperties = theConnectionProperties; + myDataSource = theDataSource; + myMigrator = theMigrator; + } + + public DriverTypeEnum getDriverType() { + return myConnectionProperties.getDriverType(); + } + + } + +} diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTest.java rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/HashTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/HashTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/HashTest.java rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/HashTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasksTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasksTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasksTest.java rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasksTest.java diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/MultitenantBatchOperationR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/MultitenantBatchOperationR4Test.java index 652ceff7947..2ce148054ac 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/MultitenantBatchOperationR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/MultitenantBatchOperationR4Test.java @@ -7,7 +7,7 @@ import ca.uhn.fhir.interceptor.api.IPointcut; import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.delete.job.ReindexTestHelper; import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.server.RequestDetails; @@ -91,7 +91,7 @@ public class MultitenantBatchOperationR4Test extends BaseMultitenantResourceProv .execute(); ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(response)); - myBatchJobHelper.awaitAllBulkJobCompletions(BatchJobsConfig.DELETE_EXPUNGE_JOB_NAME); + myBatchJobHelper.awaitAllBulkJobCompletions(BatchConstants.DELETE_EXPUNGE_JOB_NAME); assertThat(interceptor.requestPartitionIds, hasSize(1)); RequestPartitionId partitionId = interceptor.requestPartitionIds.get(0); assertEquals(TENANT_B_ID, partitionId.getFirstPartitionIdOrNull()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java index 9e9978072e9..98fbd540de1 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java @@ -1,56 +1,47 @@ package ca.uhn.fhir.jpa.provider.r4; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick; -import static org.apache.commons.lang3.StringUtils.isNotBlank; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.containsInRelativeOrder; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.emptyString; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.in; -import static org.hamcrest.Matchers.lessThan; -import static org.hamcrest.Matchers.lessThanOrEqualTo; -import static org.hamcrest.Matchers.matchesPattern; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.Matchers.stringContainsInOrder; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.math.BigDecimal; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.stream.Collectors; - -import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; +import ca.uhn.fhir.jpa.api.config.DaoConfig; +import ca.uhn.fhir.jpa.config.TestR4Config; +import ca.uhn.fhir.jpa.dao.data.ISearchDao; +import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; -import ca.uhn.fhir.util.BundleBuilder; +import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; +import ca.uhn.fhir.jpa.model.util.JpaConstants; +import ca.uhn.fhir.jpa.model.util.UcumServiceUtil; +import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; +import ca.uhn.fhir.model.api.TemporalPrecisionEnum; +import ca.uhn.fhir.model.primitive.InstantDt; +import ca.uhn.fhir.model.primitive.UriDt; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.parser.StrictErrorHandler; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.PreferReturnEnum; +import ca.uhn.fhir.rest.api.SearchTotalModeEnum; +import ca.uhn.fhir.rest.api.SummaryEnum; +import ca.uhn.fhir.rest.client.apache.ResourceEntity; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; +import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor; +import ca.uhn.fhir.rest.gclient.StringClientParam; +import ca.uhn.fhir.rest.param.DateRangeParam; +import ca.uhn.fhir.rest.param.NumberParam; +import ca.uhn.fhir.rest.param.ParamPrefixEnum; +import ca.uhn.fhir.rest.param.StringAndListParam; +import ca.uhn.fhir.rest.param.StringOrListParam; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; +import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; +import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; +import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; +import ca.uhn.fhir.util.StopWatch; +import ca.uhn.fhir.util.UrlUtil; +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; @@ -151,49 +142,52 @@ import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import com.google.common.base.Charsets; -import com.google.common.collect.Lists; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; -import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.config.TestR4Config; -import ca.uhn.fhir.jpa.dao.data.ISearchDao; -import ca.uhn.fhir.jpa.entity.Search; -import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; -import ca.uhn.fhir.jpa.model.util.JpaConstants; -import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; -import ca.uhn.fhir.jpa.util.SqlQuery; -import ca.uhn.fhir.model.api.TemporalPrecisionEnum; -import ca.uhn.fhir.model.primitive.InstantDt; -import ca.uhn.fhir.model.primitive.UriDt; -import ca.uhn.fhir.parser.IParser; -import ca.uhn.fhir.parser.StrictErrorHandler; -import ca.uhn.fhir.rest.api.Constants; -import ca.uhn.fhir.rest.api.MethodOutcome; -import ca.uhn.fhir.rest.api.PreferReturnEnum; -import ca.uhn.fhir.rest.api.SearchTotalModeEnum; -import ca.uhn.fhir.rest.api.SummaryEnum; -import ca.uhn.fhir.rest.client.apache.ResourceEntity; -import ca.uhn.fhir.rest.client.api.IClientInterceptor; -import ca.uhn.fhir.rest.client.api.IGenericClient; -import ca.uhn.fhir.rest.client.api.IHttpRequest; -import ca.uhn.fhir.rest.client.api.IHttpResponse; -import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor; -import ca.uhn.fhir.rest.gclient.StringClientParam; -import ca.uhn.fhir.rest.param.DateRangeParam; -import ca.uhn.fhir.rest.param.NumberParam; -import ca.uhn.fhir.rest.param.ParamPrefixEnum; -import ca.uhn.fhir.rest.param.StringAndListParam; -import ca.uhn.fhir.rest.param.StringOrListParam; -import ca.uhn.fhir.rest.param.StringParam; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; -import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; -import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; -import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; -import ca.uhn.fhir.util.StopWatch; -import ca.uhn.fhir.jpa.model.util.UcumServiceUtil; -import ca.uhn.fhir.util.UrlUtil; +import static ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick; +import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsInRelativeOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.emptyString; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.lessThan; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.Matchers.matchesPattern; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.stringContainsInOrder; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; @SuppressWarnings("Duplicates") public class ResourceProviderR4Test extends BaseResourceProviderR4Test { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java index 56cabaf802b..9ef68d4c799 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java @@ -26,7 +26,7 @@ import org.springframework.test.util.AopTestUtils; import java.util.Date; import java.util.UUID; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; +import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.blankOrNullString; import static org.hamcrest.Matchers.containsString; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java index 750953a8818..521397b0aab 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java @@ -4,7 +4,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.interceptor.api.Hook; import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.batch.BatchJobsConfig; +import ca.uhn.fhir.jpa.batch.config.BatchConstants; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test; import ca.uhn.fhir.jpa.rp.r4.BinaryResourceProvider; @@ -815,7 +815,7 @@ public class SystemProviderR4Test extends BaseJpaR4Test { .execute(); ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(response)); - myBatchJobHelper.awaitAllBulkJobCompletions(BatchJobsConfig.DELETE_EXPUNGE_JOB_NAME); + myBatchJobHelper.awaitAllBulkJobCompletions(BatchConstants.DELETE_EXPUNGE_JOB_NAME); Long jobId = BatchHelperR4.jobIdFromParameters(response); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/sched/SchedulerServiceImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/sched/SchedulerServiceImplTest.java index 323b20ec1a6..fd1bef5a951 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/sched/SchedulerServiceImplTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/sched/SchedulerServiceImplTest.java @@ -25,7 +25,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.util.AopTestUtils; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; +import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java index c6af09b5281..0e7d607bccb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java @@ -57,7 +57,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; +import static ca.uhn.fhir.util.TestUtil.sleepAtLeast; import static org.awaitility.Awaitility.await; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/BatchConstants.java b/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/BatchConstants.java deleted file mode 100644 index 4224e215332..00000000000 --- a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/BatchConstants.java +++ /dev/null @@ -1,32 +0,0 @@ -package ca.uhn.fhir.jpa.batch; - -/*- - * #%L - * HAPI FHIR JPA Server - Batch Task Processor - * %% - * Copyright (C) 2014 - 2021 Smile CDR, Inc. - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -public class BatchConstants { - - /** - * Non instantiable - */ - private BatchConstants() {} - - public static final String JOB_LAUNCHING_TASK_EXECUTOR = "jobLaunchingTaskExecutor"; - -} diff --git a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/InMemoryJobRepositoryBatchConfig.java b/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/InMemoryJobRepositoryBatchConfig.java deleted file mode 100644 index 57c28702fec..00000000000 --- a/hapi-fhir-jpaserver-batch/src/main/java/ca/uhn/fhir/jpa/batch/config/InMemoryJobRepositoryBatchConfig.java +++ /dev/null @@ -1,85 +0,0 @@ -package ca.uhn.fhir.jpa.batch.config; - -/*- - * #%L - * HAPI FHIR JPA Server - Batch Task Processor - * %% - * Copyright (C) 2014 - 2021 Smile CDR, Inc. - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import org.springframework.batch.core.configuration.annotation.BatchConfigurer; -import org.springframework.batch.core.explore.JobExplorer; -import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean; -import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.batch.core.launch.support.SimpleJobLauncher; -import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; -import org.springframework.batch.support.transaction.ResourcelessTransactionManager; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; - -import javax.annotation.PostConstruct; - -@Component -@Configuration -public class InMemoryJobRepositoryBatchConfig implements BatchConfigurer { - - private PlatformTransactionManager myPlatformTransactionManager; - private JobLauncher myJobLauncher; - private JobRepository myJobRepository; - private JobExplorer myJobExplorer; - - - @Override - public PlatformTransactionManager getTransactionManager() { - return myPlatformTransactionManager; - } - - @Override - public JobRepository getJobRepository() { - return myJobRepository; - } - - @Override - public JobLauncher getJobLauncher() { - return myJobLauncher; - } - - @Override - public JobExplorer getJobExplorer() { - return myJobExplorer; - } - - @PostConstruct - public void setup() throws Exception{ - if (myPlatformTransactionManager == null) { - myPlatformTransactionManager = new ResourcelessTransactionManager(); - } - MapJobRepositoryFactoryBean jobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(myPlatformTransactionManager); - jobRepositoryFactoryBean.afterPropertiesSet(); - myJobRepository = jobRepositoryFactoryBean.getObject(); - - MapJobExplorerFactoryBean jobExplorerFactoryBean = new MapJobExplorerFactoryBean(jobRepositoryFactoryBean); - jobExplorerFactoryBean.afterPropertiesSet(); - myJobExplorer = jobExplorerFactoryBean.getObject(); - - SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); - jobLauncher.setJobRepository(myJobRepository); - jobLauncher.afterPropertiesSet(); - myJobLauncher = jobLauncher; - } -} diff --git a/hapi-fhir-jpaserver-cql/pom.xml b/hapi-fhir-jpaserver-cql/pom.xml index d08c19cfdca..79b0f8682a9 100644 --- a/hapi-fhir-jpaserver-cql/pom.xml +++ b/hapi-fhir-jpaserver-cql/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index 0ebb48c99dd..22fa4dceb98 100644 --- a/hapi-fhir-jpaserver-mdm/pom.xml +++ b/hapi-fhir-jpaserver-mdm/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java index 7695be8f448..360aae8af76 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmMessageHandler.java @@ -48,8 +48,6 @@ import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import org.springframework.stereotype.Service; -import java.util.Optional; - @Service public class MdmMessageHandler implements MessageHandler { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmQueueConsumerLoader.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmQueueConsumerLoader.java index 385d8265392..90e7b5ef065 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmQueueConsumerLoader.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/broker/MdmQueueConsumerLoader.java @@ -1,11 +1,11 @@ package ca.uhn.fhir.jpa.mdm.broker; -import ca.uhn.fhir.mdm.api.IMdmSettings; -import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.jpa.subscription.channel.api.ChannelConsumerSettings; import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory; import ca.uhn.fhir.jpa.subscription.channel.api.IChannelReceiver; import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage; +import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.log.Logs; import com.google.common.annotations.VisibleForTesting; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java index 912d39331ea..29ee64e5733 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmSubmitterInterceptorLoader.java @@ -20,12 +20,12 @@ package ca.uhn.fhir.jpa.mdm.interceptor; * #L% */ -import ca.uhn.fhir.jpa.interceptor.MdmSearchExpandingInterceptor; -import ca.uhn.fhir.mdm.api.IMdmSettings; -import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.interceptor.api.IInterceptorService; import ca.uhn.fhir.jpa.api.config.DaoConfig; +import ca.uhn.fhir.jpa.interceptor.MdmSearchExpandingInterceptor; import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionSubmitInterceptorLoader; +import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.log.Logs; import org.hl7.fhir.dstu2.model.Subscription; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java index 5533c82667b..fe360c39e9f 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByExampleSvc.java @@ -21,13 +21,13 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate; */ import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; +import ca.uhn.fhir.jpa.dao.index.IdHelperService; +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; import ca.uhn.fhir.mdm.api.IMdmMatchFinderSvc; import ca.uhn.fhir.mdm.api.MatchedTarget; +import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.log.Logs; -import ca.uhn.fhir.jpa.dao.index.IdHelperService; -import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; -import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByLinkSvc.java index 7214508d224..1e56299289c 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/FindCandidateByLinkSvc.java @@ -20,8 +20,8 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate; * #L% */ -import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import org.hl7.fhir.instance.model.api.IAnyResource; import org.slf4j.Logger; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmGoldenResourceFindingSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmGoldenResourceFindingSvc.java index d430525ee36..821b87712e9 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmGoldenResourceFindingSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/candidate/MdmGoldenResourceFindingSvc.java @@ -20,8 +20,8 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate; * #L% */ -import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc; +import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java deleted file mode 100644 index 0523592f4d2..00000000000 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java +++ /dev/null @@ -1,124 +0,0 @@ -package ca.uhn.fhir.jpa.migrate.taskdef; - -/*- - * #%L - * HAPI FHIR JPA Server - Migration - * %% - * Copyright (C) 2014 - 2021 Smile CDR, Inc. - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; - -import java.util.HashMap; -import java.util.Map; - -public class ColumnTypeToDriverTypeToSqlType { - Map> myColumnTypeToDriverTypeToSqlType = new HashMap<>(); - - public Map> getColumnTypeToDriverTypeToSqlType() { - return myColumnTypeToDriverTypeToSqlType; - } - - public ColumnTypeToDriverTypeToSqlType() { - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.H2_EMBEDDED, "integer"); - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.DERBY_EMBEDDED, "integer"); - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MARIADB_10_1, "integer"); - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MYSQL_5_7, "integer"); - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MSSQL_2012, "int"); - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.ORACLE_12C, "number(10,0)"); - setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.POSTGRES_9_4, "int4"); - - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.H2_EMBEDDED, "float"); - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.DERBY_EMBEDDED, "float"); - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MARIADB_10_1, "float"); - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MYSQL_5_7, "float"); - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MSSQL_2012, "float"); - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.ORACLE_12C, "float"); - setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.POSTGRES_9_4, "float"); - - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.H2_EMBEDDED, "double"); - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.DERBY_EMBEDDED, "double"); - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MARIADB_10_1, "double precision"); - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MYSQL_5_7, "double precision"); - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MSSQL_2012, "double precision"); - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.ORACLE_12C, "double precision"); - setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.POSTGRES_9_4, "float8"); - - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.H2_EMBEDDED, "bigint"); - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.DERBY_EMBEDDED, "bigint"); - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MARIADB_10_1, "bigint"); - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MYSQL_5_7, "bigint"); - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MSSQL_2012, "bigint"); - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.ORACLE_12C, "number(19,0)"); - setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.POSTGRES_9_4, "int8"); - - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.H2_EMBEDDED, "varchar(?)"); - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.DERBY_EMBEDDED, "varchar(?)"); - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MARIADB_10_1, "varchar(?)"); - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MYSQL_5_7, "varchar(?)"); - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MSSQL_2012, "varchar(?)"); - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.ORACLE_12C, "varchar2(?)"); - setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.POSTGRES_9_4, "varchar(?)"); - - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.H2_EMBEDDED, "timestamp"); - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.DERBY_EMBEDDED, "timestamp"); - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MARIADB_10_1, "datetime(6)"); - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MYSQL_5_7, "datetime(6)"); - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MSSQL_2012, "datetime2"); - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.ORACLE_12C, "timestamp"); - setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.POSTGRES_9_4, "timestamp"); - - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.H2_EMBEDDED, "date"); - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.DERBY_EMBEDDED, "date"); - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MARIADB_10_1, "date"); - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MYSQL_5_7, "date"); - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MSSQL_2012, "date"); - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.ORACLE_12C, "date"); - setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.POSTGRES_9_4, "date"); - - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.H2_EMBEDDED, "boolean"); - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.DERBY_EMBEDDED, "boolean"); - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MSSQL_2012, "bit"); - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MARIADB_10_1, "bit"); - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.ORACLE_12C, "number(1,0)"); - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.POSTGRES_9_4, "boolean"); - setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MYSQL_5_7, "bit"); - - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.H2_EMBEDDED, "blob"); - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.DERBY_EMBEDDED, "blob"); - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MARIADB_10_1, "longblob"); - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MYSQL_5_7, "longblob"); - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.ORACLE_12C, "blob"); - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.POSTGRES_9_4, "oid"); - setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MSSQL_2012, "varbinary(MAX)"); - - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.H2_EMBEDDED, "clob"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.DERBY_EMBEDDED, "clob(100000)"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MARIADB_10_1, "longtext"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MYSQL_5_7, "longtext"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.ORACLE_12C, "clob"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.POSTGRES_9_4, "text"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MSSQL_2012, "varchar(MAX)"); - } - - private void setColumnType(ColumnTypeEnum theColumnType, DriverTypeEnum theDriverType, String theColumnTypeSql) { - Map columnSqlType = myColumnTypeToDriverTypeToSqlType.computeIfAbsent(theColumnType, k -> new HashMap<>()); - if (columnSqlType.containsKey(theDriverType)) { - throw new IllegalStateException("Duplicate key: " + theDriverType); - } - columnSqlType.put(theDriverType, theColumnTypeSql); - } -} diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index d37223e4c57..075066b6827 100644 --- a/hapi-fhir-jpaserver-model/pom.xml +++ b/hapi-fhir-jpaserver-model/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -33,6 +33,11 @@ + + ca.uhn.hapi.fhir + hapi-fhir-jpa + ${project.version} + ca.uhn.hapi.fhir hapi-fhir-server @@ -66,24 +71,6 @@ org.hibernate hibernate-core - - - xml-apis - xml-apis - - - javax.activation - activation - - - javax.activation - javax.activation-api - - - javax.xml.bind - jaxb-api - - org.hibernate.search @@ -122,11 +109,6 @@ jscience - - org.apache.commons - commons-collections4 - - org.quartz-scheduler quartz diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 769c3156374..6a029def188 100755 --- a/hapi-fhir-jpaserver-searchparam/pom.xml +++ b/hapi-fhir-jpaserver-searchparam/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index e82047b9a84..1fb86ca9421 100644 --- a/hapi-fhir-jpaserver-subscription/pom.xml +++ b/hapi-fhir-jpaserver-subscription/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -22,7 +22,7 @@ ca.uhn.hapi.fhir - hapi-fhir-jpaserver-api + hapi-fhir-storage-api ${project.version} diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index ed0446ecb7c..4cbb297b273 100644 --- a/hapi-fhir-jpaserver-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 102099628b9..74a95489730 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index c4b363475e5..a152ba8887e 100644 --- a/hapi-fhir-server-mdm/pom.xml +++ b/hapi-fhir-server-mdm/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -27,6 +27,11 @@ hapi-fhir-server ${project.version} + + ca.uhn.hapi.fhir + hapi-fhir-storage-api + ${project.version} + org.springframework.data spring-data-commons diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml index a7a0f5b62e4..d4fae64c88b 100644 --- a/hapi-fhir-server-openapi/pom.xml +++ b/hapi-fhir-server-openapi/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index 9e939a8b842..56a785466bc 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -69,10 +69,6 @@ test - - org.apache.commons - commons-collections4 - org.springframework spring-messaging @@ -110,6 +106,10 @@ + + org.apache.commons + commons-collections4 + diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ProviderConstants.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ProviderConstants.java index f9296160b36..365393697ce 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ProviderConstants.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ProviderConstants.java @@ -170,4 +170,13 @@ public class ProviderConstants { * The Spring Batch job id of the delete expunge job created by a $delete-expunge operation */ public static final String OPERATION_REINDEX_RESPONSE_JOB_ID = "jobId"; + + @Deprecated + public static final String MARK_ALL_RESOURCES_FOR_REINDEXING = "$mark-all-resources-for-reindexing"; + /** + * @see ProviderConstants#OPERATION_REINDEX + * @deprecated + */ + @Deprecated + public static final String PERFORM_REINDEXING_PASS = "$perform-reindexing-pass"; } diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml index 53e0d08a968..3447508f8a1 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml index 1bc5de61f40..7e39b57ee6a 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT hapi-fhir-spring-boot-sample-client-apache diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml index 7e30b65d2b7..2bc8878adba 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT hapi-fhir-spring-boot-sample-client-okhttp diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml index a76318684c6..672ce4ae812 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT hapi-fhir-spring-boot-sample-server-jersey diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml index 4f824c60db2..86d5f76bf7d 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT hapi-fhir-spring-boot-samples diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml index d0d3f5e065f..ecf05d548c6 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index 04d9e96e88d..01db97a81f7 100644 --- a/hapi-fhir-spring-boot/pom.xml +++ b/hapi-fhir-spring-boot/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-jpaserver-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml similarity index 86% rename from hapi-fhir-jpaserver-migrate/pom.xml rename to hapi-fhir-sql-migrate/pom.xml index 6381faf35c4..e995ed778ee 100644 --- a/hapi-fhir-jpaserver-migrate/pom.xml +++ b/hapi-fhir-sql-migrate/pom.xml @@ -1,31 +1,25 @@ - + 4.0.0 ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml - hapi-fhir-jpaserver-migrate + hapi-fhir-sql-migrate jar - HAPI FHIR JPA Server - Migration + HAPI FHIR Server - SQL Migration + Tooling for migrating SQL schemas. mysql mysql-connector-java - - org.springframework spring-jdbc @@ -34,13 +28,15 @@ org.apache.commons commons-dbcp2 - - ca.uhn.hapi.fhir - hapi-fhir-jpaserver-base + hapi-fhir-base ${project.version} + + org.hibernate + hibernate-core + com.h2database diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java index 9991b57859d..18ed02ade1d 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/BaseMigrator.java @@ -32,9 +32,9 @@ import java.util.List; import java.util.Objects; public abstract class BaseMigrator implements IMigrator { + private final List myExecutedStatements = new ArrayList<>(); private boolean myDryRun; private boolean myNoColumnShrink; - private final List myExecutedStatements = new ArrayList<>(); private boolean mySchemaWasInitialized; private DriverTypeEnum myDriverType; private DataSource myDataSource; diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java index e3ffc87b834..89369665502 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/DriverTypeEnum.java @@ -67,6 +67,15 @@ public enum DriverTypeEnum { myDerby = theDerby; } + public static DriverTypeEnum fromDriverClassName(String theDriverClassName) { + for (DriverTypeEnum driverTypeEnum : DriverTypeEnum.values()) { + if (driverTypeEnum.myDriverClassName.equals(theDriverClassName)) { + return driverTypeEnum; + } + } + return null; + } + public String getDriverClassName() { return myDriverClassName; } @@ -99,18 +108,9 @@ public enum DriverTypeEnum { return retval; } - public static DriverTypeEnum fromDriverClassName(String theDriverClassName) { - for (DriverTypeEnum driverTypeEnum : DriverTypeEnum.values()) { - if (driverTypeEnum.myDriverClassName.equals(theDriverClassName)) { - return driverTypeEnum; - } - } - return null; - } - public ConnectionProperties newConnectionProperties(String theUrl, String theUsername, String thePassword) { - BasicDataSource dataSource = new BasicDataSource(){ + BasicDataSource dataSource = new BasicDataSource() { @Override public Connection getConnection() throws SQLException { ourLog.debug("Creating new DB connection"); diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java index 7889e45933e..176b97a1e06 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTask.java @@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.migrate; */ import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask; -import ca.uhn.fhir.jpa.migrate.taskdef.InitializeSchemaTask; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import org.flywaydb.core.api.MigrationVersion; import org.flywaydb.core.api.migration.Context; diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/IMigrator.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/IMigrator.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/IMigrator.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/IMigrator.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java similarity index 96% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java index fb4af862dd6..481cc6c770d 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java @@ -62,78 +62,9 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; -import static org.thymeleaf.util.StringUtils.toUpperCase; - public class JdbcUtils { private static final Logger ourLog = LoggerFactory.getLogger(JdbcUtils.class); - public static class ColumnType { - private final ColumnTypeEnum myColumnTypeEnum; - private final Long myLength; - - public ColumnType(ColumnTypeEnum theColumnType, Long theLength) { - myColumnTypeEnum = theColumnType; - myLength = theLength; - } - - public ColumnType(ColumnTypeEnum theColumnType, int theLength) { - this(theColumnType, (long) theLength); - } - - public ColumnType(ColumnTypeEnum theColumnType) { - this(theColumnType, null); - } - - @Override - public boolean equals(Object theO) { - if (this == theO) { - return true; - } - - if (theO == null || getClass() != theO.getClass()) { - return false; - } - - ColumnType that = (ColumnType) theO; - - return new EqualsBuilder() - .append(myColumnTypeEnum, that.myColumnTypeEnum) - .append(myLength, that.myLength) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(myColumnTypeEnum) - .append(myLength) - .toHashCode(); - } - - @Override - public String toString() { - ToStringBuilder b = new ToStringBuilder(this); - b.append("type", myColumnTypeEnum); - if (myLength != null) { - b.append("length", myLength); - } - return b.toString(); - } - - public ColumnTypeEnum getColumnTypeEnum() { - return myColumnTypeEnum; - } - - public Long getLength() { - return myLength; - } - - public boolean equals(ColumnTypeEnum theTaskColumnType, Long theTaskColumnLength) { - ourLog.debug("Comparing existing {} {} to new {} {}", myColumnTypeEnum, myLength, theTaskColumnType, theTaskColumnLength); - return myColumnTypeEnum == theTaskColumnType && (theTaskColumnLength == null || theTaskColumnLength.equals(myLength)); - } - } - /** * Retrieve all index names */ @@ -155,7 +86,7 @@ public class JdbcUtils { while (indexes.next()) { ourLog.debug("*** Next index: {}", new ColumnMapRowMapper().mapRow(indexes, 0)); String indexName = indexes.getString("INDEX_NAME"); - indexName = toUpperCase(indexName, Locale.US); + indexName = indexName.toUpperCase(Locale.US); indexNames.add(indexName); } @@ -163,7 +94,7 @@ public class JdbcUtils { while (indexes.next()) { ourLog.debug("*** Next index: {}", new ColumnMapRowMapper().mapRow(indexes, 0)); String indexName = indexes.getString("INDEX_NAME"); - indexName = toUpperCase(indexName, Locale.US); + indexName = indexName.toUpperCase(Locale.US); indexNames.add(indexName); } @@ -226,11 +157,11 @@ public class JdbcUtils { while (indexes.next()) { - String tableName = toUpperCase(indexes.getString("TABLE_NAME"), Locale.US); + String tableName = indexes.getString("TABLE_NAME").toUpperCase(Locale.US); if (!theTableName.equalsIgnoreCase(tableName)) { continue; } - String columnName = toUpperCase(indexes.getString("COLUMN_NAME"), Locale.US); + String columnName = indexes.getString("COLUMN_NAME").toUpperCase(Locale.US); if (!theColumnName.equalsIgnoreCase(columnName)) { continue; } @@ -308,7 +239,7 @@ public class JdbcUtils { while (indexes.next()) { String fkName = indexes.getString("FK_NAME"); - fkName = toUpperCase(fkName, Locale.US); + fkName = fkName.toUpperCase(Locale.US); fkNames.add(fkName); } } @@ -348,7 +279,7 @@ public class JdbcUtils { while (indexes.next()) { if (theForeignKeyColumn.equals(indexes.getString("FKCOLUMN_NAME"))) { String fkName = indexes.getString("FK_NAME"); - fkName = toUpperCase(fkName, Locale.US); + fkName = fkName.toUpperCase(Locale.US); fkNames.add(fkName); } } @@ -376,13 +307,13 @@ public class JdbcUtils { Set columnNames = new HashSet<>(); while (indexes.next()) { - String tableName = toUpperCase(indexes.getString("TABLE_NAME"), Locale.US); + String tableName = indexes.getString("TABLE_NAME").toUpperCase(Locale.US); if (!theTableName.equalsIgnoreCase(tableName)) { continue; } String columnName = indexes.getString("COLUMN_NAME"); - columnName = toUpperCase(columnName, Locale.US); + columnName = columnName.toUpperCase(Locale.US); columnNames.add(columnName); } @@ -499,7 +430,7 @@ public class JdbcUtils { Set columnNames = new HashSet<>(); while (tables.next()) { String tableName = tables.getString("TABLE_NAME"); - tableName = toUpperCase(tableName, Locale.US); + tableName = tableName.toUpperCase(Locale.US); String tableType = tables.getString("TABLE_TYPE"); if ("SYSTEM TABLE".equalsIgnoreCase(tableType)) { @@ -531,7 +462,7 @@ public class JdbcUtils { ResultSet tables = metadata.getColumns(connection.getCatalog(), connection.getSchema(), massageIdentifier(metadata, theTableName), null); while (tables.next()) { - String tableName = toUpperCase(tables.getString("TABLE_NAME"), Locale.US); + String tableName = tables.getString("TABLE_NAME").toUpperCase(Locale.US); if (!theTableName.equalsIgnoreCase(tableName)) { continue; } @@ -567,4 +498,71 @@ public class JdbcUtils { } return retVal; } + + public static class ColumnType { + private final ColumnTypeEnum myColumnTypeEnum; + private final Long myLength; + + public ColumnType(ColumnTypeEnum theColumnType, Long theLength) { + myColumnTypeEnum = theColumnType; + myLength = theLength; + } + + public ColumnType(ColumnTypeEnum theColumnType, int theLength) { + this(theColumnType, (long) theLength); + } + + public ColumnType(ColumnTypeEnum theColumnType) { + this(theColumnType, null); + } + + @Override + public boolean equals(Object theO) { + if (this == theO) { + return true; + } + + if (theO == null || getClass() != theO.getClass()) { + return false; + } + + ColumnType that = (ColumnType) theO; + + return new EqualsBuilder() + .append(myColumnTypeEnum, that.myColumnTypeEnum) + .append(myLength, that.myLength) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(myColumnTypeEnum) + .append(myLength) + .toHashCode(); + } + + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this); + b.append("type", myColumnTypeEnum); + if (myLength != null) { + b.append("length", myLength); + } + return b.toString(); + } + + public ColumnTypeEnum getColumnTypeEnum() { + return myColumnTypeEnum; + } + + public Long getLength() { + return myLength; + } + + public boolean equals(ColumnTypeEnum theTaskColumnType, Long theTaskColumnLength) { + ourLog.debug("Comparing existing {} {} to new {} {}", myColumnTypeEnum, myLength, theTaskColumnType, theTaskColumnLength); + return myColumnTypeEnum == theTaskColumnType && (theTaskColumnLength == null || theTaskColumnLength.equals(myLength)); + } + } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipper.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipper.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipper.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipper.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/Migrator.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/Migrator.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/Migrator.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/Migrator.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/SchemaMigrator.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/SchemaMigrator.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/SchemaMigrator.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/SchemaMigrator.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java similarity index 95% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java index c00aa23e008..99e199d46a8 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTask.java @@ -27,7 +27,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.thymeleaf.util.StringUtils; import javax.annotation.Nonnull; import java.sql.SQLException; @@ -50,7 +49,7 @@ public class AddIndexTask extends BaseTableTask { } public void setIndexName(String theIndexName) { - myIndexName = StringUtils.toUpperCase(theIndexName, Locale.US); + myIndexName = theIndexName.toUpperCase(Locale.US); } public void setColumns(List theColumns) { @@ -104,7 +103,7 @@ public class AddIndexTask extends BaseTableTask { switch (getDriverType()) { case POSTGRES_9_4: case MSSQL_2012: - includeClause = " INCLUDE (" + StringUtils.join(myIncludeColumns, ", ") + ")"; + includeClause = " INCLUDE (" + String.join(", ", myIncludeColumns) + ")"; break; case H2_EMBEDDED: case DERBY_EMBEDDED: @@ -119,7 +118,7 @@ public class AddIndexTask extends BaseTableTask { } if (myUnique && getDriverType() == DriverTypeEnum.MSSQL_2012) { mssqlWhereClause = " WHERE ("; - for (int i = 0; i 0); } } - - private static class TableAndColumn { - private final String myTable; - private final String myColumn; - - private TableAndColumn(String theTable, String theColumn) { - myTable = theTable; - myColumn = theColumn; - } - - public String getTable() { - return myTable; - } - - public String getColumn() { - return myColumn; - } - } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java index 4bacbc4eef6..4a5163cb398 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseColumnCalculatorTask.java @@ -211,40 +211,6 @@ public abstract class BaseColumnCalculatorTask extends BaseTableColumnTask { return myExecutor.submit(task); } - private class MyRowCallbackHandler implements RowCallbackHandler { - - private List> myRows = new ArrayList<>(); - private List> myFutures = new ArrayList<>(); - - @Override - public void processRow(ResultSet rs) throws SQLException { - Map row = new ColumnMapRowMapper().mapRow(rs, 0); - myRows.add(row); - - if (myRows.size() >= myBatchSize) { - submitNext(); - } - } - - private void submitNext() { - if (myRows.size() > 0) { - myFutures.add(updateRows(myRows)); - myRows = new ArrayList<>(); - } - } - - public List> getFutures() { - return myFutures; - } - - public void done() { - if (myRows.size() > 0) { - submitNext(); - } - } - } - - public static class MandatoryKeyMap extends ForwardingMap { private final Map myWrap; @@ -282,4 +248,37 @@ public abstract class BaseColumnCalculatorTask extends BaseTableColumnTask { return getString("SP_NAME"); } } + + private class MyRowCallbackHandler implements RowCallbackHandler { + + private List> myRows = new ArrayList<>(); + private List> myFutures = new ArrayList<>(); + + @Override + public void processRow(ResultSet rs) throws SQLException { + Map row = new ColumnMapRowMapper().mapRow(rs, 0); + myRows.add(row); + + if (myRows.size() >= myBatchSize) { + submitNext(); + } + } + + private void submitNext() { + if (myRows.size() > 0) { + myFutures.add(updateRows(myRows)); + myRows = new ArrayList<>(); + } + } + + public List> getFutures() { + return myFutures; + } + + public void done() { + if (myRows.size() > 0) { + submitNext(); + } + } + } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java similarity index 95% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java index c598f7a8a6d..8c7fb6050d9 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTask.java @@ -23,10 +23,8 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.thymeleaf.util.StringUtils; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.function.Function; @@ -41,18 +39,15 @@ public abstract class BaseTableColumnTask extends BaseTableTask { super(theProductVersion, theSchemaVersion); } - public BaseTableColumnTask setColumnName(String theColumnName) { - myColumnName = StringUtils.toUpperCase(theColumnName, Locale.US); - return this; - } - public String getColumnName() { return myColumnName; } - protected void setWhereClause(String theWhereClause) { - this.myWhereClause = theWhereClause; + public BaseTableColumnTask setColumnName(String theColumnName) { + myColumnName = theColumnName.toUpperCase(); + return this; } + protected String getWhereClause() { if (myWhereClause == null) { return getColumnName() + " IS NULL"; @@ -61,6 +56,10 @@ public abstract class BaseTableColumnTask extends BaseTableTask { } } + protected void setWhereClause(String theWhereClause) { + this.myWhereClause = theWhereClause; + } + @Override public void validate() { super.validate(); diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java index 59c0b153852..ee198c50101 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableTask.java @@ -31,7 +31,6 @@ public abstract class BaseTableTask extends BaseTask { private String myTableName; - public BaseTableTask(String theProductVersion, String theSchemaVersion) { super(theProductVersion, theSchemaVersion); } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java similarity index 74% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java index f2f05a71a3f..9bbf22ca633 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateHashesTask.java @@ -21,22 +21,10 @@ package ca.uhn.fhir.jpa.migrate.taskdef; */ import ca.uhn.fhir.jpa.migrate.JdbcUtils; -import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.VersionEnum; -import com.google.common.collect.ForwardingMap; -import org.apache.commons.lang3.Validate; -import org.apache.commons.lang3.concurrent.BasicThreadFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.jdbc.core.ColumnMapRowMapper; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowCallbackHandler; -import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.Function; +import java.util.Set; public class CalculateHashesTask extends BaseColumnCalculatorTask { @@ -59,8 +47,8 @@ public class CalculateHashesTask extends BaseColumnCalculatorTask { if (shouldSkip) { logInfo(ourLog, "The table HFJ_RES_REINDEX_JOB already exists. Skipping calculate hashes task."); } - return shouldSkip; - } catch (SQLException e) { + return shouldSkip; + } catch (SQLException e) { logInfo(ourLog, "Error retrieving table names, skipping task"); return true; } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/CalculateOrdinalDatesTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeEnum.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeEnum.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeEnum.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeEnum.java diff --git a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java new file mode 100644 index 00000000000..3c24d5a281c --- /dev/null +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java @@ -0,0 +1,124 @@ +package ca.uhn.fhir.jpa.migrate.taskdef; + +/*- + * #%L + * HAPI FHIR JPA Server - Migration + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; + +import java.util.HashMap; +import java.util.Map; + +public class ColumnTypeToDriverTypeToSqlType { + Map> myColumnTypeToDriverTypeToSqlType = new HashMap<>(); + + public ColumnTypeToDriverTypeToSqlType() { + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.H2_EMBEDDED, "integer"); + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.DERBY_EMBEDDED, "integer"); + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MARIADB_10_1, "integer"); + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MYSQL_5_7, "integer"); + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MSSQL_2012, "int"); + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.ORACLE_12C, "number(10,0)"); + setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.POSTGRES_9_4, "int4"); + + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.H2_EMBEDDED, "float"); + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.DERBY_EMBEDDED, "float"); + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MARIADB_10_1, "float"); + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MYSQL_5_7, "float"); + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MSSQL_2012, "float"); + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.ORACLE_12C, "float"); + setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.POSTGRES_9_4, "float"); + + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.H2_EMBEDDED, "double"); + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.DERBY_EMBEDDED, "double"); + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MARIADB_10_1, "double precision"); + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MYSQL_5_7, "double precision"); + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MSSQL_2012, "double precision"); + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.ORACLE_12C, "double precision"); + setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.POSTGRES_9_4, "float8"); + + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.H2_EMBEDDED, "bigint"); + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.DERBY_EMBEDDED, "bigint"); + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MARIADB_10_1, "bigint"); + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MYSQL_5_7, "bigint"); + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MSSQL_2012, "bigint"); + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.ORACLE_12C, "number(19,0)"); + setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.POSTGRES_9_4, "int8"); + + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.H2_EMBEDDED, "varchar(?)"); + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.DERBY_EMBEDDED, "varchar(?)"); + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MARIADB_10_1, "varchar(?)"); + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MYSQL_5_7, "varchar(?)"); + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MSSQL_2012, "varchar(?)"); + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.ORACLE_12C, "varchar2(?)"); + setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.POSTGRES_9_4, "varchar(?)"); + + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.H2_EMBEDDED, "timestamp"); + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.DERBY_EMBEDDED, "timestamp"); + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MARIADB_10_1, "datetime(6)"); + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MYSQL_5_7, "datetime(6)"); + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MSSQL_2012, "datetime2"); + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.ORACLE_12C, "timestamp"); + setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.POSTGRES_9_4, "timestamp"); + + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.H2_EMBEDDED, "date"); + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.DERBY_EMBEDDED, "date"); + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MARIADB_10_1, "date"); + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MYSQL_5_7, "date"); + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MSSQL_2012, "date"); + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.ORACLE_12C, "date"); + setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.POSTGRES_9_4, "date"); + + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.H2_EMBEDDED, "boolean"); + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.DERBY_EMBEDDED, "boolean"); + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MSSQL_2012, "bit"); + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MARIADB_10_1, "bit"); + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.ORACLE_12C, "number(1,0)"); + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.POSTGRES_9_4, "boolean"); + setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MYSQL_5_7, "bit"); + + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.H2_EMBEDDED, "blob"); + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.DERBY_EMBEDDED, "blob"); + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MARIADB_10_1, "longblob"); + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MYSQL_5_7, "longblob"); + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.ORACLE_12C, "blob"); + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.POSTGRES_9_4, "oid"); + setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MSSQL_2012, "varbinary(MAX)"); + + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.H2_EMBEDDED, "clob"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.DERBY_EMBEDDED, "clob(100000)"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MARIADB_10_1, "longtext"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MYSQL_5_7, "longtext"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.ORACLE_12C, "clob"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.POSTGRES_9_4, "text"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MSSQL_2012, "varchar(MAX)"); + } + + public Map> getColumnTypeToDriverTypeToSqlType() { + return myColumnTypeToDriverTypeToSqlType; + } + + private void setColumnType(ColumnTypeEnum theColumnType, DriverTypeEnum theDriverType, String theColumnTypeSql) { + Map columnSqlType = myColumnTypeToDriverTypeToSqlType.computeIfAbsent(theColumnType, k -> new HashMap<>()); + if (columnSqlType.containsKey(theDriverType)) { + throw new IllegalStateException("Duplicate key: " + theDriverType); + } + columnSqlType.put(theDriverType, theColumnTypeSql); + } +} diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java similarity index 89% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java index eb1072fbf8e..3989e420920 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTask.java @@ -26,7 +26,6 @@ import org.intellij.lang.annotations.Language; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.Driver; import java.sql.SQLException; import java.util.List; import java.util.Set; @@ -39,6 +38,11 @@ public class DropColumnTask extends BaseTableColumnTask { super(theProductVersion, theSchemaVersion); } + @Language("SQL") + static String createSql(String theTableName, String theColumnName) { + return "alter table " + theTableName + " drop column " + theColumnName; + } + @Override public void validate() { super.validate(); @@ -53,15 +57,15 @@ public class DropColumnTask extends BaseTableColumnTask { return; } - if(getDriverType().equals(DriverTypeEnum.MYSQL_5_7) || getDriverType().equals(DriverTypeEnum.MARIADB_10_1) - || getDriverType().equals(DriverTypeEnum.MSSQL_2012)) { + if (getDriverType().equals(DriverTypeEnum.MYSQL_5_7) || getDriverType().equals(DriverTypeEnum.MARIADB_10_1) + || getDriverType().equals(DriverTypeEnum.MSSQL_2012)) { // Some DBs such as MYSQL and Maria DB require that foreign keys depending on the column be dropped before the column itself is dropped. logInfo(ourLog, "Dropping any foreign keys on table {} depending on column {}", getTableName(), getColumnName()); Set foreignKeys = JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), getColumnName(), getTableName()); - if(foreignKeys != null) { - for (String foreignKey:foreignKeys) { + if (foreignKeys != null) { + for (String foreignKey : foreignKeys) { List dropFkSqls = DropForeignKeyTask.generateSql(getTableName(), foreignKey, getDriverType()); - for(String dropFkSql : dropFkSqls) { + for (String dropFkSql : dropFkSqls) { executeSql(getTableName(), dropFkSql); } } @@ -75,10 +79,5 @@ public class DropColumnTask extends BaseTableColumnTask { executeSql(getTableName(), sql); } - @Language("SQL") - static String createSql(String theTableName, String theColumnName) { - return "alter table " + theTableName + " drop column " + theColumnName; - } - } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java index a756b611984..dbabb523e3c 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTask.java @@ -46,6 +46,28 @@ public class DropForeignKeyTask extends BaseTableTask { super(theProductVersion, theSchemaVersion); } + @Nonnull + static List generateSql(String theTableName, String theConstraintName, DriverTypeEnum theDriverType) { + List sqls = new ArrayList<>(); + switch (theDriverType) { + case MYSQL_5_7: + case MARIADB_10_1: + // Lousy MYQL.... + sqls.add("alter table " + theTableName + " drop foreign key " + theConstraintName); + break; + case POSTGRES_9_4: + case DERBY_EMBEDDED: + case H2_EMBEDDED: + case ORACLE_12C: + case MSSQL_2012: + sqls.add("alter table " + theTableName + " drop constraint " + theConstraintName); + break; + default: + throw new IllegalStateException(); + } + return sqls; + } + public void setConstraintName(String theConstraintName) { myConstraintName = theConstraintName; } @@ -95,26 +117,4 @@ public class DropForeignKeyTask extends BaseTableTask { theBuilder.append(myConstraintName); theBuilder.append(myParentTableName); } - - @Nonnull - static List generateSql(String theTableName, String theConstraintName, DriverTypeEnum theDriverType) { - List sqls = new ArrayList<>(); - switch (theDriverType) { - case MYSQL_5_7: - case MARIADB_10_1: - // Lousy MYQL.... - sqls.add("alter table " + theTableName + " drop foreign key " + theConstraintName); - break; - case POSTGRES_9_4: - case DERBY_EMBEDDED: - case H2_EMBEDDED: - case ORACLE_12C: - case MSSQL_2012: - sqls.add("alter table " + theTableName + " drop constraint " + theConstraintName); - break; - default: - throw new IllegalStateException(); - } - return sqls; - } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java index f8cd1ddc5be..17634257e17 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java @@ -49,6 +49,64 @@ public class DropIndexTask extends BaseTableTask { super(theProductVersion, theSchemaVersion); } + static List createDropIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theIndexName, DriverTypeEnum theDriverType) throws SQLException { + Validate.notBlank(theIndexName, "theIndexName must not be blank"); + Validate.notBlank(theTableName, "theTableName must not be blank"); + + if (!JdbcUtils.getIndexNames(theConnectionProperties, theTableName).contains(theIndexName)) { + return Collections.emptyList(); + } + + boolean isUnique = JdbcUtils.isIndexUnique(theConnectionProperties, theTableName, theIndexName); + + List sql = new ArrayList<>(); + + if (isUnique) { + // Drop constraint + switch (theDriverType) { + case MYSQL_5_7: + case MARIADB_10_1: + // Need to quote the index name as the word "PRIMARY" is reserved in MySQL + sql.add("alter table " + theTableName + " drop index `" + theIndexName + "`"); + break; + case H2_EMBEDDED: + sql.add("drop index " + theIndexName); + break; + case DERBY_EMBEDDED: + sql.add("alter table " + theTableName + " drop constraint " + theIndexName); + break; + case ORACLE_12C: + sql.add("drop index " + theIndexName); + break; + case MSSQL_2012: + sql.add("drop index " + theIndexName + " on " + theTableName); + break; + case POSTGRES_9_4: + sql.add("alter table " + theTableName + " drop constraint if exists " + theIndexName + " cascade"); + sql.add("drop index if exists " + theIndexName + " cascade"); + break; + } + } else { + // Drop index + switch (theDriverType) { + case MYSQL_5_7: + case MARIADB_10_1: + sql.add("alter table " + theTableName + " drop index " + theIndexName); + break; + case POSTGRES_9_4: + case DERBY_EMBEDDED: + case H2_EMBEDDED: + case ORACLE_12C: + sql.add("drop index " + theIndexName); + break; + case MSSQL_2012: + sql.add("drop index " + theTableName + "." + theIndexName); + break; + } + } + return sql; + } + @Override public void validate() { super.validate(); @@ -145,62 +203,4 @@ public class DropIndexTask extends BaseTableTask { super.generateHashCode(theBuilder); theBuilder.append(myIndexName); } - - static List createDropIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theIndexName, DriverTypeEnum theDriverType) throws SQLException { - Validate.notBlank(theIndexName, "theIndexName must not be blank"); - Validate.notBlank(theTableName, "theTableName must not be blank"); - - if (!JdbcUtils.getIndexNames(theConnectionProperties, theTableName).contains(theIndexName)) { - return Collections.emptyList(); - } - - boolean isUnique = JdbcUtils.isIndexUnique(theConnectionProperties, theTableName, theIndexName); - - List sql = new ArrayList<>(); - - if (isUnique) { - // Drop constraint - switch (theDriverType) { - case MYSQL_5_7: - case MARIADB_10_1: - // Need to quote the index name as the word "PRIMARY" is reserved in MySQL - sql.add("alter table " + theTableName + " drop index `" + theIndexName + "`"); - break; - case H2_EMBEDDED: - sql.add("drop index " + theIndexName); - break; - case DERBY_EMBEDDED: - sql.add("alter table " + theTableName + " drop constraint " + theIndexName); - break; - case ORACLE_12C: - sql.add("drop index " + theIndexName); - break; - case MSSQL_2012: - sql.add("drop index " + theIndexName + " on " + theTableName); - break; - case POSTGRES_9_4: - sql.add("alter table " + theTableName + " drop constraint if exists " + theIndexName + " cascade"); - sql.add("drop index if exists " + theIndexName + " cascade"); - break; - } - } else { - // Drop index - switch (theDriverType) { - case MYSQL_5_7: - case MARIADB_10_1: - sql.add("alter table " + theTableName + " drop index " + theIndexName); - break; - case POSTGRES_9_4: - case DERBY_EMBEDDED: - case H2_EMBEDDED: - case ORACLE_12C: - sql.add("drop index " + theIndexName); - break; - case MSSQL_2012: - sql.add("drop index " + theTableName + "." + theIndexName); - break; - } - } - return sql; - } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java similarity index 94% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java index cc499500b71..1f665475909 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTask.java @@ -162,14 +162,14 @@ public class ModifyColumnTask extends BaseTableColumnTypeTask { switch (getDriverType()) { case ORACLE_12C: @Language("SQL") String findNullableConstraintSql = - "SELECT acc.owner, acc.table_name, acc.column_name, search_condition_vc " + - "FROM all_cons_columns acc, all_constraints ac " + - "WHERE acc.constraint_name = ac.constraint_name " + - "AND acc.table_name = ac.table_name " + - "AND ac.constraint_type = ? " + - "AND acc.table_name = ? " + - "AND acc.column_name = ? " + - "AND search_condition_vc = ? "; + "SELECT acc.owner, acc.table_name, acc.column_name, search_condition_vc " + + "FROM all_cons_columns acc, all_constraints ac " + + "WHERE acc.constraint_name = ac.constraint_name " + + "AND acc.table_name = ac.table_name " + + "AND ac.constraint_type = ? " + + "AND acc.table_name = ? " + + "AND acc.column_name = ? " + + "AND search_condition_vc = ? "; String[] params = new String[4]; params[0] = "C"; params[1] = tableName.toUpperCase(); diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/NopTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/NopTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/NopTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/NopTask.java diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java index 59f818a6cb0..7c0401dfedf 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTask.java @@ -91,10 +91,10 @@ public class RenameColumnTask extends BaseTableTask { // Some DBs such as MYSQL require that foreign keys depending on the column be explicitly dropped before the column itself is dropped. logInfo(ourLog, "Table {} has columns {} and {} - Going to drop any foreign keys depending on column {} before renaming", getTableName(), myOldName, myNewName, myNewName); Set foreignKeys = JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), myNewName, getTableName()); - if(foreignKeys != null) { - for (String foreignKey:foreignKeys) { + if (foreignKeys != null) { + for (String foreignKey : foreignKeys) { List dropFkSqls = DropForeignKeyTask.generateSql(getTableName(), foreignKey, getDriverType()); - for(String dropFkSql : dropFkSqls) { + for (String dropFkSql : dropFkSqls) { executeSql(getTableName(), dropFkSql); } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java index 5ccc8c1eeef..413e2aea409 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameIndexTask.java @@ -44,6 +44,39 @@ public class RenameIndexTask extends BaseTableTask { super(theProductVersion, theSchemaVersion); } + static List createRenameIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theOldIndexName, String theNewIndexName, DriverTypeEnum theDriverType) throws SQLException { + Validate.notBlank(theOldIndexName, "theOldIndexName must not be blank"); + Validate.notBlank(theNewIndexName, "theNewIndexName must not be blank"); + Validate.notBlank(theTableName, "theTableName must not be blank"); + + if (!JdbcUtils.getIndexNames(theConnectionProperties, theTableName).contains(theOldIndexName)) { + return Collections.emptyList(); + } + + List sql = new ArrayList<>(); + + // Drop constraint + switch (theDriverType) { + case MYSQL_5_7: + case MARIADB_10_1: + // Quote the index names as "PRIMARY" is a reserved word in MySQL + sql.add("rename index `" + theOldIndexName + "` to `" + theNewIndexName + "`"); + break; + case DERBY_EMBEDDED: + sql.add("rename index " + theOldIndexName + " to " + theNewIndexName); + break; + case H2_EMBEDDED: + case POSTGRES_9_4: + case ORACLE_12C: + sql.add("alter index " + theOldIndexName + " rename to " + theNewIndexName); + break; + case MSSQL_2012: + sql.add("EXEC sp_rename '" + theTableName + "." + theOldIndexName + "', '" + theNewIndexName + "'"); + break; + } + return sql; + } + @Override public void validate() { super.validate(); @@ -95,37 +128,4 @@ public class RenameIndexTask extends BaseTableTask { theBuilder.append(myOldIndexName); theBuilder.append(myNewIndexName); } - - static List createRenameIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theOldIndexName, String theNewIndexName, DriverTypeEnum theDriverType) throws SQLException { - Validate.notBlank(theOldIndexName, "theOldIndexName must not be blank"); - Validate.notBlank(theNewIndexName, "theNewIndexName must not be blank"); - Validate.notBlank(theTableName, "theTableName must not be blank"); - - if (!JdbcUtils.getIndexNames(theConnectionProperties, theTableName).contains(theOldIndexName)) { - return Collections.emptyList(); - } - - List sql = new ArrayList<>(); - - // Drop constraint - switch (theDriverType) { - case MYSQL_5_7: - case MARIADB_10_1: - // Quote the index names as "PRIMARY" is a reserved word in MySQL - sql.add("rename index `" + theOldIndexName + "` to `" + theNewIndexName + "`"); - break; - case DERBY_EMBEDDED: - sql.add("rename index " + theOldIndexName + " to " + theNewIndexName); - break; - case H2_EMBEDDED: - case POSTGRES_9_4: - case ORACLE_12C: - sql.add("alter index " + theOldIndexName + " rename to " + theNewIndexName); - break; - case MSSQL_2012: - sql.add("EXEC sp_rename '" + theTableName + "." + theOldIndexName + "', '" + theNewIndexName + "'"); - break; - } - return sql; - } } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java similarity index 97% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java index f1490da0ded..56444de2d71 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/SchemaInitializationProvider.java @@ -37,16 +37,15 @@ import static org.apache.commons.lang3.StringUtils.isBlank; public class SchemaInitializationProvider implements ISchemaInitializationProvider { - private String mySchemaFileClassPath; - - private String mySchemaDescription; private final String mySchemaExistsIndicatorTable; private final boolean myCanInitializeSchema; + private String mySchemaFileClassPath; + private String mySchemaDescription; /** * @param theSchemaFileClassPath pathname to script used to initialize schema * @param theSchemaExistsIndicatorTable a table name we can use to determine if this schema has already been initialized - * @param theCanInitializeSchema this is a "root" schema initializer that creates the primary tables used by this app + * @param theCanInitializeSchema this is a "root" schema initializer that creates the primary tables used by this app */ public SchemaInitializationProvider(String theSchemaDescription, String theSchemaFileClassPath, String theSchemaExistsIndicatorTable, boolean theCanInitializeSchema) { mySchemaDescription = theSchemaDescription; diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java index 0aacaadb850..7af302cc867 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasks.java @@ -33,8 +33,8 @@ import java.util.Collection; import java.util.List; public class BaseMigrationTasks { - private Multimap myTasks = MultimapBuilder.hashKeys().arrayListValues().build(); MigrationVersion lastVersion; + private Multimap myTasks = MultimapBuilder.hashKeys().arrayListValues().build(); @SuppressWarnings("unchecked") public List getTasks(@Nonnull T theFrom, @Nonnull T theTo) { @@ -94,7 +94,7 @@ public class BaseMigrationTasks { } void validate(Collection theTasks) { - for (BaseTask task: theTasks) { + for (BaseTask task : theTasks) { task.validateVersion(); String version = task.getFlywayVersion(); MigrationVersion migrationVersion = MigrationVersion.fromVersion(version); diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java similarity index 93% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java index 34c8805de97..49c39da0ab0 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java @@ -21,7 +21,26 @@ package ca.uhn.fhir.jpa.migrate.tasks.api; */ import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; -import ca.uhn.fhir.jpa.migrate.taskdef.*; +import ca.uhn.fhir.jpa.migrate.taskdef.AddColumnTask; +import ca.uhn.fhir.jpa.migrate.taskdef.AddForeignKeyTask; +import ca.uhn.fhir.jpa.migrate.taskdef.AddIdGeneratorTask; +import ca.uhn.fhir.jpa.migrate.taskdef.AddIndexTask; +import ca.uhn.fhir.jpa.migrate.taskdef.AddTableByColumnTask; +import ca.uhn.fhir.jpa.migrate.taskdef.AddTableRawSqlTask; +import ca.uhn.fhir.jpa.migrate.taskdef.BaseTableTask; +import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask; +import ca.uhn.fhir.jpa.migrate.taskdef.ColumnTypeEnum; +import ca.uhn.fhir.jpa.migrate.taskdef.DropColumnTask; +import ca.uhn.fhir.jpa.migrate.taskdef.DropForeignKeyTask; +import ca.uhn.fhir.jpa.migrate.taskdef.DropIdGeneratorTask; +import ca.uhn.fhir.jpa.migrate.taskdef.DropIndexTask; +import ca.uhn.fhir.jpa.migrate.taskdef.DropTableTask; +import ca.uhn.fhir.jpa.migrate.taskdef.ExecuteRawSqlTask; +import ca.uhn.fhir.jpa.migrate.taskdef.InitializeSchemaTask; +import ca.uhn.fhir.jpa.migrate.taskdef.ModifyColumnTask; +import ca.uhn.fhir.jpa.migrate.taskdef.NopTask; +import ca.uhn.fhir.jpa.migrate.taskdef.RenameColumnTask; +import ca.uhn.fhir.jpa.migrate.taskdef.RenameIndexTask; import org.apache.commons.lang3.Validate; import org.intellij.lang.annotations.Language; @@ -98,56 +117,8 @@ public class Builder { addTask(task); } - public void addNop(String theVersion) { - addTask(new NopTask(myRelease, theVersion)); - } - - public class BuilderAddTableRawSql { - - private final AddTableRawSqlTask myTask; - - protected BuilderAddTableRawSql(String theVersion, String theTableName) { - myTask = new AddTableRawSqlTask(myRelease, theVersion); - myTask.setTableName(theTableName); - addTask(myTask); - } - - - public BuilderAddTableRawSql addSql(DriverTypeEnum theDriverTypeEnum, @Language("SQL") String theSql) { - myTask.addSql(theDriverTypeEnum, theSql); - return this; - } - - public void addSql(@Language("SQL") String theSql) { - myTask.addSql(theSql); - } - } - - public class BuilderAddTableByColumns extends BuilderWithTableName implements BaseMigrationTasks.IAcceptsTasks { - private final String myVersion; - private final AddTableByColumnTask myTask; - - public BuilderAddTableByColumns(String theRelease, String theVersion, BaseMigrationTasks.IAcceptsTasks theSink, String theTableName, List thePkColumnNames) { - super(theRelease, theSink, theTableName); - myVersion = theVersion; - myTask = new AddTableByColumnTask(myRelease, theVersion); - myTask.setTableName(theTableName); - myTask.setPkColumns(thePkColumnNames); - theSink.addTask(myTask); - } - - public BuilderAddColumnWithName addColumn(String theColumnName) { - return new BuilderAddColumnWithName(myRelease, myVersion, theColumnName, this); - } - - @Override - public void addTask(BaseTask theTask) { - if (theTask instanceof AddColumnTask) { - myTask.addAddColumnTask((AddColumnTask) theTask); - } else { - super.addTask(theTask); - } - } + public void addNop(String theVersion) { + addTask(new NopTask(myRelease, theVersion)); } public static class BuilderWithTableName implements BaseMigrationTasks.IAcceptsTasks { @@ -479,7 +450,6 @@ public class Builder { } } - public static class BuilderCompleteTask { private final BaseTask myTask; @@ -510,4 +480,52 @@ public class Builder { } } + public class BuilderAddTableRawSql { + + private final AddTableRawSqlTask myTask; + + protected BuilderAddTableRawSql(String theVersion, String theTableName) { + myTask = new AddTableRawSqlTask(myRelease, theVersion); + myTask.setTableName(theTableName); + addTask(myTask); + } + + + public BuilderAddTableRawSql addSql(DriverTypeEnum theDriverTypeEnum, @Language("SQL") String theSql) { + myTask.addSql(theDriverTypeEnum, theSql); + return this; + } + + public void addSql(@Language("SQL") String theSql) { + myTask.addSql(theSql); + } + } + + public class BuilderAddTableByColumns extends BuilderWithTableName implements BaseMigrationTasks.IAcceptsTasks { + private final String myVersion; + private final AddTableByColumnTask myTask; + + public BuilderAddTableByColumns(String theRelease, String theVersion, BaseMigrationTasks.IAcceptsTasks theSink, String theTableName, List thePkColumnNames) { + super(theRelease, theSink, theTableName); + myVersion = theVersion; + myTask = new AddTableByColumnTask(myRelease, theVersion); + myTask.setTableName(theTableName); + myTask.setPkColumns(thePkColumnNames); + theSink.addTask(myTask); + } + + public BuilderAddColumnWithName addColumn(String theColumnName) { + return new BuilderAddColumnWithName(myRelease, myVersion, theColumnName, this); + } + + @Override + public void addTask(BaseTask theTask) { + if (theTask instanceof AddColumnTask) { + myTask.addAddColumnTask((AddColumnTask) theTask); + } else { + super.addTask(theTask); + } + } + } + } diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/ISchemaInitializationProvider.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/ISchemaInitializationProvider.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/ISchemaInitializationProvider.java rename to hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/ISchemaInitializationProvider.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java index 1cedd099139..130413f204f 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/FlywayMigrationTaskTest.java @@ -23,13 +23,12 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class FlywayMigrationTaskTest { + TestTask myTestTask = new TestTask(); @Mock private FlywayMigrator myFlywayMigrator; @Mock private Context myContext; - TestTask myTestTask = new TestTask(); - @Test public void schemaInitializedStubsFollowingMigration() { when(myFlywayMigrator.isSchemaWasInitialized()).thenReturn(true); diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java index 42eaf645543..cdc9fb01a1f 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/JdbcUtilsTest.java @@ -13,8 +13,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import static org.mockito.Mockito.when; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class JdbcUtilsTest { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java similarity index 97% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java index 60a86eead8b..f804d2265a3 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/MigrationTaskSkipperTest.java @@ -12,8 +12,8 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; public class MigrationTaskSkipperTest { public static final String RELEASE = "4_1_0"; @@ -88,7 +88,7 @@ public class MigrationTaskSkipperTest { @Test public void oneQuoted() { - MigrationTaskSkipper.setDoNothingOnSkippedTasks(myTasks, "\"" + VERSION_PREFIX + 2 + "\"" ); + MigrationTaskSkipper.setDoNothingOnSkippedTasks(myTasks, "\"" + VERSION_PREFIX + 2 + "\""); assertSkipped(myTasks, 2); } @@ -109,7 +109,7 @@ public class MigrationTaskSkipperTest { } @Nonnull -private Stream integersToVersions(Integer[] theVersions) { + private Stream integersToVersions(Integer[] theVersions) { return Stream.of(theVersions).map(s -> VERSION_PREFIX + s); } } diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddColumnTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java similarity index 97% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java index 4cde5b886bc..53b14956ed6 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddForeignKeyTaskTest.java @@ -2,15 +2,14 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import ca.uhn.fhir.jpa.migrate.JdbcUtils; import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import java.sql.SQLException; import java.util.function.Supplier; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; public class AddForeignKeyTaskTest extends BaseTest { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java index e3d8aefbf59..b6366dfbbea 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIdGeneratorTaskTest.java @@ -10,9 +10,9 @@ import org.junit.jupiter.params.provider.MethodSource; import java.sql.SQLException; import java.util.function.Supplier; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; -import static org.hamcrest.MatcherAssert.assertThat; public class AddIdGeneratorTaskTest extends BaseTest { @@ -40,7 +40,6 @@ public class AddIdGeneratorTaskTest extends BaseTest { } - private static class MyMigrationTasks extends BaseMigrationTasks { public MyMigrationTasks(String theVersion) { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddIndexTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java similarity index 97% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java index c1989522d4c..2cd066563e4 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableByColumnTaskTest.java @@ -5,7 +5,6 @@ import ca.uhn.fhir.jpa.migrate.JdbcUtils; import ca.uhn.fhir.jpa.migrate.tasks.api.BaseMigrationTasks; import ca.uhn.fhir.jpa.migrate.tasks.api.Builder; import ca.uhn.fhir.util.VersionEnum; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -14,8 +13,8 @@ import java.util.Set; import java.util.function.Supplier; import java.util.stream.Collectors; -import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; public class AddTableByColumnTaskTest extends BaseTest { @@ -37,7 +36,7 @@ public class AddTableByColumnTaskTest extends BaseTest { // Derby auto-creates constraints with a system name for unique indexes if (getDriverType().equals(DriverTypeEnum.DERBY_EMBEDDED)) { - indexes.removeIf(t->t.startsWith("SQL")); + indexes.removeIf(t -> t.startsWith("SQL")); } assertThat(indexes.toString(), indexes, containsInAnyOrder("IDX_BONJOUR")); diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java index 36cb0256475..b672e318463 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/AddTableTest.java @@ -7,8 +7,8 @@ import org.junit.jupiter.params.provider.MethodSource; import java.sql.SQLException; import java.util.function.Supplier; -import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; public class AddTableTest extends BaseTest { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTaskTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTaskTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java index 777df41e6a1..a0942d26ada 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTest.java @@ -30,6 +30,56 @@ public abstract class BaseTest { private FlywayMigrator myMigrator; private DriverTypeEnum.ConnectionProperties myConnectionProperties; + public static Stream> data() { + ourLog.info("H2: {}", org.h2.Driver.class.toString()); + + ArrayList> retVal = new ArrayList<>(); + + // H2 + retVal.add(new Supplier() { + @Override + public TestDatabaseDetails get() { + String url = "jdbc:h2:mem:" + DATABASE_NAME + ourDatabaseUrl++; + DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.H2_EMBEDDED.newConnectionProperties(url, "SA", "SA"); + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl(url); + dataSource.setUsername("SA"); + dataSource.setPassword("SA"); + dataSource.setDriverClassName(DriverTypeEnum.H2_EMBEDDED.getDriverClassName()); + FlywayMigrator migrator = new FlywayMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, DriverTypeEnum.H2_EMBEDDED); + return new TestDatabaseDetails(url, connectionProperties, dataSource, migrator); + } + + @Override + public String toString() { + return "H2"; + } + }); + + // Derby + retVal.add(new Supplier() { + @Override + public TestDatabaseDetails get() { + String url = "jdbc:derby:memory:" + DATABASE_NAME + ourDatabaseUrl++ + ";create=true"; + DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.DERBY_EMBEDDED.newConnectionProperties(url, "SA", "SA"); + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl(url); + dataSource.setUsername("SA"); + dataSource.setPassword("SA"); + dataSource.setDriverClassName(DriverTypeEnum.DERBY_EMBEDDED.getDriverClassName()); + FlywayMigrator migrator = new FlywayMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, DriverTypeEnum.DERBY_EMBEDDED); + return new TestDatabaseDetails(url, connectionProperties, dataSource, migrator); + } + + @Override + public String toString() { + return "Derby"; + } + }); + + return retVal.stream(); + } + public void before(Supplier theTestDatabaseDetails) { TestDatabaseDetails testDatabaseDetails = theTestDatabaseDetails.get(); myUrl = testDatabaseDetails.myUrl; @@ -108,54 +158,4 @@ public abstract class BaseTest { } - public static Stream> data() { - ourLog.info("H2: {}", org.h2.Driver.class.toString()); - - ArrayList> retVal = new ArrayList<>(); - - // H2 - retVal.add(new Supplier() { - @Override - public TestDatabaseDetails get() { - String url = "jdbc:h2:mem:" + DATABASE_NAME + ourDatabaseUrl++; - DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.H2_EMBEDDED.newConnectionProperties(url, "SA", "SA"); - BasicDataSource dataSource = new BasicDataSource(); - dataSource.setUrl(url); - dataSource.setUsername("SA"); - dataSource.setPassword("SA"); - dataSource.setDriverClassName(DriverTypeEnum.H2_EMBEDDED.getDriverClassName()); - FlywayMigrator migrator = new FlywayMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, DriverTypeEnum.H2_EMBEDDED); - return new TestDatabaseDetails(url, connectionProperties, dataSource, migrator); - } - - @Override - public String toString() { - return "H2"; - } - }); - - // Derby - retVal.add(new Supplier() { - @Override - public TestDatabaseDetails get() { - String url = "jdbc:derby:memory:" + DATABASE_NAME + ourDatabaseUrl++ + ";create=true"; - DriverTypeEnum.ConnectionProperties connectionProperties = DriverTypeEnum.DERBY_EMBEDDED.newConnectionProperties(url, "SA", "SA"); - BasicDataSource dataSource = new BasicDataSource(); - dataSource.setUrl(url); - dataSource.setUsername("SA"); - dataSource.setPassword("SA"); - dataSource.setDriverClassName(DriverTypeEnum.DERBY_EMBEDDED.getDriverClassName()); - FlywayMigrator migrator = new FlywayMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, DriverTypeEnum.DERBY_EMBEDDED); - return new TestDatabaseDetails(url, connectionProperties, dataSource, migrator); - } - - @Override - public String toString() { - return "Derby"; - } - }); - - return retVal.stream(); - } - } diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java similarity index 96% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java index e2655fef2bc..9cad4bbd34b 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropColumnTest.java @@ -7,8 +7,8 @@ import org.junit.jupiter.params.provider.MethodSource; import java.sql.SQLException; import java.util.function.Supplier; -import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasSize; public class DropColumnTest extends BaseTest { @@ -20,7 +20,7 @@ public class DropColumnTest extends BaseTest { executeSql("create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))"); - DropColumnTask task = new DropColumnTask("1", "1"); + DropColumnTask task = new DropColumnTask("1", "1"); task.setTableName("SOMETABLE"); task.setColumnName("TEXTCOL"); getMigrator().addTask(task); @@ -52,7 +52,7 @@ public class DropColumnTest extends BaseTest { assertThat(JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), "PARENTREF", "CHILD"), containsInAnyOrder("FK_MOM")); assertThat(JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), "SIBLINGREF", "CHILD"), containsInAnyOrder("FK_BROTHER")); - DropColumnTask task = new DropColumnTask("1", "1"); + DropColumnTask task = new DropColumnTask("1", "1"); task.setTableName("CHILD"); task.setColumnName("PARENTREF"); getMigrator().addTask(task); diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTaskTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropForeignKeyTaskTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java index 5d566b68c94..735dc92de24 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIdGeneratorTaskTest.java @@ -10,9 +10,9 @@ import org.junit.jupiter.params.provider.MethodSource; import java.sql.SQLException; import java.util.function.Supplier; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; -import static org.hamcrest.MatcherAssert.assertThat; public class DropIdGeneratorTaskTest extends BaseTest { @@ -33,7 +33,6 @@ public class DropIdGeneratorTaskTest extends BaseTest { } - private static class MyMigrationTasks extends BaseMigrationTasks { public MyMigrationTasks() { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java index e6aeb43dfda..acf939180ae 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTest.java @@ -1,8 +1,6 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import ca.uhn.fhir.jpa.migrate.JdbcUtils; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java index dc80e30ca26..c8520d87892 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTest.java @@ -1,7 +1,6 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import ca.uhn.fhir.jpa.migrate.JdbcUtils; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTaskTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ExecuteRawSqlTaskTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java index 7a469c372b5..c5efda09693 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/InitializeSchemaTaskTest.java @@ -4,7 +4,6 @@ import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; import ca.uhn.fhir.jpa.migrate.JdbcUtils; import ca.uhn.fhir.jpa.migrate.tasks.api.ISchemaInitializationProvider; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -13,8 +12,8 @@ import java.util.Collections; import java.util.List; import java.util.function.Supplier; -import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; public class InitializeSchemaTaskTest extends BaseTest { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java similarity index 99% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java index d3ed886f6ce..f750af7b93d 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/ModifyColumnTest.java @@ -3,7 +3,6 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; import ca.uhn.fhir.jpa.migrate.JdbcUtils; import org.flywaydb.core.internal.command.DbMigrate; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskDbSpecificTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskDbSpecificTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskDbSpecificTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskDbSpecificTest.java diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java similarity index 98% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java index 3e02111e397..a01fda1ee09 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/taskdef/RenameColumnTaskTest.java @@ -2,7 +2,6 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import ca.uhn.fhir.jpa.migrate.JdbcUtils; import org.flywaydb.core.api.FlywayException; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -54,7 +53,7 @@ public class RenameColumnTaskTest extends BaseTest { assertThat(JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), "PARENTREF", "CHILD"), containsInAnyOrder("FK_MOM")); - RenameColumnTask task = new RenameColumnTask("1", "1"); + RenameColumnTask task = new RenameColumnTask("1", "1"); task.setTableName("CHILD"); task.setOldName("myParentRef"); task.setNewName("PARENTREF"); @@ -120,7 +119,7 @@ public class RenameColumnTaskTest extends BaseTest { assertThat(JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), "PARENTREF", "CHILD"), containsInAnyOrder("FK_MOM")); assertThat(JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), "NOKREF", "CHILD"), containsInAnyOrder("FK_NOK")); - RenameColumnTask task = new RenameColumnTask("1", "1"); + RenameColumnTask task = new RenameColumnTask("1", "1"); task.setTableName("CHILD"); task.setOldName("PARENTREF"); task.setNewName("NOKREF"); @@ -208,7 +207,7 @@ public class RenameColumnTaskTest extends BaseTest { assertThat(JdbcUtils.getForeignKeysForColumn(getConnectionProperties(), "PARENTREF", "CHILD"), containsInAnyOrder("FK_MOM")); - RenameColumnTask task = new RenameColumnTask("1", "1"); + RenameColumnTask task = new RenameColumnTask("1", "1"); task.setTableName("CHILD"); task.setOldName("PARENTREF"); task.setNewName("MOMREF"); diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java similarity index 100% rename from hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java rename to hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java index 8bd1243d284..fba2745ce36 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java +++ b/hapi-fhir-sql-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/tasks/api/BaseMigrationTasksTest.java @@ -11,9 +11,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; public class BaseMigrationTasksTest { - static class MyMigrationTasks extends BaseMigrationTasks { - } - @Test public void testValidateCorrectOrder() { MyMigrationTasks migrationTasks = new MyMigrationTasks(); @@ -65,4 +62,7 @@ public class BaseMigrationTasksTest { } } + static class MyMigrationTasks extends BaseMigrationTasks { + } + } diff --git a/hapi-fhir-jpaserver-migrate/src/test/resources/logback-test.xml b/hapi-fhir-sql-migrate/src/test/resources/logback-test.xml similarity index 89% rename from hapi-fhir-jpaserver-migrate/src/test/resources/logback-test.xml rename to hapi-fhir-sql-migrate/src/test/resources/logback-test.xml index dc857b12814..50b91b94870 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/resources/logback-test.xml +++ b/hapi-fhir-sql-migrate/src/test/resources/logback-test.xml @@ -8,7 +8,7 @@ - + diff --git a/hapi-fhir-jpaserver-api/pom.xml b/hapi-fhir-storage-api/pom.xml similarity index 92% rename from hapi-fhir-jpaserver-api/pom.xml rename to hapi-fhir-storage-api/pom.xml index 4f709865c14..e9870a401b0 100644 --- a/hapi-fhir-jpaserver-api/pom.xml +++ b/hapi-fhir-storage-api/pom.xml @@ -5,14 +5,17 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml - hapi-fhir-jpaserver-api + hapi-fhir-storage-api jar - HAPI FHIR JPA API + HAPI FHIR Storage api + This project provides services useful for fhir repository storage. Actual repository storage services + are not in this project, just the api and helper libraries. + @@ -56,6 +59,7 @@ hapi-fhir-structures-hl7org-dstu2 ${project.version} + ca.uhn.hapi.fhir hapi-fhir-jpaserver-model @@ -99,11 +103,6 @@ jscience - - org.apache.commons - commons-collections4 - - org.quartz-scheduler quartz diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java similarity index 99% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java index ca9b5969021..062ce21426e 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java @@ -89,6 +89,14 @@ public class DaoConfig { * @since 5.5.0 */ public static final TagStorageModeEnum DEFAULT_TAG_STORAGE_MODE = TagStorageModeEnum.VERSIONED; + public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 800; + /** + * @since 5.6.0 + */ + // Thread Pool size used by batch in bundle + public static final int DEFAULT_BUNDLE_BATCH_POOL_SIZE = 20; // 1 for single thread + public static final int DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE = 100; // 1 for single thread + public static final int DEFAULT_BUNDLE_BATCH_QUEUE_CAPACITY = 200; /** * Default value for {@link #setMaximumSearchResultCountInTransaction(Integer)} * @@ -97,7 +105,6 @@ public class DaoConfig { private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null; private static final Integer DEFAULT_MAXIMUM_TRANSACTION_BUNDLE_SIZE = null; private static final Logger ourLog = LoggerFactory.getLogger(DaoConfig.class); - public static final int DEFAULT_EXPUNGE_BATCH_SIZE = 800; private static final int DEFAULT_REINDEX_BATCH_SIZE = 800; private static final int DEFAULT_MAXIMUM_DELETE_CONFLICT_COUNT = 60; /** @@ -111,7 +118,11 @@ public class DaoConfig { * @since 4.1.0 */ private final int myPreExpandValueSetsDefaultOffset = 0; - + /** + * update setter javadoc if default changes + */ + @Nonnull + private final Long myTranslationCachesExpireAfterWriteInMinutes = DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES; /** * @since 5.5.0 */ @@ -219,17 +230,10 @@ public class DaoConfig { * @since 5.2.0 */ private boolean myUseLegacySearchBuilder = false; - /** * @since 5.5.0 */ private boolean myReindexEnabled = true; - - /** - * update setter javadoc if default changes - */ - @Nonnull - private final Long myTranslationCachesExpireAfterWriteInMinutes = DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES; /** * @since 5.4.0 */ @@ -257,20 +261,10 @@ public class DaoConfig { private boolean myMassIngestionMode; private boolean myAccountForDateIndexNulls; private boolean myTriggerSubscriptionsForNonVersioningChanges; - /** * @since 5.6.0 */ private String myElasicSearchIndexPrefix; - - /** - * @since 5.6.0 - */ - // Thread Pool size used by batch in bundle - public static final int DEFAULT_BUNDLE_BATCH_POOL_SIZE = 20; // 1 for single thread - public static final int DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE = 100; // 1 for single thread - public static final int DEFAULT_BUNDLE_BATCH_QUEUE_CAPACITY = 200; - private Integer myBundleBatchPoolSize = DEFAULT_BUNDLE_BATCH_POOL_SIZE; private Integer myBundleBatchMaxPoolSize = DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE; @@ -2588,8 +2582,8 @@ public class DaoConfig { } /** - * Get the batch transaction thread pool size. - * + * Get the batch transaction thread pool size. + * * @since 5.6.0 */ public Integer getBundleBatchPoolSize() { @@ -2599,32 +2593,32 @@ public class DaoConfig { /** * Set the batch transaction thread pool size. The default is @see {@link #DEFAULT_BUNDLE_BATCH_POOL_SIZE} * set pool size to 1 for single thread - * + * * @since 5.6.0 */ public void setBundleBatchPoolSize(Integer theBundleBatchPoolSize) { this.myBundleBatchPoolSize = theBundleBatchPoolSize; } - + /** * Get the batch transaction thread max pool size. * set max pool size to 1 for single thread - * + * * @since 5.6.0 */ public Integer getBundleBatchMaxPoolSize() { return myBundleBatchMaxPoolSize; } - + /** * Set the batch transaction thread pool size. The default is @see {@link #DEFAULT_BUNDLE_BATCH_MAX_POOL_SIZE} - * + * * @since 5.6.0 */ public void setBundleBatchMaxPoolSize(Integer theBundleBatchMaxPoolSize) { this.myBundleBatchMaxPoolSize = theBundleBatchMaxPoolSize; } - + public boolean canDeleteExpunge() { return isAllowMultipleDelete() && isExpungeEnabled() && isDeleteExpungeEnabled(); } @@ -2650,7 +2644,6 @@ public class DaoConfig { } /** - * * Sets a prefix for any indexes created when interacting with elasticsearch. This will apply to fulltext search indexes * and terminology expansion indexes. * @@ -2661,7 +2654,6 @@ public class DaoConfig { } /** - * * Sets a prefix for any indexes created when interacting with elasticsearch. This will apply to fulltext search indexes * and terminology expansion indexes. * @@ -2671,7 +2663,7 @@ public class DaoConfig { myElasicSearchIndexPrefix = thePrefix; } - public enum StoreMetaSourceInformationEnum { + public enum StoreMetaSourceInformationEnum { NONE(false, false), SOURCE_URI(true, false), REQUEST_ID(false, true), diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java similarity index 99% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java index 0171d842884..550cb973e0c 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/DaoRegistry.java @@ -81,6 +81,7 @@ public class DaoRegistry implements ApplicationContextAware, IDaoRegistry { public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException { myAppCtx = theApplicationContext; } + public IFhirSystemDao getSystemDao() { IFhirSystemDao retVal = mySystemDao; if (retVal == null) { diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IDao.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IDao.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IDao.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IDao.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDao.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDao.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDao.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDao.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoCodeSystem.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoComposition.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoComposition.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoComposition.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoComposition.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java index 73d92fd35a7..ea2b0551037 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoConceptMap.java @@ -20,8 +20,8 @@ package ca.uhn.fhir.jpa.api.dao; * #L% */ -import ca.uhn.fhir.jpa.api.model.TranslationRequest; import ca.uhn.fhir.context.support.TranslateConceptResults; +import ca.uhn.fhir.jpa.api.model.TranslationRequest; import ca.uhn.fhir.rest.api.server.RequestDetails; import org.hl7.fhir.instance.model.api.IBaseResource; diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoEncounter.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoEncounter.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoEncounter.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoEncounter.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoMessageHeader.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoMessageHeader.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoMessageHeader.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoMessageHeader.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java similarity index 81% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java index cc6ab3f9c12..88f6283e72f 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoObservation.java @@ -31,9 +31,10 @@ public interface IFhirResourceDaoObservation extends IF /** * Returns a BundleProvider which can be used to implement the $lastn operation. - * @param paramMap Parameters supported include Observation.subject, Observation.patient, Observation.code, - * Observation.category, and max (the maximum number of Observations to return per specified subjects/patients, - * codes, and/or categories. + * + * @param paramMap Parameters supported include Observation.subject, Observation.patient, Observation.code, + * Observation.category, and max (the maximum number of Observations to return per specified subjects/patients, + * codes, and/or categories. * @param theRequestDetails * @param theServletResponse * @return diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoPatient.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoPatient.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoPatient.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoPatient.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSearchParameter.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSearchParameter.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSearchParameter.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSearchParameter.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoStructureDefinition.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoStructureDefinition.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoStructureDefinition.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoStructureDefinition.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSubscription.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSubscription.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSubscription.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoSubscription.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirResourceDaoValueSet.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IFhirSystemDao.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java index 4889d41e9a5..595b33a0c3e 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/IJpaDao.java @@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.api.dao; * #L% */ -import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyCurrentlyReindexing.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyCurrentlyReindexing.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyCurrentlyReindexing.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyCurrentlyReindexing.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyResourcePid.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyResourcePid.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyResourcePid.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/dao/MetadataKeyResourcePid.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java index 9c954089dd3..c40846bc46d 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DaoMethodOutcome.java @@ -85,13 +85,13 @@ public class DaoMethodOutcome extends MethodOutcome { return this; } + public ResourcePersistentId getPersistentId() { + return myResourcePersistentId; + } + public DaoMethodOutcome setPersistentId(ResourcePersistentId theResourcePersistentId) { myResourcePersistentId = theResourcePersistentId; return this; } - public ResourcePersistentId getPersistentId() { - return myResourcePersistentId; - } - } diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflict.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflict.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflict.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflict.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflictList.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflictList.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflictList.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteConflictList.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteMethodOutcome.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteMethodOutcome.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteMethodOutcome.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/DeleteMethodOutcome.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOptions.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOptions.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOptions.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOptions.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOutcome.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOutcome.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOutcome.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/ExpungeOutcome.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/HistoryCountModeEnum.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/HistoryCountModeEnum.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/HistoryCountModeEnum.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/HistoryCountModeEnum.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/LazyDaoMethodOutcome.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/ResourceVersionConflictResolutionStrategy.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/ResourceVersionConflictResolutionStrategy.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/ResourceVersionConflictResolutionStrategy.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/ResourceVersionConflictResolutionStrategy.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java similarity index 99% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java index 9df16c29e2c..d8ebd91f0cd 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationQuery.java @@ -84,7 +84,7 @@ public class TranslationQuery { public void setConceptMapVersion(StringType theConceptMapVersion) { myConceptMapVersion = theConceptMapVersion; } - + public boolean hasSource() { return mySource != null && mySource.hasValue(); } diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java similarity index 99% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java index 54800697465..295e3eeae6f 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/TranslationRequest.java @@ -1,9 +1,6 @@ package ca.uhn.fhir.jpa.api.model; -import java.util.ArrayList; -import java.util.List; - -/* +/*- * #%L * HAPI FHIR JPA API * %% @@ -30,6 +27,9 @@ import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.StringType; import org.hl7.fhir.r4.model.UriType; +import java.util.ArrayList; +import java.util.List; + public class TranslationRequest { private CodeableConcept myCodeableConcept; private Long myResourceId; @@ -85,6 +85,10 @@ public class TranslationRequest { myReverse = theReverse; } + public void setReverse(boolean theReverse) { + myReverse = new BooleanType(theReverse); + } + public boolean getReverseAsBoolean() { if (hasReverse()) { return myReverse.booleanValue(); @@ -101,7 +105,7 @@ public class TranslationRequest { myUrl = theUrl; return this; } - + public StringType getConceptMapVersion() { return myConceptMapVersion; } @@ -110,7 +114,7 @@ public class TranslationRequest { myConceptMapVersion = theConceptMapVersion; return this; } - + public UriType getSource() { return mySource; } @@ -154,11 +158,11 @@ public class TranslationRequest { if (this.hasUrl()) { translationQuery.setUrl(this.getUrl()); } - + if (this.hasConceptMapVersion()) { translationQuery.setConceptMapVersion(this.getConceptMapVersion()); } - + if (this.hasSource()) { translationQuery.setSource(this.getSource()); } @@ -204,8 +208,4 @@ public class TranslationRequest { public boolean hasTargetSystem() { return myTargetSystem != null && myTargetSystem.hasValue(); } - - public void setReverse(boolean theReverse) { - myReverse = new BooleanType(theReverse); - } } diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/WarmCacheEntry.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/WarmCacheEntry.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/model/WarmCacheEntry.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/model/WarmCacheEntry.java diff --git a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java index 299eb8cc0b1..5a7f1c003f5 100644 --- a/hapi-fhir-jpaserver-api/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/api/svc/ISearchCoordinatorSvc.java @@ -22,11 +22,11 @@ package ca.uhn.fhir.jpa.api.svc; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; -import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import javax.annotation.Nullable; import java.util.List; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java similarity index 99% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java index ba645d9ebc0..bee8178441d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/api/IBulkDataImportSvc.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.api; /*- * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java index c9de981b5fd..bc44aea61d1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobFileJson.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.model; /*- * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java index fe6ea10d0ba..32e541cb620 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobJson.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.model; /*- * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java index 5c3fe355224..e13c2ebd92b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/BulkImportJobStatusEnum.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.model; /*- * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java similarity index 97% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java index 92826d97242..fd9365dfb9d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/JobFileRowProcessingModeEnum.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.model; /*- * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java index 5b2e49a5c16..bb32691449f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/bulk/imprt/model/ParsedBulkImportRecord.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.bulk.imprt.model; /*- * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java similarity index 98% rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java index b494500d4c1..f038024e684 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/dao/GZipUtil.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.dao; /* * #%L - * HAPI FHIR JPA Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -20,16 +20,15 @@ package ca.uhn.fhir.jpa.dao; * #L% */ +import ca.uhn.fhir.parser.DataFormatException; +import org.apache.commons.io.IOUtils; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -import org.apache.commons.io.IOUtils; - -import ca.uhn.fhir.parser.DataFormatException; - public class GZipUtil { public static String decompress(byte[] theResource) { diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java index 66c76539000..1fe8aa5ef87 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/BaseChannelSettings.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java index d12834717c3..ef3c1fc1113 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelConsumerSettings.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java index 92c81535af7..24573d9de8a 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/ChannelProducerSettings.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java similarity index 98% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java index fb99cd465b8..d35f5ebaebf 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelFactory.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java similarity index 96% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java index 2f794260383..333196341b6 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelProducer.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java similarity index 96% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java index 573112b1518..65b50e5a2f7 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelReceiver.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java similarity index 95% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java index af130c51362..d1138a8e10c 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/api/IChannelSettings.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.api; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java similarity index 98% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java index 30f7b342a2e..d6ca470a18e 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/config/SubscriptionChannelConfig.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.config; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java similarity index 98% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java index c7dbba13e24..728e27fe5d8 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannel.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.impl; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java similarity index 99% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java index 4f69ba6785b..65da0f82288 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/impl/LinkedBlockingChannelFactory.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.impl; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java similarity index 98% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java index 980ee4690fa..bb32e1cc266 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/BroadcastingSubscribableChannelWrapper.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.subscription; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java index f9fbeaeeea3..36efd627d24 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/IChannelNamer.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.subscription; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java similarity index 99% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java index ef45530f9b2..0b29c28c895 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/channel/subscription/SubscriptionChannelFactory.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.channel.subscription; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java index d3f823c2c83..0bc77f57d8c 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/IResourceModifiedConsumer.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.match.matcher.matching; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java similarity index 96% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java index 49f69b1af27..f4a4cef739b 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/matcher/matching/SubscriptionMatchingStrategy.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.match.matcher.matching; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java similarity index 99% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java index c7aec9d309b..4122b0f8c09 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionCanonicalizer.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.match.registry; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -29,7 +29,6 @@ import ca.uhn.fhir.model.dstu2.resource.Subscription; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.util.HapiExtensions; -import org.apache.commons.lang3.Validate; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseHasExtensions; import org.hl7.fhir.instance.model.api.IBaseMetaType; diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java similarity index 98% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java index c699c7868c4..0291279821f 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionConstants.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.match.registry; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java similarity index 99% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java index e7f4be7e52c..12881a30b8c 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscription.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.model; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java similarity index 99% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java index 7b5c30407ec..dfda8619bf0 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/CanonicalSubscriptionChannelType.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.model; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java index d56deaf3c0d..23cebaef2d9 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryJsonMessage.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.model; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java similarity index 99% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java index b755531daf0..b9819585a73 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceDeliveryMessage.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.model; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java similarity index 97% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java index 56a72254540..0e7020eb94b 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedJsonMessage.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.model; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java similarity index 98% rename from hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java index 01b295c69b9..820ce3fc496 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/jpa/subscription/model/ResourceModifiedMessage.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.model; /*- * #%L - * HAPI FHIR Subscription Server + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/log/Logs.java b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/mdm/log/Logs.java similarity index 96% rename from hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/log/Logs.java rename to hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/mdm/log/Logs.java index ae3720f5803..1abc94d5593 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/log/Logs.java +++ b/hapi-fhir-storage-api/src/main/java/ca/uhn/fhir/mdm/log/Logs.java @@ -2,7 +2,7 @@ package ca.uhn.fhir.mdm.log; /*- * #%L - * HAPI FHIR - Master Data Management + * HAPI FHIR JPA API * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% diff --git a/hapi-fhir-jpaserver-api/src/main/resources/.keep-jpaserver-api b/hapi-fhir-storage-api/src/main/resources/.keep-jpaserver-api similarity index 100% rename from hapi-fhir-jpaserver-api/src/main/resources/.keep-jpaserver-api rename to hapi-fhir-storage-api/src/main/resources/.keep-jpaserver-api diff --git a/hapi-fhir-jpaserver-api/src/test/java/.keep b/hapi-fhir-storage-api/src/test/java/.keep similarity index 100% rename from hapi-fhir-jpaserver-api/src/test/java/.keep rename to hapi-fhir-storage-api/src/test/java/.keep diff --git a/hapi-fhir-jpaserver-api/src/test/resources/.keep b/hapi-fhir-storage-api/src/test/resources/.keep similarity index 100% rename from hapi-fhir-jpaserver-api/src/test/resources/.keep rename to hapi-fhir-storage-api/src/test/resources/.keep diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index 3910f44e72a..ef2bbef3f7e 100644 --- a/hapi-fhir-structures-dstu2.1/pom.xml +++ b/hapi-fhir-structures-dstu2.1/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index 6545402f181..2c81d57e6a9 100644 --- a/hapi-fhir-structures-dstu2/pom.xml +++ b/hapi-fhir-structures-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index d9856c320b0..b5a91f0ea57 100644 --- a/hapi-fhir-structures-dstu3/pom.xml +++ b/hapi-fhir-structures-dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml index 9821181f70c..f62d30af447 100644 --- a/hapi-fhir-structures-hl7org-dstu2/pom.xml +++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index d026c82c568..a5b1177c900 100644 --- a/hapi-fhir-structures-r4/pom.xml +++ b/hapi-fhir-structures-r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index 54c8261c98e..63da59f558d 100644 --- a/hapi-fhir-structures-r5/pom.xml +++ b/hapi-fhir-structures-r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index fe8822ed4cd..17157ff1753 100644 --- a/hapi-fhir-test-utilities/pom.xml +++ b/hapi-fhir-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index 466f37f72e3..5ab492a17c8 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index 9be7e6175f5..1635076b1e0 100644 --- a/hapi-fhir-validation-resources-dstu2.1/pom.xml +++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml index 312012590ee..cbace5aa862 100644 --- a/hapi-fhir-validation-resources-dstu2/pom.xml +++ b/hapi-fhir-validation-resources-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml index 9e4259aa765..e0ebab22cb0 100644 --- a/hapi-fhir-validation-resources-dstu3/pom.xml +++ b/hapi-fhir-validation-resources-dstu3/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml index 670e3eb55c9..0b6dc70c454 100644 --- a/hapi-fhir-validation-resources-r4/pom.xml +++ b/hapi-fhir-validation-resources-r4/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml index c4ccaa6187f..18fee1725e9 100644 --- a/hapi-fhir-validation-resources-r5/pom.xml +++ b/hapi-fhir-validation-resources-r5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index 8158acb5ba3..2765d4804a5 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index 86257aa8913..ce03bcdfc4b 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml @@ -58,37 +58,37 @@ ca.uhn.hapi.fhir hapi-fhir-structures-dstu3 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-hl7org-dstu2 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-r4 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-r5 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-dstu2 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-dstu3 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-r4 - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT org.apache.velocity diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index aba66273ba3..f4c47e7ea09 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index b808fcf355c..1aca1b4d3a7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,10 @@ ca.uhn.hapi.fhir hapi-fhir pom - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT + + hapi-fhir-jpa + HAPI-FHIR An open-source implementation of the FHIR specification in Java. https://hapifhir.io @@ -972,7 +975,7 @@ com.sun.activation javax.activation - 1.2.0 + ${activation_api_version} com.sun.activation @@ -1545,6 +1548,24 @@ org.hibernate hibernate-core ${hibernate_version} + + + xml-apis + xml-apis + + + javax.activation + activation + + + javax.activation + javax.activation-api + + + javax.xml.bind + jaxb-api + + org.hibernate @@ -2320,7 +2341,7 @@ - + @@ -2754,15 +2775,15 @@ hapi-fhir-validation-resources-r4 hapi-fhir-structures-r5 hapi-fhir-validation-resources-r5 - hapi-fhir-jpaserver-api + hapi-fhir-storage-api hapi-fhir-jpaserver-cql hapi-fhir-jpaserver-model hapi-fhir-jpaserver-searchparam hapi-fhir-jpaserver-subscription hapi-fhir-jaxrsserver-base - hapi-fhir-jpaserver-batch + hapi-fhir-batch hapi-fhir-jpaserver-base - hapi-fhir-jpaserver-migrate + hapi-fhir-sql-migrate hapi-fhir-jpaserver-mdm hapi-fhir-testpage-overlay hapi-fhir-jpaserver-uhnfhirtest diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index 243e84ae57b..365ce8e7c26 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml index 7d25aab4a21..a8df44b7045 100644 --- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml index 00f4b73b00c..545ebba468a 100644 --- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.6.0-PRE5-SNAPSHOT + 5.6.0-PRE6-SNAPSHOT ../../pom.xml From 645386c99953911da95a21b8bd1cfb5826e2c9c8 Mon Sep 17 00:00:00 2001 From: JasonRoberts-smile <85363818+JasonRoberts-smile@users.noreply.github.com> Date: Tue, 21 Sep 2021 12:26:21 -0400 Subject: [PATCH 45/46] Apply suggestions from code review Co-authored-by: Ken Stevens --- .../fhir/changelog/5_6_0/3012-mssql-database-migration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml index 899aacb26a5..46ce08c8fa0 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3012-mssql-database-migration.yaml @@ -1,4 +1,4 @@ --- type: fix issue: 3012 -title: "Fixes some recent database schema migration failures on MS SQLServer." +title: "Fixes migration of VARBINARY columns on MS SQLServer." From 68b26f7a5e0fb9679fa8ab0d22cee10ea4c64dfb Mon Sep 17 00:00:00 2001 From: Jason Roberts Date: Tue, 21 Sep 2021 12:28:15 -0400 Subject: [PATCH 46/46] apply recommendations from code review --- .../src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java index 21975ad9270..df3c904f687 100644 --- a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/JdbcUtils.java @@ -186,7 +186,7 @@ public class JdbcUtils { case Types.BLOB: return new ColumnType(ColumnTypeEnum.BLOB, length); case Types.VARBINARY: - if (theConnectionProperties.getDriverType().equals(DriverTypeEnum.MSSQL_2012)) { + if (DriverTypeEnum.MSSQL_2012.equals(theConnectionProperties.getDriverType())) { // MS SQLServer seems to be mapping BLOB to VARBINARY under the covers, so we need to reverse that mapping return new ColumnType(ColumnTypeEnum.BLOB, length); } else {