From 9fa7ff42224c6e90bcee27eeaa87985bcc9b60f3 Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 9 Oct 2025 16:22:04 -0600 Subject: [PATCH 01/29] Initial pass over refactoring the sprawling MDM expansion --- .../export/svc/JpaBulkExportProcessor.java | 15 +- .../fhir/jpa/config/JpaBulkExportConfig.java | 9 +- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 68 ++---- .../svc/JpaBulkExportProcessorTest.java | 15 +- .../MdmReadVirtualizationInterceptorTest.java | 2 - .../fhir/jpa/bulk/BulkExportUseCaseTest.java | 181 +++++++------- .../MdmRulesWithEidMatchOnlyConfig.java | 28 +++ .../fhir/jpa/test/config/TestJPAConfig.java | 2 - .../uhn/fhir/mdm/api/IMdmLinkExpandSvc.java | 12 + .../ca/uhn/fhir/mdm/api/IMdmSettings.java | 14 ++ ...ExportMdmEidMatchOnlyResourceExpander.java | 123 ---------- .../svc/BulkExportMdmResourceExpander.java | 228 ------------------ .../mdm/svc/DisabledMdmLinkExpandSvc.java | 53 ++++ .../svc/IBulkExportMdmResourceExpander.java | 43 ---- .../mdm/svc/MdmEidMatchOnlyExpandSvc.java | 69 +++++- .../uhn/fhir/mdm/svc/MdmExpandersHolder.java | 181 -------------- .../ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 178 +++++++++++++- .../fhir/mdm/svc/MdmSearchExpansionSvc.java | 17 +- 18 files changed, 476 insertions(+), 762 deletions(-) create mode 100644 hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java delete mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmEidMatchOnlyResourceExpander.java delete mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmResourceExpander.java create mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java delete mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/IBulkExportMdmResourceExpander.java delete mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpandersHolder.java diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index 79485f5d3d90..ce70403473bd 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -37,7 +37,7 @@ import ca.uhn.fhir.jpa.model.search.SearchBuilderLoadIncludesParameters; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.svc.MdmExpandersHolder; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.api.server.SystemRequestDetails; @@ -86,7 +86,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor { private EntityManager myEntityManager; private IHapiTransactionService myHapiTransactionService; private ISearchParamRegistry mySearchParamRegistry; - private MdmExpandersHolder myMdmExpandersHolder; + private IMdmLinkExpandSvc myMdmLinkExpandSvc; @Autowired public JpaBulkExportProcessor( @@ -98,8 +98,8 @@ public JpaBulkExportProcessor( IIdHelperService theIdHelperService, EntityManager theEntityManager, IHapiTransactionService theHapiTransactionService, - ISearchParamRegistry theSearchParamRegistry, - MdmExpandersHolder theMdmExpandersHolder) { + ISearchParamRegistry theSearchParamRegistry + ) { myContext = theContext; myBulkExportHelperSvc = theBulkExportHelperSvc; myStorageSettings = theStorageSettings; @@ -109,7 +109,6 @@ public JpaBulkExportProcessor( myEntityManager = theEntityManager; myHapiTransactionService = theHapiTransactionService; mySearchParamRegistry = theSearchParamRegistry; - myMdmExpandersHolder = theMdmExpandersHolder; } @Override @@ -349,7 +348,7 @@ protected RuntimeSearchParam getPatientSearchParamForCurrentResourceType(String public void expandMdmResources(List theResources) { for (IBaseResource resource : theResources) { if (!PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(resource.fhirType())) { - myMdmExpandersHolder.getBulkExportMDMResourceExpanderInstance().annotateResource(resource); + myMdmLinkExpandSvc.annotateResource(resource); } } } @@ -405,9 +404,7 @@ private LinkedHashSet getExpandedPatientList( if (theParameters.isExpandMdm()) { RequestPartitionId partitionId = theParameters.getPartitionIdOrAllPartitions(); - patientPidsToExport.addAll(myMdmExpandersHolder - .getBulkExportMDMResourceExpanderInstance() - .expandGroup(theParameters.getGroupId(), partitionId)); + patientPidsToExport.addAll(myMdmLinkExpandSvc.expandGroup(theParameters.getGroupId(), partitionId)); } return patientPidsToExport; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java index f08fffc689b6..eaa54d82c522 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java @@ -29,7 +29,6 @@ import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; import ca.uhn.fhir.jpa.model.dao.JpaPid; -import ca.uhn.fhir.mdm.svc.MdmExpandersHolder; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import jakarta.persistence.EntityManager; import org.springframework.context.annotation.Bean; @@ -47,8 +46,8 @@ public IBulkExportProcessor jpaBulkExportProcessor( IIdHelperService theIdHelperService, EntityManager theEntityManager, IHapiTransactionService theHapiTransactionService, - ISearchParamRegistry theSearchParamRegistry, - MdmExpandersHolder theMdmExpandersHolder) { + ISearchParamRegistry theSearchParamRegistry + ) { return new JpaBulkExportProcessor( theFhirContext, theBulkExportHelperService, @@ -58,8 +57,8 @@ public IBulkExportProcessor jpaBulkExportProcessor( theIdHelperService, theEntityManager, theHapiTransactionService, - theSearchParamRegistry, - theMdmExpandersHolder); + theSearchParamRegistry + ); } @Bean diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index acf2b94bff19..1d5b0cdac900 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -30,46 +30,35 @@ import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; +import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory; -import ca.uhn.fhir.mdm.svc.BulkExportMdmEidMatchOnlyResourceExpander; -import ca.uhn.fhir.mdm.svc.BulkExportMdmResourceExpander; +import ca.uhn.fhir.mdm.svc.DisabledMdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmEidMatchOnlyExpandSvc; -import ca.uhn.fhir.mdm.svc.MdmExpandersHolder; -import ca.uhn.fhir.mdm.svc.MdmExpansionCacheSvc; import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; + +import java.util.Optional; @Configuration public class MdmJpaConfig { + /** + * Based on the rules laid out in the {@link IMdmSettings} file, construct an {@link IMdmLinkExpandSvc} that is suitable + */ +// FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! @Bean - public MdmExpandersHolder mdmLinkExpandSvcHolder( - FhirContext theFhirContext, - IMdmLinkExpandSvc theMdmLinkExpandSvc, - MdmEidMatchOnlyExpandSvc theMdmEidMatchOnlyLinkExpandSvc, - BulkExportMdmEidMatchOnlyResourceExpander theBulkExportMdmEidMatchOnlyResourceExpander, - BulkExportMdmResourceExpander theBulkExportMdmResourceExpander) { - return new MdmExpandersHolder( - theFhirContext, - theMdmLinkExpandSvc, - theMdmEidMatchOnlyLinkExpandSvc, - theBulkExportMdmResourceExpander, - theBulkExportMdmEidMatchOnlyResourceExpander); - } - - @Bean - public MdmEidMatchOnlyExpandSvc mdmEidMatchOnlyLinkExpandSvc(DaoRegistry theDaoRegistry) { - return new MdmEidMatchOnlyExpandSvc(theDaoRegistry); - } - - @Bean - @Primary - public IMdmLinkExpandSvc mdmLinkExpandSvc() { - return new MdmLinkExpandSvc(); + public IMdmLinkExpandSvc mdmLinkExpandSvc(Optional theMdmSettings, DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { + if (theMdmSettings.isPresent()) { + if (theMdmSettings.get().supportsLinkBasedExpansion()) { + return new MdmLinkExpandSvc(); + } else if (theMdmSettings.get().supportsEidBasedExpansion()) { + return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService); + } + } + return new DisabledMdmLinkExpandSvc(); } @Bean @@ -82,34 +71,13 @@ public IMdmLinkDao mdmLinkDao() { return new MdmLinkDaoJpaImpl(); } - @Bean - public BulkExportMdmResourceExpander bulkExportMDMResourceExpander( - MdmExpansionCacheSvc theMdmExpansionCacheSvc, - IMdmLinkDao theMdmLinkDao, - IIdHelperService theIdHelperService, - DaoRegistry theDaoRegistry, - FhirContext theFhirContext) { - return new BulkExportMdmResourceExpander( - theMdmExpansionCacheSvc, theMdmLinkDao, theIdHelperService, theDaoRegistry, theFhirContext); - } - - @Bean - public BulkExportMdmEidMatchOnlyResourceExpander bulkExportMDMEidMatchOnlyResourceExpander( - DaoRegistry theDaoRegistry, - MdmEidMatchOnlyExpandSvc theMdmEidMatchOnlyLinkExpandSvc, - FhirContext theFhirContext, - IIdHelperService theIdHelperService) { - return new BulkExportMdmEidMatchOnlyResourceExpander( - theDaoRegistry, theMdmEidMatchOnlyLinkExpandSvc, theFhirContext, theIdHelperService); - } - @Bean public IMdmLinkImplFactory mdmLinkImplFactory() { return new JpaMdmLinkImplFactory(); } @Bean - public IMdmClearHelperSvc helperSvc(IDeleteExpungeSvc theDeleteExpungeSvc) { + public IMdmClearHelperSvc mdmClearHelperSvc(IDeleteExpungeSvc theDeleteExpungeSvc) { return new MdmClearHelperSvcImpl(theDeleteExpungeSvc); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java index 3a1adefeffc1..71943f7e7e98 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java @@ -8,7 +8,8 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.svc.IIdHelperService; -import ca.uhn.fhir.mdm.svc.IBulkExportMdmResourceExpander; +import ca.uhn.fhir.mdm.api.IMdmLink; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.jpa.bulk.export.model.ExportPIDIteratorParameters; import ca.uhn.fhir.jpa.dao.IResultIterator; import ca.uhn.fhir.jpa.dao.ISearchBuilder; @@ -19,7 +20,6 @@ import ca.uhn.fhir.jpa.model.search.SearchBuilderLoadIncludesParameters; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.svc.MdmExpandersHolder; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.server.RequestDetails; @@ -131,10 +131,7 @@ public JpaPid next() { private IIdHelperService myIdHelperService; @Mock - private MdmExpandersHolder myMdmExpandersHolder; - - @Mock - private IBulkExportMdmResourceExpander myBulkExportMDMResourceExpander; + private IMdmLinkExpandSvc myMdmLinkExpanderService; @Mock private ISearchParamRegistry mySearchParamRegistry; @@ -299,9 +296,8 @@ public void getResourcePidIterator_groupExportStyleWithPatientResource_returnsIt final JpaPid mdmExpandedPatientId = JpaPid.fromId(4567L); if (theMdm) { - when(myMdmExpandersHolder.getBulkExportMDMResourceExpanderInstance()).thenReturn(myBulkExportMDMResourceExpander); // mock the call to expandGroup method of the expander - when(myBulkExportMDMResourceExpander.expandGroup(parameters.getGroupId(), getPartitionIdFromParams(thePartitioned))) + when(myMdmLinkExpanderService.expandGroup(parameters.getGroupId(), getPartitionIdFromParams(thePartitioned))) .thenReturn(Set.of(mdmExpandedPatientId)); } @@ -395,9 +391,8 @@ public void getResourcePidIterator_groupExportStyleWithNonPatientResource_return .thenReturn(observationResultsIterator); if (theMdm) { - when(myMdmExpandersHolder.getBulkExportMDMResourceExpanderInstance()).thenReturn(myBulkExportMDMResourceExpander); // mock the call to expandGroup method of the expander - when(myBulkExportMDMResourceExpander.expandGroup(parameters.getGroupId(), getPartitionIdFromParams(thePartitioned))) + when(myMdmLinkExpanderService.expandGroup(parameters.getGroupId(), getPartitionIdFromParams(thePartitioned))) .thenReturn(Collections.emptySet()); } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmReadVirtualizationInterceptorTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmReadVirtualizationInterceptorTest.java index 001b4b57b501..117332b4022a 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmReadVirtualizationInterceptorTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/interceptor/MdmReadVirtualizationInterceptorTest.java @@ -9,9 +9,7 @@ import ca.uhn.fhir.jpa.mdm.helper.testmodels.MDMState; import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.interceptor.MdmReadVirtualizationInterceptor; -import ca.uhn.fhir.mdm.svc.MdmExpandersHolder; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.SystemRequestDetails; diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java index 986796df5535..75c0d87fab7a 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java @@ -12,6 +12,7 @@ import ca.uhn.fhir.jpa.api.model.BulkExportJobResults; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse; +import ca.uhn.fhir.jpa.bulk.config.MdmRulesWithEidMatchOnlyConfig; import ca.uhn.fhir.jpa.bulk.export.model.BulkExportResponseJson; import ca.uhn.fhir.jpa.dao.data.IBatch2JobInstanceRepository; import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkRepository; @@ -20,11 +21,13 @@ import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; +import ca.uhn.fhir.mdm.api.IMdmRuleValidator; +import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.api.MdmModeEnum; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; -import ca.uhn.fhir.mdm.svc.MdmExpandersHolder; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.MethodOutcome; @@ -75,6 +78,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; import java.io.IOException; import java.util.ArrayList; @@ -102,14 +108,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; - public class BulkExportUseCaseTest extends BaseResourceProviderR4Test { private static final Logger ourLog = LoggerFactory.getLogger(BulkExportUseCaseTest.class); private static final String TEST_PATIENT_EID_SYS = "http://patient-eid-sys"; @Autowired private IJobCoordinator myJobCoordinator; - @Autowired private IJobPersistence myJobPersistence; @Autowired @@ -123,14 +127,13 @@ public class BulkExportUseCaseTest extends BaseResourceProviderR4Test { @Autowired private MdmRuleValidator myMdmRulesValidator; @Autowired - private MdmExpandersHolder myMdmExpandersHolder; + private IMdmLinkExpandSvc myMdmLinkExpandSvc; @BeforeEach public void beforeEach() { myStorageSettings.setJobFastTrackingEnabled(false); } - @Nested public class SpecConformanceTests { @@ -359,27 +362,6 @@ public void export_shouldNotExportBinaryResource_whenTypeParameterOmitted() thro } - private String submitBulkExportForTypes(String... theTypes) throws IOException { - return submitBulkExportForTypesWithExportId(null, theTypes); - } - - private String submitBulkExportForTypesWithExportId(String theExportId, String... theTypes) throws IOException { - String typeString = String.join(",", theTypes); - String uri = myClient.getServerBase() + "/$export?_type=" + typeString; - if (!StringUtils.isBlank(theExportId)) { - uri += "&_exportId=" + theExportId; - } - - HttpGet httpGet = new HttpGet(uri); - httpGet.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RESPOND_ASYNC); - String pollingLocation; - try (CloseableHttpResponse status = ourHttpClient.execute(httpGet)) { - Header[] headers = status.getHeaders("Content-Location"); - pollingLocation = headers[0].getValue(); - } - return pollingLocation; - } - @Nested public class SystemBulkExportTests { @@ -684,13 +666,9 @@ public void testExportEmptyResult() { @Nested + @ContextConfiguration(classes = {MdmRulesWithEidMatchOnlyConfig.class}) public class GroupBulkExportTests { - @AfterEach - void tearDown() { - restoreMdmSettingsToDefault(); - } - @Test public void testGroupExportSuccessfulyExportsPatientForwardReferences() { BundleBuilder bb = new BundleBuilder(myFhirContext); @@ -799,6 +777,58 @@ public void testGroupBulkExportMembershipShouldNotExpandIntoOtherGroups() { assertThat(firstMap.get("Patient")).hasSize(1); assertThat(firstMap.get("Group")).hasSize(1); } + @Test + void testGroupExportWithMdmEnabled_EidMatchOnly() { + + BundleBuilder bb = new BundleBuilder(myFhirContext); + + //In this test, we create two patients with the same Eid value for the eid system specified in mdm rules + //and 2 observations referencing one of each of these patients + //Create a group that contains one of the patients. + //When we export the group, we should get both patients and the 2 observations + //in the export as the other patient should be mdm expanded + //based on having the same eid value + Patient pat1 = new Patient(); + pat1.setId("pat-1"); + pat1.addIdentifier(new Identifier().setSystem(TEST_PATIENT_EID_SYS).setValue("the-patient-eid-value")); + bb.addTransactionUpdateEntry(pat1); + + Observation obs1 = new Observation(); + obs1.setId("obs-1"); + obs1.setSubject(new Reference("Patient/pat-1")); + bb.addTransactionUpdateEntry(obs1); + + Patient pat2 = new Patient(); + pat2.setId("pat-2"); + pat2.addIdentifier(new Identifier().setSystem(TEST_PATIENT_EID_SYS).setValue("the-patient-eid-value")); + bb.addTransactionUpdateEntry(pat2); + + Observation obs2 = new Observation(); + obs2.setId("obs-2"); + obs2.setSubject(new Reference("Patient/pat-2")); + bb.addTransactionUpdateEntry(obs2); + + Group group = new Group(); + group.setId("Group/mdm-group"); + group.setActive(true); + group.addMember().getEntity().setReference("Patient/pat-1"); + bb.addTransactionUpdateEntry(group); + + myClient.transaction().withBundle(bb.getBundle()).execute(); + + BulkExportJobResults bulkExportJobResults = startGroupBulkExportJobAndAwaitCompletionForMdmExpand(new HashSet<>(), new HashSet<>(), "mdm-group", true); + Map> exportedResourcesMap = convertJobResultsToResources(bulkExportJobResults); + + assertThat(exportedResourcesMap.keySet()).hasSize(3); + List exportedGroups = exportedResourcesMap.get("Group"); + assertResourcesIds(exportedGroups, "Group/mdm-group"); + + List exportedPatients = exportedResourcesMap.get("Patient"); + assertResourcesIds(exportedPatients, "Patient/pat-1", "Patient/pat-2"); + + List exportedObservations = exportedResourcesMap.get("Observation"); + assertResourcesIds(exportedObservations, "Observation/obs-1", "Observation/obs-2"); + } @Test public void testDifferentTypesDoNotUseCachedResults() { @@ -1676,6 +1706,26 @@ void testBulkExportJobParametersBuilder_includeHistoryParameter_handlesNullParam } + private String submitBulkExportForTypes(String... theTypes) throws IOException { + return submitBulkExportForTypesWithExportId(null, theTypes); + } + + private String submitBulkExportForTypesWithExportId(String theExportId, String... theTypes) throws IOException { + String typeString = String.join(",", theTypes); + String uri = myClient.getServerBase() + "/$export?_type=" + typeString; + if (!StringUtils.isBlank(theExportId)) { + uri += "&_exportId=" + theExportId; + } + + HttpGet httpGet = new HttpGet(uri); + httpGet.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RESPOND_ASYNC); + String pollingLocation; + try (CloseableHttpResponse status = ourHttpClient.execute(httpGet)) { + Header[] headers = status.getHeaders("Content-Location"); + pollingLocation = headers[0].getValue(); + } + return pollingLocation; + } private Map>> convertJobResultsToResourceVersionMap(BulkExportJobResults theBulkExportJobResults) { Map> exportedResourcesByType = convertJobResultsToResources(theBulkExportJobResults); @@ -1863,77 +1913,10 @@ private IIdType createPatient() { return myPatientDao.create(p, mySrd).getId(); } - @Test - void testGroupExportWithMdmEnabled_EidMatchOnly() { - - createAndSetMdmSettingsForEidMatchOnly(); - BundleBuilder bb = new BundleBuilder(myFhirContext); - - //In this test, we create two patients with the same Eid value for the eid system specified in mdm rules - //and 2 observations referencing one of each of these patients - //Create a group that contains one of the patients. - //When we export the group, we should get both patients and the 2 observations - //in the export as the other patient should be mdm expanded - //based on having the same eid value - Patient pat1 = new Patient(); - pat1.setId("pat-1"); - pat1.addIdentifier(new Identifier().setSystem(TEST_PATIENT_EID_SYS).setValue("the-patient-eid-value")); - bb.addTransactionUpdateEntry(pat1); - - Observation obs1 = new Observation(); - obs1.setId("obs-1"); - obs1.setSubject(new Reference("Patient/pat-1")); - bb.addTransactionUpdateEntry(obs1); - - Patient pat2 = new Patient(); - pat2.setId("pat-2"); - pat2.addIdentifier(new Identifier().setSystem(TEST_PATIENT_EID_SYS).setValue("the-patient-eid-value")); - bb.addTransactionUpdateEntry(pat2); - - Observation obs2 = new Observation(); - obs2.setId("obs-2"); - obs2.setSubject(new Reference("Patient/pat-2")); - bb.addTransactionUpdateEntry(obs2); - Group group = new Group(); - group.setId("Group/mdm-group"); - group.setActive(true); - group.addMember().getEntity().setReference("Patient/pat-1"); - bb.addTransactionUpdateEntry(group); - - myClient.transaction().withBundle(bb.getBundle()).execute(); - BulkExportJobResults bulkExportJobResults = startGroupBulkExportJobAndAwaitCompletionForMdmExpand(new HashSet<>(), new HashSet<>(), "mdm-group", true); - Map> exportedResourcesMap = convertJobResultsToResources(bulkExportJobResults); - assertThat(exportedResourcesMap.keySet()).hasSize(3); - List exportedGroups = exportedResourcesMap.get("Group"); - assertResourcesIds(exportedGroups, "Group/mdm-group"); - List exportedPatients = exportedResourcesMap.get("Patient"); - assertResourcesIds(exportedPatients, "Patient/pat-1", "Patient/pat-2"); - - List exportedObservations = exportedResourcesMap.get("Observation"); - assertResourcesIds(exportedObservations, "Observation/obs-1", "Observation/obs-2"); - - } - - - private void createAndSetMdmSettingsForEidMatchOnly() { - MdmSettings mdmSettings = new MdmSettings(myMdmRulesValidator); - mdmSettings.setEnabled(true); - mdmSettings.setMdmMode(MdmModeEnum.MATCH_ONLY); - MdmRulesJson rules = new MdmRulesJson(); - rules.setMdmTypes(List.of("Patient")); - rules.addEnterpriseEIDSystem("Patient", TEST_PATIENT_EID_SYS); - mdmSettings.setMdmRules(rules); - - myMdmExpandersHolder.setMdmSettings(mdmSettings); - } - - private void restoreMdmSettingsToDefault() { - myMdmExpandersHolder.setMdmSettings(new MdmSettings(myMdmRulesValidator)); - } private static void assertResourcesIds(List theResources, String... theExpectedResourceIds) { assertThat(theResources).hasSize(theExpectedResourceIds.length); @@ -2178,4 +2161,6 @@ private void verifyBulkExportResults(@SuppressWarnings("SameParameterValue") Str private BulkExportJobResults startPatientBulkExportJobAndAwaitResults(HashSet theTypes, HashSet theFilters, @SuppressWarnings("SameParameterValue") String thePatientId) { return startBulkExportJobAndAwaitCompletion(BulkExportJobParameters.ExportStyle.PATIENT, theTypes, theFilters, thePatientId, false); } + + } diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java new file mode 100644 index 000000000000..428d3d86299b --- /dev/null +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java @@ -0,0 +1,28 @@ +package ca.uhn.fhir.jpa.bulk.config; + +import ca.uhn.fhir.mdm.api.IMdmRuleValidator; +import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.api.MdmModeEnum; +import ca.uhn.fhir.mdm.rules.config.MdmSettings; +import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +@Configuration +public class MdmRulesWithEidMatchOnlyConfig { + public static final String TEST_PATIENT_EID_SYS = "http://patient-eid-sys"; + + @Bean + public IMdmSettings mdmSettings(IMdmRuleValidator theMdmRuleValidator) { + MdmSettings mdmSettings = new MdmSettings(theMdmRuleValidator); + mdmSettings.setEnabled(true); + mdmSettings.setMdmMode(MdmModeEnum.MATCH_ONLY); + MdmRulesJson rules = new MdmRulesJson(); + rules.setMdmTypes(List.of("Patient")); + rules.addEnterpriseEIDSystem("Patient", TEST_PATIENT_EID_SYS); + mdmSettings.setMdmRules(rules); + return mdmSettings; + } +} diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java index 58bf58380037..2125d35a7dc8 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java @@ -43,9 +43,7 @@ import ca.uhn.fhir.jpa.test.util.SubscriptionTestUtil; import ca.uhn.fhir.jpa.util.LoggingEmailSender; import ca.uhn.fhir.mdm.api.IMdmRuleValidator; -import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; -import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.system.HapiTestSystemProperties; import jakarta.persistence.EntityManagerFactory; diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java index bd52509dc8f3..8ce46aa19549 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.mdm.api; import ca.uhn.fhir.interceptor.model.RequestPartitionId; +import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -41,4 +42,15 @@ Set expandMdmByGoldenResourcePid( RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid); Set expandMdmByGoldenResourceId(RequestPartitionId theRequestPartitionId, IIdType theId); + + /** + * For the Group resource with the given id, returns all the persistent id ofs + * the members of the group + the mdm matched resources to a member in the group + */ + Set expandGroup(String groupResourceId, RequestPartitionId requestPartitionId); + /** + * annotates the given resource to be exported with the implementation specific extra information if applicable + */ + void annotateResource(IBaseResource resource); + } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java index 4c64fe9e8a68..bf923cc324cb 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java @@ -53,6 +53,20 @@ default String getSupportedMdmTypes() { return getMdmRules().getMdmTypes().stream().collect(Collectors.joining(", ")); } + /** + * Link based expansion (using the {@link IMdmLink}) table is enabled if MDM is running in MATCH_AND_LINK mode. + */ + default boolean supportsLinkBasedExpansion() { + return getMode().equals(MdmModeEnum.MATCH_AND_LINK); + } + + /** + * EID-Based expansion is supported if MDM is running in MATCH_ONLY mode, and at least one EID system is defined. + */ + default boolean supportsEidBasedExpansion() { + return getMode().equals(MdmModeEnum.MATCH_ONLY) && getMdmRules().getEnterpriseEIDSystems().isEmpty(); + } + int getCandidateSearchLimit(); String getGoldenResourcePartitionName(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmEidMatchOnlyResourceExpander.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmEidMatchOnlyResourceExpander.java deleted file mode 100644 index 2239db8e6412..000000000000 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmEidMatchOnlyResourceExpander.java +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * #%L - * HAPI FHIR - Master Data Management - * %% - * Copyright (C) 2014 - 2025 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% - */ -package ca.uhn.fhir.mdm.svc; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.interceptor.model.RequestPartitionId; -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; -import ca.uhn.fhir.jpa.api.svc.IIdHelperService; -import ca.uhn.fhir.jpa.api.svc.ResolveIdentityMode; -import ca.uhn.fhir.jpa.model.dao.JpaPid; -import ca.uhn.fhir.rest.api.server.SystemRequestDetails; -import ca.uhn.fhir.util.FhirTerser; -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 java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Implementation of {@link IBulkExportMdmResourceExpander} that handles bulk export resource expansion - * when MDM mode is Match-Only and Eid Systems defined in mdm rules. - * - *

This expander is used during bulk export operations to expand Group resources by resolving - * MDM matching resources for the members in the group. Resources are - * matched based on just eids rather than the full MDM golden resource relationships.

- */ -public class BulkExportMdmEidMatchOnlyResourceExpander implements IBulkExportMdmResourceExpander { - - private final DaoRegistry myDaoRegistry; - private final MdmEidMatchOnlyExpandSvc myMdmEidMatchOnlyLinkExpandSvc; - private final FhirContext myFhirContext; - private final IIdHelperService myIdHelperService; - - /** - * Constructor - */ - public BulkExportMdmEidMatchOnlyResourceExpander( - DaoRegistry theDaoRegistry, - MdmEidMatchOnlyExpandSvc theMdmEidMatchOnlyLinkExpandSvc, - FhirContext theFhirContext, - IIdHelperService theIdHelperService) { - myDaoRegistry = theDaoRegistry; - myMdmEidMatchOnlyLinkExpandSvc = theMdmEidMatchOnlyLinkExpandSvc; - myFhirContext = theFhirContext; - myIdHelperService = theIdHelperService; - } - - /** - * Expands a Group resource and returns the Group members' resource persistent ids. - * The returned ids consists of group members + all MDM matched resources based on EID only. - * - *

This method:

- *
    - *
  1. Reads the specified Group resource
  2. - *
  3. Extracts all member entity references from the Group
  4. - *
  5. For each member, uses EID matching to find all resources that have the same EID as the member, using eid system specified in mdm rules
  6. - *
  7. Converts the expanded resource IDs to persistent IDs (PIDs)
  8. - *
- * - * @param groupResourceId The ID of the Group resource to expand - * @param requestPartitionId The request partition ID - * @return A set of {@link JpaPid} objects representing all expanded resources - */ - @Override - public Set expandGroup(String groupResourceId, RequestPartitionId requestPartitionId) { - // Read the Group resource - SystemRequestDetails srd = SystemRequestDetails.forRequestPartitionId(requestPartitionId); - IIdType groupId = myFhirContext.getVersion().newIdType(groupResourceId); - IFhirResourceDao groupDao = myDaoRegistry.getResourceDao("Group"); - IBaseResource groupResource = groupDao.read(groupId, srd); - - Set allResourceIds = new HashSet<>(); - FhirTerser terser = myFhirContext.newTerser(); - // Extract all member.entity references from the Group resource - List memberEntities = - terser.getValues(groupResource, "Group.member.entity", IBaseReference.class); - // mdm expand each member based on eid - for (IBaseReference entityRef : memberEntities) { - if (!entityRef.getReferenceElement().isEmpty()) { - IIdType memberId = entityRef.getReferenceElement(); - Set expanded = - myMdmEidMatchOnlyLinkExpandSvc.expandMdmBySourceResourceId(requestPartitionId, memberId); - allResourceIds.addAll(expanded); - } - } - // Convert all resourceIds to IIdType and resolve in batch - List idTypes = allResourceIds.stream() - .map(id -> myFhirContext.getVersion().newIdType(id)) - .collect(Collectors.toList()); - List pidList = myIdHelperService.resolveResourcePids( - requestPartitionId, - idTypes, - ResolveIdentityMode.excludeDeleted().cacheOk()); - return new HashSet<>(pidList); - } - - @Override - public void annotateResource(IBaseResource resource) { - // This function is normally used to add golden resource id to the exported resources, - // but in the Eid-based match only mode, there isn't any golden resource, so nothing to do here - } -} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmResourceExpander.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmResourceExpander.java deleted file mode 100644 index 06b12dac3a71..000000000000 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/BulkExportMdmResourceExpander.java +++ /dev/null @@ -1,228 +0,0 @@ -/*- - * #%L - * HAPI FHIR - Master Data Management - * %% - * Copyright (C) 2014 - 2025 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% - */ -package ca.uhn.fhir.mdm.svc; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.fhirpath.IFhirPath; -import ca.uhn.fhir.i18n.Msg; -import ca.uhn.fhir.interceptor.model.RequestPartitionId; -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap; -import ca.uhn.fhir.jpa.api.svc.IIdHelperService; -import ca.uhn.fhir.jpa.model.dao.JpaPid; -import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; -import ca.uhn.fhir.mdm.dao.IMdmLinkDao; -import ca.uhn.fhir.mdm.model.MdmPidTuple; -import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.rest.api.server.SystemRequestDetails; -import ca.uhn.fhir.util.ExtensionUtil; -import ca.uhn.fhir.util.HapiExtensions; -import ca.uhn.fhir.util.SearchParameterUtil; -import org.apache.commons.lang3.StringUtils; -import org.hl7.fhir.instance.model.api.IBaseExtension; -import org.hl7.fhir.instance.model.api.IBaseReference; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * Implementation of MDM resource expansion for bulk export operations. - * Expands group memberships via MDM links and annotates exported resources with golden resource references. - */ -public class BulkExportMdmResourceExpander implements IBulkExportMdmResourceExpander { - private static final Logger ourLog = LoggerFactory.getLogger(BulkExportMdmResourceExpander.class); - - private final MdmExpansionCacheSvc myMdmExpansionCacheSvc; - private final IMdmLinkDao myMdmLinkDao; - private final IIdHelperService myIdHelperService; - private final DaoRegistry myDaoRegistry; - private final FhirContext myContext; - private IFhirPath myFhirPath; - - public BulkExportMdmResourceExpander( - MdmExpansionCacheSvc theMdmExpansionCacheSvc, - IMdmLinkDao theMdmLinkDao, - IIdHelperService theIdHelperService, - DaoRegistry theDaoRegistry, - FhirContext theFhirContext) { - myMdmExpansionCacheSvc = theMdmExpansionCacheSvc; - myMdmLinkDao = theMdmLinkDao; - myIdHelperService = theIdHelperService; - myDaoRegistry = theDaoRegistry; - myContext = theFhirContext; - } - - @Override - public Set expandGroup(String theGroupResourceId, RequestPartitionId theRequestPartitionId) { - IdDt groupId = new IdDt(theGroupResourceId); - SystemRequestDetails requestDetails = new SystemRequestDetails(); - requestDetails.setRequestPartitionId(theRequestPartitionId); - IBaseResource group = myDaoRegistry.getResourceDao("Group").read(groupId, requestDetails); - JpaPid pidOrNull = myIdHelperService.getPidOrNull(theRequestPartitionId, group); - // Attempt to perform MDM Expansion of membership - return performMembershipExpansionViaMdmTable(pidOrNull); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private Set performMembershipExpansionViaMdmTable(JpaPid pidOrNull) { - List> goldenPidTargetPidTuples = - myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); - - Set uniquePids = new HashSet<>(); - goldenPidTargetPidTuples.forEach(tuple -> { - uniquePids.add(tuple.getGoldenPid()); - uniquePids.add(tuple.getSourcePid()); - }); - populateMdmResourceCache(goldenPidTargetPidTuples); - return uniquePids; - } - - /** - * @param thePidTuples - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - private void populateMdmResourceCache(List> thePidTuples) { - if (myMdmExpansionCacheSvc.hasBeenPopulated()) { - return; - } - // First, convert this zipped set of tuples to a map of - // { - // patient/gold-1 -> [patient/1, patient/2] - // patient/gold-2 -> [patient/3, patient/4] - // } - Map> goldenResourceToSourcePidMap = new HashMap<>(); - extract(thePidTuples, goldenResourceToSourcePidMap); - - // Next, lets convert it to an inverted index for fast lookup - // { - // patient/1 -> patient/gold-1 - // patient/2 -> patient/gold-1 - // patient/3 -> patient/gold-2 - // patient/4 -> patient/gold-2 - // } - Map sourceResourceIdToGoldenResourceIdMap = new HashMap<>(); - goldenResourceToSourcePidMap.forEach((key, value) -> { - String goldenResourceId = - myIdHelperService.translatePidIdToForcedIdWithCache(key).orElse(key.toString()); - PersistentIdToForcedIdMap pidsToForcedIds = myIdHelperService.translatePidsToForcedIds(value); - - Set sourceResourceIds = pidsToForcedIds.getResolvedResourceIds(); - - sourceResourceIds.forEach( - sourceResourceId -> sourceResourceIdToGoldenResourceIdMap.put(sourceResourceId, goldenResourceId)); - }); - - // Now that we have built our cached expansion, store it. - myMdmExpansionCacheSvc.setCacheContents(sourceResourceIdToGoldenResourceIdMap); - } - - private void extract( - List> theGoldenPidTargetPidTuples, - Map> theGoldenResourceToSourcePidMap) { - for (MdmPidTuple goldenPidTargetPidTuple : theGoldenPidTargetPidTuples) { - JpaPid goldenPid = goldenPidTargetPidTuple.getGoldenPid(); - JpaPid sourcePid = goldenPidTargetPidTuple.getSourcePid(); - theGoldenResourceToSourcePidMap - .computeIfAbsent(goldenPid, key -> new HashSet<>()) - .add(sourcePid); - } - } - - private RuntimeSearchParam getRuntimeSearchParam(IBaseResource theResource) { - Optional oPatientSearchParam = - SearchParameterUtil.getOnlyPatientSearchParamForResourceType(myContext, theResource.fhirType()); - if (!oPatientSearchParam.isPresent()) { - String errorMessage = String.format( - "[%s] has no search parameters that are for patients, so it is invalid for Group Bulk Export!", - theResource.fhirType()); - throw new IllegalArgumentException(Msg.code(2242) + errorMessage); - } else { - return oPatientSearchParam.get(); - } - } - - @Override - public void annotateResource(IBaseResource iBaseResource) { - Optional patientReference = getPatientReference(iBaseResource); - if (patientReference.isPresent()) { - addGoldenResourceExtension(iBaseResource, patientReference.get()); - } else { - ourLog.error( - "Failed to find the patient reference information for resource {}. This is a bug, " - + "as all resources which can be exported via Group Bulk Export must reference a patient.", - iBaseResource); - } - } - - private Optional getPatientReference(IBaseResource iBaseResource) { - String fhirPath; - - RuntimeSearchParam runtimeSearchParam = getRuntimeSearchParam(iBaseResource); - fhirPath = getPatientFhirPath(runtimeSearchParam); - - if (iBaseResource.fhirType().equalsIgnoreCase("Patient")) { - return Optional.of(iBaseResource.getIdElement().getIdPart()); - } else { - Optional optionalReference = - getFhirParser().evaluateFirst(iBaseResource, fhirPath, IBaseReference.class); - if (optionalReference.isPresent()) { - return optionalReference.map(theIBaseReference -> - theIBaseReference.getReferenceElement().getIdPart()); - } else { - return Optional.empty(); - } - } - } - - private void addGoldenResourceExtension(IBaseResource iBaseResource, String sourceResourceId) { - String goldenResourceId = myMdmExpansionCacheSvc.getGoldenResourceId(sourceResourceId); - IBaseExtension extension = ExtensionUtil.getOrCreateExtension( - iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); - if (!StringUtils.isBlank(goldenResourceId)) { - ExtensionUtil.setExtension(myContext, extension, "reference", prefixPatient(goldenResourceId)); - } - } - - private String prefixPatient(String theResourceId) { - return "Patient/" + theResourceId; - } - - private IFhirPath getFhirParser() { - if (myFhirPath == null) { - myFhirPath = myContext.newFhirPath(); - } - return myFhirPath; - } - - private String getPatientFhirPath(RuntimeSearchParam theRuntimeParam) { - String path = theRuntimeParam.getPath(); - // GGG: Yes this is a stupid hack, but by default this runtime search param will return stuff like - // Observation.subject.where(resolve() is Patient) which unfortunately our FHIRpath evaluator doesn't play - // nicely with - // our FHIRPath evaluator. - if (path.contains(".where")) { - path = path.substring(0, path.indexOf(".where")); - } - return path; - } -} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java new file mode 100644 index 000000000000..83b5decdb914 --- /dev/null +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java @@ -0,0 +1,53 @@ +package ca.uhn.fhir.mdm.svc; + +import ca.uhn.fhir.interceptor.model.RequestPartitionId; +import ca.uhn.fhir.jpa.model.dao.JpaPid; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; +import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; + +import java.util.Set; + +//FIXME GGG unsupportedoperation for all of these. +public class DisabledMdmLinkExpandSvc implements IMdmLinkExpandSvc { + @Override + public Set expandMdmBySourceResource(RequestPartitionId theRequestPartitionId, IBaseResource theResource) { + return Set.of(); + } + + @Override + public Set expandMdmBySourceResourceId(RequestPartitionId theRequestPartitionId, IIdType theId) { + return Set.of(); + } + + @Override + public Set expandMdmBySourceResourcePid(RequestPartitionId theRequestPartitionId, IResourcePersistentId theSourceResourcePid) { + return Set.of(); + } + + @Override + public Set expandMdmByGoldenResourceId(RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid) { + return Set.of(); + } + + @Override + public Set expandMdmByGoldenResourcePid(RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid) { + return Set.of(); + } + + @Override + public Set expandMdmByGoldenResourceId(RequestPartitionId theRequestPartitionId, IIdType theId) { + return Set.of(); + } + + @Override + public Set expandGroup(String groupResourceId, RequestPartitionId requestPartitionId) { + return Set.of(); + } + + @Override + public void annotateResource(IBaseResource resource) { + + } +} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/IBulkExportMdmResourceExpander.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/IBulkExportMdmResourceExpander.java deleted file mode 100644 index 22b83a6cb4b2..000000000000 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/IBulkExportMdmResourceExpander.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * HAPI FHIR - Master Data Management - * %% - * Copyright (C) 2014 - 2025 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% - */ -package ca.uhn.fhir.mdm.svc; - -import ca.uhn.fhir.interceptor.model.RequestPartitionId; -import ca.uhn.fhir.jpa.model.dao.JpaPid; -import org.hl7.fhir.instance.model.api.IBaseResource; - -import java.util.Set; - -/** - * Interface for mdm expanding Group resources on group bulk export - */ -public interface IBulkExportMdmResourceExpander { - - /** - * For the Group resource with the given id, returns all the persistent id ofs - * the members of the group + the mdm matched resources to a member in the group - */ - Set expandGroup(String groupResourceId, RequestPartitionId requestPartitionId); - - /** - * annotates the given resource to be exported with the implementation specific extra information if applicable - */ - void annotateResource(IBaseResource resource); -} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java index 3422455e9fde..24926978b422 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java @@ -19,10 +19,14 @@ */ package ca.uhn.fhir.mdm.svc; +import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; +import ca.uhn.fhir.jpa.api.svc.IIdHelperService; +import ca.uhn.fhir.jpa.api.svc.ResolveIdentityMode; +import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.mdm.model.CanonicalEID; @@ -31,10 +35,13 @@ import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; import ca.uhn.fhir.rest.param.TokenOrListParam; import ca.uhn.fhir.rest.param.TokenParam; +import ca.uhn.fhir.util.FhirTerser; +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 java.util.*; +import java.util.stream.Collectors; /** * MDM link expansion service that is used when MDM mode is Match-Only and eid systems are defined in Mdm rules. @@ -46,8 +53,14 @@ public class MdmEidMatchOnlyExpandSvc implements IMdmLinkExpandSvc { private EIDHelper myEidHelper; - public MdmEidMatchOnlyExpandSvc(DaoRegistry theDaoRegistry) { + private IIdHelperService myIdHelperService; + + private FhirContext myFhirContext; + + public MdmEidMatchOnlyExpandSvc(DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { myDaoRegistry = theDaoRegistry; + myFhirContext = theFhirContext; + myIdHelperService = theIdHelperService; } public void setMyEidHelper(EIDHelper theEidHelper) { @@ -118,4 +131,58 @@ public Set expandMdmByGoldenResourceId(RequestPartitionId theRequestPart // return an emtpy set to rather than an exception to not affect existing code return Collections.emptySet(); } + /** + * Expands a Group resource and returns the Group members' resource persistent ids. + * The returned ids consists of group members + all MDM matched resources based on EID only. + * + *

This method:

+ *
    + *
  1. Reads the specified Group resource
  2. + *
  3. Extracts all member entity references from the Group
  4. + *
  5. For each member, uses EID matching to find all resources that have the same EID as the member, using eid system specified in mdm rules
  6. + *
  7. Converts the expanded resource IDs to persistent IDs (PIDs)
  8. + *
+ * + * @param groupResourceId The ID of the Group resource to expand + * @param requestPartitionId The request partition ID + * @return A set of {@link JpaPid} objects representing all expanded resources + */ + @Override + public Set expandGroup(String groupResourceId, RequestPartitionId requestPartitionId) { + // Read the Group resource + SystemRequestDetails srd = SystemRequestDetails.forRequestPartitionId(requestPartitionId); + IIdType groupId = myFhirContext.getVersion().newIdType(groupResourceId); + IFhirResourceDao groupDao = myDaoRegistry.getResourceDao("Group"); + IBaseResource groupResource = groupDao.read(groupId, srd); + + Set allResourceIds = new HashSet<>(); + FhirTerser terser = myFhirContext.newTerser(); + // Extract all member.entity references from the Group resource + List memberEntities = + terser.getValues(groupResource, "Group.member.entity", IBaseReference.class); + // mdm expand each member based on eid + for (IBaseReference entityRef : memberEntities) { + if (!entityRef.getReferenceElement().isEmpty()) { + IIdType memberId = entityRef.getReferenceElement(); + Set expanded = + this.expandMdmBySourceResourceId(requestPartitionId, memberId); + allResourceIds.addAll(expanded); + } + } + // Convert all resourceIds to IIdType and resolve in batch + List idTypes = allResourceIds.stream() + .map(id -> myFhirContext.getVersion().newIdType(id)) + .collect(Collectors.toList()); + List pidList = myIdHelperService.resolveResourcePids( + requestPartitionId, + idTypes, + ResolveIdentityMode.excludeDeleted().cacheOk()); + return new HashSet<>(pidList); + } + + @Override + public void annotateResource(IBaseResource resource) { + // This function is normally used to add golden resource id to the exported resources, + // but in the Eid-based match only mode, there isn't any golden resource, so nothing to do here + } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpandersHolder.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpandersHolder.java deleted file mode 100644 index f3c423d09abf..000000000000 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpandersHolder.java +++ /dev/null @@ -1,181 +0,0 @@ -/*- - * #%L - * HAPI FHIR - Master Data Management - * %% - * Copyright (C) 2014 - 2025 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% - */ -package ca.uhn.fhir.mdm.svc; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; -import ca.uhn.fhir.mdm.api.IMdmSettings; -import ca.uhn.fhir.mdm.api.MdmModeEnum; -import ca.uhn.fhir.mdm.util.EIDHelper; - -/** - * Holder class that manages two different MDM expansion implementation approaches based on MdmSettings. - *

- * This class addresses the dependency injection challenge where MdmSettings may not be available when these - * service objects are created. It holds references to both implementation approaches and determines which ones - * to use based on the MdmSettings. setMdmSettings method should be called when MdmSettings is constructed or updated - * for proper functioning. - *

- * The two implementation approaches are: - *

- * 1. Eid Match-Only Mode: A simplified approach where resources are matched based solely on - * Enterprise ID (EID) values without creating golden resources or MDM links. This mode is activated when - * MdmSettings specify MATCH_ONLY mode and EID systems are defined. - *

- * 2. Full MDM Mode: The complete MDM solution that creates golden resources and manages - * MDM links between resources. - *

- * Each approach has two service implementations, one for mdm expansion for searches and the other for mdm expansion for group bulk export: - *

- * Eid Match-Only Mode implementations: - * - MdmEidMatchOnlyLinkExpandSvc - * - BulkExportMdmEidMatchOnlyResourceExpander - *

- * Full MDM Mode implementations: - * - MdmLinkExpandSvc - * - BulkExportMdmResourceExpander - *

- * - * This class holds references to these service objects rather than creating them by itself, because some of these service objects have Spring annotations - * like @Transactional, for those annotations to work the objects need to be created by Spring itself. - */ -public class MdmExpandersHolder { - - /** MDM configuration settings used to determine which implementation to use */ - private IMdmSettings myMdmSettings; - - /** Cached instance of the selected link expand service */ - private IMdmLinkExpandSvc myLinkExpandSvcInstanceToUse; - - /** Cached instance of the selected bulk export resource expander */ - private IBulkExportMdmResourceExpander myBulkExportMDMResourceExpanderInstanceToUse; - - /** Full MDM link expand service implementation - * We have to use the interface as the type here instead of concrete implementing class MdmLinkExpandSvc - * because the class has Spring annotations like @Transactional which rely on a Proxy interface implementation and doesn't work if concrete classes are used as beans. */ - private final IMdmLinkExpandSvc myMdmLinkExpandSvc; - - /** EID-only match expand service implementation */ - private final MdmEidMatchOnlyExpandSvc myMdmEidMatchOnlyExpandSvc; - - /** Full MDM bulk export resource expander implementation */ - private final BulkExportMdmResourceExpander myBulkExportMDMResourceExpander; - - /** EID-only match bulk export resource expander implementation */ - private final BulkExportMdmEidMatchOnlyResourceExpander myBulkExportMDMEidMatchOnlyResourceExpander; - - private final FhirContext myFhirContext; - - public MdmExpandersHolder( - FhirContext theFhirContext, - IMdmLinkExpandSvc theMdmLinkExpandSvc, - MdmEidMatchOnlyExpandSvc theMdmEidMatchOnlyLinkExpandSvc, - BulkExportMdmResourceExpander theBulkExportMDMResourceExpander, - BulkExportMdmEidMatchOnlyResourceExpander theBulkExportMDMEidMatchOnlyResourceExpander) { - - myFhirContext = theFhirContext; - myMdmLinkExpandSvc = theMdmLinkExpandSvc; - myMdmEidMatchOnlyExpandSvc = theMdmEidMatchOnlyLinkExpandSvc; - myBulkExportMDMResourceExpander = theBulkExportMDMResourceExpander; - myBulkExportMDMEidMatchOnlyResourceExpander = theBulkExportMDMEidMatchOnlyResourceExpander; - } - - /** - * Returns the appropriate expand service instance appropriate for the mdm settings - */ - public IMdmLinkExpandSvc getLinkExpandSvcInstance() { - if (myLinkExpandSvcInstanceToUse != null) { - // we already determined instance to use, just return it - return myLinkExpandSvcInstanceToUse; - } - - myLinkExpandSvcInstanceToUse = determineExpandSvsInstanceToUse(); - - return myLinkExpandSvcInstanceToUse; - } - - /** - * Returns the appropriate bulk export resource expander instance appropriate for the mdm settings - */ - public IBulkExportMdmResourceExpander getBulkExportMDMResourceExpanderInstance() { - if (myBulkExportMDMResourceExpanderInstanceToUse != null) { - // we already determined instance to use, just return it - return myBulkExportMDMResourceExpanderInstanceToUse; - } - - myBulkExportMDMResourceExpanderInstanceToUse = determineBulkExportMDMResourceExpanderInstanceToUse(); - - return myBulkExportMDMResourceExpanderInstanceToUse; - } - - /** - * Determines which bulk export resource expander to use based on MDM mode and EID configuration. - */ - public IBulkExportMdmResourceExpander determineBulkExportMDMResourceExpanderInstanceToUse() { - if (isMatchOnlyWithEidSystems()) { - return myBulkExportMDMEidMatchOnlyResourceExpander; - } else { - return myBulkExportMDMResourceExpander; - } - } - - /** - * Determines if MDM is configured in MATCH_ONLY mode and EID systems are defined in the MDM rules. - */ - private boolean isMatchOnlyWithEidSystems() { - - if (myMdmSettings == null) { - // if mdmSettings is not set yet, assume we are using the full mdm mode - // to not break existing code, because previously we were just using the - // full mdm implementation without checking the mdm settings. - // This would be called again when mdmSettings setter is called - return false; - } - boolean isMatchOnly = myMdmSettings.getMode() == MdmModeEnum.MATCH_ONLY; - boolean hasEidSystems = false; - if (myMdmSettings.getMdmRules() != null) { - hasEidSystems = myMdmSettings.getMdmRules().getEnterpriseEIDSystems() != null - && !myMdmSettings.getMdmRules().getEnterpriseEIDSystems().isEmpty(); - } - return isMatchOnly && hasEidSystems; - } - - /** - * Determines which expand service to use and configures it if necessary. - */ - private IMdmLinkExpandSvc determineExpandSvsInstanceToUse() { - if (isMatchOnlyWithEidSystems()) { - myMdmEidMatchOnlyExpandSvc.setMyEidHelper(new EIDHelper(myFhirContext, myMdmSettings)); - return myMdmEidMatchOnlyExpandSvc; - } else { - return myMdmLinkExpandSvc; - } - } - - /** - * Sets the MDM settings and immediately determines which service implementations to use. - * This method is called after MDM settings become available during application startup. - */ - public void setMdmSettings(IMdmSettings theMdmSettings) { - myMdmSettings = theMdmSettings; - myLinkExpandSvcInstanceToUse = determineExpandSvsInstanceToUse(); - myBulkExportMDMResourceExpanderInstanceToUse = determineBulkExportMDMResourceExpanderInstanceToUse(); - } -} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 82fb144b9282..189a0f0060b6 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -19,15 +19,31 @@ */ package ca.uhn.fhir.mdm.svc; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.fhirpath.IFhirPath; +import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.interceptor.model.RequestPartitionId; +import ca.uhn.fhir.jpa.api.IDaoRegistry; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; +import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap; import ca.uhn.fhir.jpa.api.svc.IIdHelperService; +import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.model.MdmPidTuple; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.api.server.SystemRequestDetails; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; +import ca.uhn.fhir.util.ExtensionUtil; +import ca.uhn.fhir.util.HapiExtensions; +import ca.uhn.fhir.util.SearchParameterUtil; import jakarta.annotation.Nonnull; +import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.instance.model.api.IBaseExtension; +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.slf4j.Logger; @@ -37,7 +53,11 @@ import java.util.Collection; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -46,13 +66,27 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); + + @Autowired + private FhirContext myContext; + @Autowired IMdmLinkDao myMdmLinkDao; @Autowired IIdHelperService myIdHelperService; - public MdmLinkExpandSvc() {} + @Autowired + private DaoRegistry myDaoRegistry; + + @Autowired + private MdmExpansionCacheSvc myMdmExpansionCacheSvc; + + private IFhirPath myFhirPath; + + public MdmLinkExpandSvc() { + myFhirPath = myContext.newFhirPath(); + } /** * Given a source resource, perform MDM expansion and return all the resource IDs of all resources that are @@ -172,4 +206,146 @@ static Set flattenTuple(RequestPartitionId theRequestPart return Collections.emptySet(); } + + @Override + public Set expandGroup(String theGroupResourceId, RequestPartitionId theRequestPartitionId) { + IdDt groupId = new IdDt(theGroupResourceId); + SystemRequestDetails requestDetails = new SystemRequestDetails(); + requestDetails.setRequestPartitionId(theRequestPartitionId); + IBaseResource group = myDaoRegistry.getResourceDao("Group").read(groupId, requestDetails); +// FIXME GGG think more about this cast. How does mongo do this? + JpaPid pidOrNull = (JpaPid) myIdHelperService.getPidOrNull(theRequestPartitionId, group); + // Attempt to perform MDM Expansion of membership + return performMembershipExpansionViaMdmTable(pidOrNull); + }@ + Override + public void annotateResource(IBaseResource iBaseResource) { + Optional patientReference = getPatientReference(iBaseResource); + if (patientReference.isPresent()) { + addGoldenResourceExtension(iBaseResource, patientReference.get()); + } else { + ourLog.error( + "Failed to find the patient reference information for resource {}. This is a bug, " + + "as all resources which can be exported via Group Bulk Export must reference a patient.", + iBaseResource); + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private Set performMembershipExpansionViaMdmTable(JpaPid pidOrNull) { + List> goldenPidTargetPidTuples = + myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); + + Set uniquePids = new HashSet<>(); + goldenPidTargetPidTuples.forEach(tuple -> { + uniquePids.add(tuple.getGoldenPid()); + uniquePids.add(tuple.getSourcePid()); + }); + populateMdmResourceCache(goldenPidTargetPidTuples); + return uniquePids; + } + /** + * @param thePidTuples + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private void populateMdmResourceCache(List> thePidTuples) { + if (myMdmExpansionCacheSvc.hasBeenPopulated()) { + return; + } + // First, convert this zipped set of tuples to a map of + // { + // patient/gold-1 -> [patient/1, patient/2] + // patient/gold-2 -> [patient/3, patient/4] + // } + Map> goldenResourceToSourcePidMap = new HashMap<>(); + extract(thePidTuples, goldenResourceToSourcePidMap); + + // Next, lets convert it to an inverted index for fast lookup + // { + // patient/1 -> patient/gold-1 + // patient/2 -> patient/gold-1 + // patient/3 -> patient/gold-2 + // patient/4 -> patient/gold-2 + // } + Map sourceResourceIdToGoldenResourceIdMap = new HashMap<>(); + goldenResourceToSourcePidMap.forEach((key, value) -> { + String goldenResourceId = (String) myIdHelperService.translatePidIdToForcedIdWithCache(key).orElseGet(key::toString); + PersistentIdToForcedIdMap pidsToForcedIds = myIdHelperService.translatePidsToForcedIds(value); + + Set sourceResourceIds = pidsToForcedIds.getResolvedResourceIds(); + + sourceResourceIds.forEach( + sourceResourceId -> sourceResourceIdToGoldenResourceIdMap.put(sourceResourceId, goldenResourceId)); + }); + + // Now that we have built our cached expansion, store it. + myMdmExpansionCacheSvc.setCacheContents(sourceResourceIdToGoldenResourceIdMap); + } + private void extract( + List> theGoldenPidTargetPidTuples, + Map> theGoldenResourceToSourcePidMap) { + for (MdmPidTuple goldenPidTargetPidTuple : theGoldenPidTargetPidTuples) { + JpaPid goldenPid = goldenPidTargetPidTuple.getGoldenPid(); + JpaPid sourcePid = goldenPidTargetPidTuple.getSourcePid(); + theGoldenResourceToSourcePidMap + .computeIfAbsent(goldenPid, key -> new HashSet<>()) + .add(sourcePid); + } + } + private Optional getPatientReference(IBaseResource iBaseResource) { + String fhirPath; + + RuntimeSearchParam runtimeSearchParam = getRuntimeSearchParam(iBaseResource); + fhirPath = getPatientFhirPath(runtimeSearchParam); + + if (iBaseResource.fhirType().equalsIgnoreCase("Patient")) { + return Optional.of(iBaseResource.getIdElement().getIdPart()); + } else { + Optional optionalReference = + myFhirPath.evaluateFirst(iBaseResource, fhirPath, IBaseReference.class); + if (optionalReference.isPresent()) { + return optionalReference.map(theIBaseReference -> + theIBaseReference.getReferenceElement().getIdPart()); + } else { + return Optional.empty(); + } + } + } + + private void addGoldenResourceExtension(IBaseResource iBaseResource, String sourceResourceId) { + String goldenResourceId = myMdmExpansionCacheSvc.getGoldenResourceId(sourceResourceId); + IBaseExtension extension = ExtensionUtil.getOrCreateExtension( + iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); + if (!StringUtils.isBlank(goldenResourceId)) { + ExtensionUtil.setExtension(myContext, extension, "reference", prefixPatient(goldenResourceId)); + } + } + + private String prefixPatient(String theResourceId) { + return "Patient/" + theResourceId; + } + + private String getPatientFhirPath(RuntimeSearchParam theRuntimeParam) { + String path = theRuntimeParam.getPath(); + // GGG: Yes this is a stupid hack, but by default this runtime search param will return stuff like + // Observation.subject.where(resolve() is Patient) which unfortunately our FHIRpath evaluator doesn't play + // nicely with + if (path.contains(".where")) { + path = path.substring(0, path.indexOf(".where")); + } + return path; + } + + private RuntimeSearchParam getRuntimeSearchParam(IBaseResource theResource) { + Optional oPatientSearchParam = + SearchParameterUtil.getOnlyPatientSearchParamForResourceType(myContext, theResource.fhirType()); + if (!oPatientSearchParam.isPresent()) { + String errorMessage = String.format( + "[%s] has no search parameters that are for patients, so it is invalid for Group Bulk Export!", + theResource.fhirType()); + throw new IllegalArgumentException(Msg.code(2242) + errorMessage); + } else { + return oPatientSearchParam.get(); + } + } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java index c025086451d2..6f7e6172cfa9 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; +import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.RequestDetails; @@ -53,12 +54,12 @@ public class MdmSearchExpansionSvc { @Autowired private FhirContext myFhirContext; - + @Autowired - private IRequestPartitionHelperSvc myRequestPartitionHelperSvc; + private IMdmLinkExpandSvc myMdmLinkExpandSvc; @Autowired - private MdmExpandersHolder myMdmExpandersHolder; + private IRequestPartitionHelperSvc myRequestPartitionHelperSvc; /** * This method looks through all the reference parameters within a {@link SearchParameterMap} @@ -141,7 +142,6 @@ private void expandAnyReferenceParameters( IParamTester theParamTester, MdmSearchExpansionResults theResultsToPopulate) { - IMdmLinkExpandSvc mdmLinkExpandSvc = myMdmExpandersHolder.getLinkExpandSvcInstance(); List toRemove = new ArrayList<>(); List toAdd = new ArrayList<>(); @@ -153,12 +153,12 @@ private void expandAnyReferenceParameters( // First, attempt to expand as a source resource. IIdType sourceId = newId(refParam.getValue()); Set expandedResourceIds = - mdmLinkExpandSvc.expandMdmBySourceResourceId(theRequestPartitionId, sourceId); + myMdmLinkExpandSvc.expandMdmBySourceResourceId(theRequestPartitionId, sourceId); // If we failed, attempt to expand as a golden resource if (expandedResourceIds.isEmpty()) { expandedResourceIds = - mdmLinkExpandSvc.expandMdmByGoldenResourceId(theRequestPartitionId, sourceId); + myMdmLinkExpandSvc.expandMdmByGoldenResourceId(theRequestPartitionId, sourceId); } // Rebuild the search param list. @@ -239,11 +239,10 @@ private void expandIdParameter( } else if (mdmExpand) { ourLog.debug("_id parameter must be expanded out from: {}", id.getValue()); - IMdmLinkExpandSvc mdmLinkExpandSvc = myMdmExpandersHolder.getLinkExpandSvcInstance(); - Set expandedResourceIds = mdmLinkExpandSvc.expandMdmBySourceResourceId(theRequestPartitionId, id); + Set expandedResourceIds = myMdmLinkExpandSvc.expandMdmBySourceResourceId(theRequestPartitionId, id); if (expandedResourceIds.isEmpty()) { - expandedResourceIds = mdmLinkExpandSvc.expandMdmByGoldenResourceId(theRequestPartitionId, id); + expandedResourceIds = myMdmLinkExpandSvc.expandMdmByGoldenResourceId(theRequestPartitionId, id); } // Rebuild From be91a82883ea705834b28016980304344ff2bd0b Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 9 Oct 2025 16:27:32 -0600 Subject: [PATCH 02/29] Fix up an error in construction --- .../export/svc/JpaBulkExportProcessor.java | 22 +++++----- .../fhir/jpa/config/JpaBulkExportConfig.java | 25 ++++++----- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 8 +++- .../uhn/fhir/mdm/api/IMdmLinkExpandSvc.java | 1 - .../ca/uhn/fhir/mdm/api/IMdmSettings.java | 3 +- .../mdm/svc/DisabledMdmLinkExpandSvc.java | 15 ++++--- .../mdm/svc/MdmEidMatchOnlyExpandSvc.java | 20 ++++----- .../ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 44 ++++++++++--------- .../fhir/mdm/svc/MdmSearchExpansionSvc.java | 4 +- 9 files changed, 75 insertions(+), 67 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index ce70403473bd..0790c7e3d683 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -37,6 +37,7 @@ import ca.uhn.fhir.jpa.model.search.SearchBuilderLoadIncludesParameters; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.primitive.IdDt; @@ -90,16 +91,16 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor { @Autowired public JpaBulkExportProcessor( - FhirContext theContext, - BulkExportHelperService theBulkExportHelperSvc, - JpaStorageSettings theStorageSettings, - DaoRegistry theDaoRegistry, - SearchBuilderFactory theSearchBuilderFactory, - IIdHelperService theIdHelperService, - EntityManager theEntityManager, - IHapiTransactionService theHapiTransactionService, - ISearchParamRegistry theSearchParamRegistry - ) { + FhirContext theContext, + BulkExportHelperService theBulkExportHelperSvc, + JpaStorageSettings theStorageSettings, + DaoRegistry theDaoRegistry, + SearchBuilderFactory theSearchBuilderFactory, + IIdHelperService theIdHelperService, + EntityManager theEntityManager, + IHapiTransactionService theHapiTransactionService, + ISearchParamRegistry theSearchParamRegistry, + IMdmLinkExpandSvc theMdmLinkExpandSvc) { myContext = theContext; myBulkExportHelperSvc = theBulkExportHelperSvc; myStorageSettings = theStorageSettings; @@ -109,6 +110,7 @@ public JpaBulkExportProcessor( myEntityManager = theEntityManager; myHapiTransactionService = theHapiTransactionService; mySearchParamRegistry = theSearchParamRegistry; + myMdmLinkExpandSvc = theMdmLinkExpandSvc; } @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java index eaa54d82c522..82ec11daa56f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java @@ -29,6 +29,7 @@ import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; import ca.uhn.fhir.jpa.model.dao.JpaPid; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import jakarta.persistence.EntityManager; import org.springframework.context.annotation.Bean; @@ -38,16 +39,16 @@ public class JpaBulkExportConfig { @Bean public IBulkExportProcessor jpaBulkExportProcessor( - FhirContext theFhirContext, - BulkExportHelperService theBulkExportHelperService, - JpaStorageSettings theJpaStorageSettings, - DaoRegistry theDaoRegistry, - SearchBuilderFactory theSearchBuilderFactory, - IIdHelperService theIdHelperService, - EntityManager theEntityManager, - IHapiTransactionService theHapiTransactionService, - ISearchParamRegistry theSearchParamRegistry - ) { + FhirContext theFhirContext, + BulkExportHelperService theBulkExportHelperService, + JpaStorageSettings theJpaStorageSettings, + DaoRegistry theDaoRegistry, + SearchBuilderFactory theSearchBuilderFactory, + IIdHelperService theIdHelperService, + EntityManager theEntityManager, + IHapiTransactionService theHapiTransactionService, + ISearchParamRegistry theSearchParamRegistry, + IMdmLinkExpandSvc theMdmLinkExpandSvc) { return new JpaBulkExportProcessor( theFhirContext, theBulkExportHelperService, @@ -57,8 +58,8 @@ public IBulkExportProcessor jpaBulkExportProcessor( theIdHelperService, theEntityManager, theHapiTransactionService, - theSearchParamRegistry - ); + theSearchParamRegistry, + theMdmLinkExpandSvc); } @Bean diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 1d5b0cdac900..7821d24f0a36 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -48,9 +48,13 @@ public class MdmJpaConfig { /** * Based on the rules laid out in the {@link IMdmSettings} file, construct an {@link IMdmLinkExpandSvc} that is suitable */ -// FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! + // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! @Bean - public IMdmLinkExpandSvc mdmLinkExpandSvc(Optional theMdmSettings, DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { + public IMdmLinkExpandSvc mdmLinkExpandSvc( + Optional theMdmSettings, + DaoRegistry theDaoRegistry, + FhirContext theFhirContext, + IIdHelperService theIdHelperService) { if (theMdmSettings.isPresent()) { if (theMdmSettings.get().supportsLinkBasedExpansion()) { return new MdmLinkExpandSvc(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java index 8ce46aa19549..8ec772f89d9e 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java @@ -52,5 +52,4 @@ Set expandMdmByGoldenResourcePid( * annotates the given resource to be exported with the implementation specific extra information if applicable */ void annotateResource(IBaseResource resource); - } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java index bf923cc324cb..b8fb22d89a81 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java @@ -64,7 +64,8 @@ default boolean supportsLinkBasedExpansion() { * EID-Based expansion is supported if MDM is running in MATCH_ONLY mode, and at least one EID system is defined. */ default boolean supportsEidBasedExpansion() { - return getMode().equals(MdmModeEnum.MATCH_ONLY) && getMdmRules().getEnterpriseEIDSystems().isEmpty(); + return getMode().equals(MdmModeEnum.MATCH_ONLY) + && getMdmRules().getEnterpriseEIDSystems().isEmpty(); } int getCandidateSearchLimit(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java index 83b5decdb914..af488deaa259 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java @@ -9,7 +9,7 @@ import java.util.Set; -//FIXME GGG unsupportedoperation for all of these. +// FIXME GGG unsupportedoperation for all of these. public class DisabledMdmLinkExpandSvc implements IMdmLinkExpandSvc { @Override public Set expandMdmBySourceResource(RequestPartitionId theRequestPartitionId, IBaseResource theResource) { @@ -22,17 +22,20 @@ public Set expandMdmBySourceResourceId(RequestPartitionId theRequestPart } @Override - public Set expandMdmBySourceResourcePid(RequestPartitionId theRequestPartitionId, IResourcePersistentId theSourceResourcePid) { + public Set expandMdmBySourceResourcePid( + RequestPartitionId theRequestPartitionId, IResourcePersistentId theSourceResourcePid) { return Set.of(); } @Override - public Set expandMdmByGoldenResourceId(RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid) { + public Set expandMdmByGoldenResourceId( + RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid) { return Set.of(); } @Override - public Set expandMdmByGoldenResourcePid(RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid) { + public Set expandMdmByGoldenResourcePid( + RequestPartitionId theRequestPartitionId, IResourcePersistentId theGoldenResourcePid) { return Set.of(); } @@ -47,7 +50,5 @@ public Set expandGroup(String groupResourceId, RequestPartitionId reques } @Override - public void annotateResource(IBaseResource resource) { - - } + public void annotateResource(IBaseResource resource) {} } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java index 24926978b422..2bcbf9ab41bd 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java @@ -40,8 +40,8 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; -import java.util.*; import java.util.stream.Collectors; +import java.util.*; /** * MDM link expansion service that is used when MDM mode is Match-Only and eid systems are defined in Mdm rules. @@ -57,7 +57,8 @@ public class MdmEidMatchOnlyExpandSvc implements IMdmLinkExpandSvc { private FhirContext myFhirContext; - public MdmEidMatchOnlyExpandSvc(DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { + public MdmEidMatchOnlyExpandSvc( + DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { myDaoRegistry = theDaoRegistry; myFhirContext = theFhirContext; myIdHelperService = theIdHelperService; @@ -159,24 +160,23 @@ public Set expandGroup(String groupResourceId, RequestPartitionId reques FhirTerser terser = myFhirContext.newTerser(); // Extract all member.entity references from the Group resource List memberEntities = - terser.getValues(groupResource, "Group.member.entity", IBaseReference.class); + terser.getValues(groupResource, "Group.member.entity", IBaseReference.class); // mdm expand each member based on eid for (IBaseReference entityRef : memberEntities) { if (!entityRef.getReferenceElement().isEmpty()) { IIdType memberId = entityRef.getReferenceElement(); - Set expanded = - this.expandMdmBySourceResourceId(requestPartitionId, memberId); + Set expanded = this.expandMdmBySourceResourceId(requestPartitionId, memberId); allResourceIds.addAll(expanded); } } // Convert all resourceIds to IIdType and resolve in batch List idTypes = allResourceIds.stream() - .map(id -> myFhirContext.getVersion().newIdType(id)) - .collect(Collectors.toList()); + .map(id -> myFhirContext.getVersion().newIdType(id)) + .collect(Collectors.toList()); List pidList = myIdHelperService.resolveResourcePids( - requestPartitionId, - idTypes, - ResolveIdentityMode.excludeDeleted().cacheOk()); + requestPartitionId, + idTypes, + ResolveIdentityMode.excludeDeleted().cacheOk()); return new HashSet<>(pidList); } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 189a0f0060b6..332094fb3523 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.fhirpath.IFhirPath; import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.interceptor.model.RequestPartitionId; -import ca.uhn.fhir.jpa.api.IDaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap; import ca.uhn.fhir.jpa.api.svc.IIdHelperService; @@ -66,7 +65,6 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); - @Autowired private FhirContext myContext; @@ -213,28 +211,29 @@ public Set expandGroup(String theGroupResourceId, RequestPartitionId the SystemRequestDetails requestDetails = new SystemRequestDetails(); requestDetails.setRequestPartitionId(theRequestPartitionId); IBaseResource group = myDaoRegistry.getResourceDao("Group").read(groupId, requestDetails); -// FIXME GGG think more about this cast. How does mongo do this? + // FIXME GGG think more about this cast. How does mongo do this? JpaPid pidOrNull = (JpaPid) myIdHelperService.getPidOrNull(theRequestPartitionId, group); // Attempt to perform MDM Expansion of membership return performMembershipExpansionViaMdmTable(pidOrNull); - }@ - Override + } + + @Override public void annotateResource(IBaseResource iBaseResource) { Optional patientReference = getPatientReference(iBaseResource); if (patientReference.isPresent()) { addGoldenResourceExtension(iBaseResource, patientReference.get()); } else { ourLog.error( - "Failed to find the patient reference information for resource {}. This is a bug, " - + "as all resources which can be exported via Group Bulk Export must reference a patient.", - iBaseResource); + "Failed to find the patient reference information for resource {}. This is a bug, " + + "as all resources which can be exported via Group Bulk Export must reference a patient.", + iBaseResource); } } @SuppressWarnings({"rawtypes", "unchecked"}) private Set performMembershipExpansionViaMdmTable(JpaPid pidOrNull) { List> goldenPidTargetPidTuples = - myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); + myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); Set uniquePids = new HashSet<>(); goldenPidTargetPidTuples.forEach(tuple -> { @@ -269,29 +268,32 @@ private void populateMdmResourceCache(List> thePidTuples) { // } Map sourceResourceIdToGoldenResourceIdMap = new HashMap<>(); goldenResourceToSourcePidMap.forEach((key, value) -> { - String goldenResourceId = (String) myIdHelperService.translatePidIdToForcedIdWithCache(key).orElseGet(key::toString); + String goldenResourceId = (String) + myIdHelperService.translatePidIdToForcedIdWithCache(key).orElseGet(key::toString); PersistentIdToForcedIdMap pidsToForcedIds = myIdHelperService.translatePidsToForcedIds(value); Set sourceResourceIds = pidsToForcedIds.getResolvedResourceIds(); sourceResourceIds.forEach( - sourceResourceId -> sourceResourceIdToGoldenResourceIdMap.put(sourceResourceId, goldenResourceId)); + sourceResourceId -> sourceResourceIdToGoldenResourceIdMap.put(sourceResourceId, goldenResourceId)); }); // Now that we have built our cached expansion, store it. myMdmExpansionCacheSvc.setCacheContents(sourceResourceIdToGoldenResourceIdMap); } + private void extract( - List> theGoldenPidTargetPidTuples, - Map> theGoldenResourceToSourcePidMap) { + List> theGoldenPidTargetPidTuples, + Map> theGoldenResourceToSourcePidMap) { for (MdmPidTuple goldenPidTargetPidTuple : theGoldenPidTargetPidTuples) { JpaPid goldenPid = goldenPidTargetPidTuple.getGoldenPid(); JpaPid sourcePid = goldenPidTargetPidTuple.getSourcePid(); theGoldenResourceToSourcePidMap - .computeIfAbsent(goldenPid, key -> new HashSet<>()) - .add(sourcePid); + .computeIfAbsent(goldenPid, key -> new HashSet<>()) + .add(sourcePid); } } + private Optional getPatientReference(IBaseResource iBaseResource) { String fhirPath; @@ -302,10 +304,10 @@ private Optional getPatientReference(IBaseResource iBaseResource) { return Optional.of(iBaseResource.getIdElement().getIdPart()); } else { Optional optionalReference = - myFhirPath.evaluateFirst(iBaseResource, fhirPath, IBaseReference.class); + myFhirPath.evaluateFirst(iBaseResource, fhirPath, IBaseReference.class); if (optionalReference.isPresent()) { return optionalReference.map(theIBaseReference -> - theIBaseReference.getReferenceElement().getIdPart()); + theIBaseReference.getReferenceElement().getIdPart()); } else { return Optional.empty(); } @@ -315,7 +317,7 @@ private Optional getPatientReference(IBaseResource iBaseResource) { private void addGoldenResourceExtension(IBaseResource iBaseResource, String sourceResourceId) { String goldenResourceId = myMdmExpansionCacheSvc.getGoldenResourceId(sourceResourceId); IBaseExtension extension = ExtensionUtil.getOrCreateExtension( - iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); + iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); if (!StringUtils.isBlank(goldenResourceId)) { ExtensionUtil.setExtension(myContext, extension, "reference", prefixPatient(goldenResourceId)); } @@ -338,11 +340,11 @@ private String getPatientFhirPath(RuntimeSearchParam theRuntimeParam) { private RuntimeSearchParam getRuntimeSearchParam(IBaseResource theResource) { Optional oPatientSearchParam = - SearchParameterUtil.getOnlyPatientSearchParamForResourceType(myContext, theResource.fhirType()); + SearchParameterUtil.getOnlyPatientSearchParamForResourceType(myContext, theResource.fhirType()); if (!oPatientSearchParam.isPresent()) { String errorMessage = String.format( - "[%s] has no search parameters that are for patients, so it is invalid for Group Bulk Export!", - theResource.fhirType()); + "[%s] has no search parameters that are for patients, so it is invalid for Group Bulk Export!", + theResource.fhirType()); throw new IllegalArgumentException(Msg.code(2242) + errorMessage); } else { return oPatientSearchParam.get(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java index 6f7e6172cfa9..3f2d38d8987d 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmSearchExpansionSvc.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; -import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.RequestDetails; @@ -54,7 +53,7 @@ public class MdmSearchExpansionSvc { @Autowired private FhirContext myFhirContext; - + @Autowired private IMdmLinkExpandSvc myMdmLinkExpandSvc; @@ -142,7 +141,6 @@ private void expandAnyReferenceParameters( IParamTester theParamTester, MdmSearchExpansionResults theResultsToPopulate) { - List toRemove = new ArrayList<>(); List toAdd = new ArrayList<>(); for (IQueryParameterType iQueryParameterType : orList) { From daa3e4866c837520c620abba6aef94d3d9c17b4f Mon Sep 17 00:00:00 2001 From: Gary Date: Thu, 9 Oct 2025 16:59:29 -0600 Subject: [PATCH 03/29] failing test location --- .../main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 8 +++----- .../java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 7821d24f0a36..b98bba92a7c1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -51,17 +51,15 @@ public class MdmJpaConfig { // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! @Bean public IMdmLinkExpandSvc mdmLinkExpandSvc( - Optional theMdmSettings, + IMdmSettings theMdmSettings, DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { - if (theMdmSettings.isPresent()) { - if (theMdmSettings.get().supportsLinkBasedExpansion()) { + if (theMdmSettings.supportsLinkBasedExpansion()) { return new MdmLinkExpandSvc(); - } else if (theMdmSettings.get().supportsEidBasedExpansion()) { + } else if (theMdmSettings.supportsEidBasedExpansion()) { return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService); } - } return new DisabledMdmLinkExpandSvc(); } diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java index 75c0d87fab7a..2873e97552db 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java @@ -108,6 +108,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +@ContextConfiguration(classes = {MdmRulesWithEidMatchOnlyConfig.class}) public class BulkExportUseCaseTest extends BaseResourceProviderR4Test { private static final Logger ourLog = LoggerFactory.getLogger(BulkExportUseCaseTest.class); @@ -666,7 +667,6 @@ public void testExportEmptyResult() { @Nested - @ContextConfiguration(classes = {MdmRulesWithEidMatchOnlyConfig.class}) public class GroupBulkExportTests { @Test @@ -779,6 +779,7 @@ public void testGroupBulkExportMembershipShouldNotExpandIntoOtherGroups() { } @Test void testGroupExportWithMdmEnabled_EidMatchOnly() { + //FIXME GGG TEST FAILING START HERE. BundleBuilder bb = new BundleBuilder(myFhirContext); From 58db184db5be64c217a1aa587d8b0b756435d3b8 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 10 Oct 2025 12:12:14 -0400 Subject: [PATCH 04/29] Remove dead annotation, fix logic bug in new method for determining whether eid expansion is supported --- .../src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java | 2 +- .../src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java index b8fb22d89a81..f2d815024456 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java @@ -65,7 +65,7 @@ default boolean supportsLinkBasedExpansion() { */ default boolean supportsEidBasedExpansion() { return getMode().equals(MdmModeEnum.MATCH_ONLY) - && getMdmRules().getEnterpriseEIDSystems().isEmpty(); + && !getMdmRules().getEnterpriseEIDSystems().isEmpty(); } int getCandidateSearchLimit(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java index 9930cc7690e2..ad8deb769d5a 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java @@ -33,7 +33,6 @@ import java.util.UUID; import java.util.stream.Collectors; -@Service public class EIDHelper { private final FhirContext myFhirContext; From 4a9663f9632830a6d3379d2c1719dfafd0f9ae3b Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 10 Oct 2025 12:13:06 -0400 Subject: [PATCH 05/29] Spotless --- .../export/svc/JpaBulkExportProcessor.java | 21 +++++++++---------- .../fhir/jpa/config/JpaBulkExportConfig.java | 20 +++++++++--------- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 12 +++++------ .../java/ca/uhn/fhir/mdm/util/EIDHelper.java | 1 - 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index 0790c7e3d683..18f17cd2acd6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -37,7 +37,6 @@ import ca.uhn.fhir.jpa.model.search.SearchBuilderLoadIncludesParameters; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.primitive.IdDt; @@ -91,16 +90,16 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor { @Autowired public JpaBulkExportProcessor( - FhirContext theContext, - BulkExportHelperService theBulkExportHelperSvc, - JpaStorageSettings theStorageSettings, - DaoRegistry theDaoRegistry, - SearchBuilderFactory theSearchBuilderFactory, - IIdHelperService theIdHelperService, - EntityManager theEntityManager, - IHapiTransactionService theHapiTransactionService, - ISearchParamRegistry theSearchParamRegistry, - IMdmLinkExpandSvc theMdmLinkExpandSvc) { + FhirContext theContext, + BulkExportHelperService theBulkExportHelperSvc, + JpaStorageSettings theStorageSettings, + DaoRegistry theDaoRegistry, + SearchBuilderFactory theSearchBuilderFactory, + IIdHelperService theIdHelperService, + EntityManager theEntityManager, + IHapiTransactionService theHapiTransactionService, + ISearchParamRegistry theSearchParamRegistry, + IMdmLinkExpandSvc theMdmLinkExpandSvc) { myContext = theContext; myBulkExportHelperSvc = theBulkExportHelperSvc; myStorageSettings = theStorageSettings; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java index 82ec11daa56f..ead800822169 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java @@ -39,16 +39,16 @@ public class JpaBulkExportConfig { @Bean public IBulkExportProcessor jpaBulkExportProcessor( - FhirContext theFhirContext, - BulkExportHelperService theBulkExportHelperService, - JpaStorageSettings theJpaStorageSettings, - DaoRegistry theDaoRegistry, - SearchBuilderFactory theSearchBuilderFactory, - IIdHelperService theIdHelperService, - EntityManager theEntityManager, - IHapiTransactionService theHapiTransactionService, - ISearchParamRegistry theSearchParamRegistry, - IMdmLinkExpandSvc theMdmLinkExpandSvc) { + FhirContext theFhirContext, + BulkExportHelperService theBulkExportHelperService, + JpaStorageSettings theJpaStorageSettings, + DaoRegistry theDaoRegistry, + SearchBuilderFactory theSearchBuilderFactory, + IIdHelperService theIdHelperService, + EntityManager theEntityManager, + IHapiTransactionService theHapiTransactionService, + ISearchParamRegistry theSearchParamRegistry, + IMdmLinkExpandSvc theMdmLinkExpandSvc) { return new JpaBulkExportProcessor( theFhirContext, theBulkExportHelperService, diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index b98bba92a7c1..0eb5a26b992f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -40,8 +40,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Optional; - @Configuration public class MdmJpaConfig { @@ -55,11 +53,11 @@ public IMdmLinkExpandSvc mdmLinkExpandSvc( DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { - if (theMdmSettings.supportsLinkBasedExpansion()) { - return new MdmLinkExpandSvc(); - } else if (theMdmSettings.supportsEidBasedExpansion()) { - return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService); - } + if (theMdmSettings.supportsLinkBasedExpansion()) { + return new MdmLinkExpandSvc(); + } else if (theMdmSettings.supportsEidBasedExpansion()) { + return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService); + } return new DisabledMdmLinkExpandSvc(); } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java index ad8deb769d5a..d0134847bcb7 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/EIDHelper.java @@ -26,7 +26,6 @@ import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; From f76048bfccbb6066fa052b2b714dda1fd249f801 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 10 Oct 2025 12:39:17 -0400 Subject: [PATCH 06/29] Redefine bean in jpaconfig for app ctx loading --- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 40 +++++++++++-------- .../jpa/mdm/config/MdmConsumerConfig.java | 1 + .../mdm/svc/MdmEidMatchOnlyExpandSvc.java | 5 +-- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 0eb5a26b992f..9ec6f8a48573 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -37,43 +37,49 @@ import ca.uhn.fhir.mdm.svc.MdmEidMatchOnlyExpandSvc; import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; +import ca.uhn.fhir.mdm.util.EIDHelper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MdmJpaConfig { + @Bean + public MdmSearchExpansionSvc mdmSearchExpansionSvc() { + return new MdmSearchExpansionSvc(); + } + + @Bean + public IMdmLinkDao mdmLinkDao() { + return new MdmLinkDaoJpaImpl(); + } + + @Bean + public IMdmLinkImplFactory mdmLinkImplFactory() { + return new JpaMdmLinkImplFactory(); + } /** * Based on the rules laid out in the {@link IMdmSettings} file, construct an {@link IMdmLinkExpandSvc} that is suitable */ // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! @Bean public IMdmLinkExpandSvc mdmLinkExpandSvc( - IMdmSettings theMdmSettings, - DaoRegistry theDaoRegistry, - FhirContext theFhirContext, - IIdHelperService theIdHelperService) { + EIDHelper theEidHelper, + IMdmSettings theMdmSettings, + DaoRegistry theDaoRegistry, + FhirContext theFhirContext, + IIdHelperService theIdHelperService) { if (theMdmSettings.supportsLinkBasedExpansion()) { return new MdmLinkExpandSvc(); } else if (theMdmSettings.supportsEidBasedExpansion()) { - return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService); + return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService, theEidHelper); } return new DisabledMdmLinkExpandSvc(); } @Bean - public MdmSearchExpansionSvc mdmSearchExpansionSvc() { - return new MdmSearchExpansionSvc(); - } - - @Bean - public IMdmLinkDao mdmLinkDao() { - return new MdmLinkDaoJpaImpl(); - } - - @Bean - public IMdmLinkImplFactory mdmLinkImplFactory() { - return new JpaMdmLinkImplFactory(); + EIDHelper eidHelper(FhirContext theFhirContext, IMdmSettings theMdmSettings) { + return new EIDHelper(theFhirContext, theMdmSettings); } @Bean 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 0d8af3e6a656..0e4271c59cb2 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 @@ -229,6 +229,7 @@ IMdmLinkCreateSvc mdmLinkCreateSvc() { return new MdmLinkCreateSvcImpl(); } + @Bean MdmLoader mdmLoader() { return new MdmLoader(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java index 2bcbf9ab41bd..7d5366eecb02 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java @@ -58,13 +58,10 @@ public class MdmEidMatchOnlyExpandSvc implements IMdmLinkExpandSvc { private FhirContext myFhirContext; public MdmEidMatchOnlyExpandSvc( - DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { + DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService, EIDHelper theEidHelper) { myDaoRegistry = theDaoRegistry; myFhirContext = theFhirContext; myIdHelperService = theIdHelperService; - } - - public void setMyEidHelper(EIDHelper theEidHelper) { myEidHelper = theEidHelper; } From ebb9a6a887c3be906932d4373043723b9a92b755 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 10 Oct 2025 12:40:25 -0400 Subject: [PATCH 07/29] comments --- .../ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java index 2873e97552db..8147a86863a4 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java @@ -22,12 +22,7 @@ import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; -import ca.uhn.fhir.mdm.api.IMdmRuleValidator; -import ca.uhn.fhir.mdm.api.IMdmSettings; -import ca.uhn.fhir.mdm.api.MdmModeEnum; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; -import ca.uhn.fhir.mdm.rules.config.MdmSettings; -import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.MethodOutcome; @@ -78,8 +73,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import java.io.IOException; @@ -107,7 +100,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; - +//TODO GGG: we should be splitting out tests that enable MDM, as otherwise I am adding MDM config to all these tests for no reason. @ContextConfiguration(classes = {MdmRulesWithEidMatchOnlyConfig.class}) public class BulkExportUseCaseTest extends BaseResourceProviderR4Test { private static final Logger ourLog = LoggerFactory.getLogger(BulkExportUseCaseTest.class); @@ -777,10 +770,9 @@ public void testGroupBulkExportMembershipShouldNotExpandIntoOtherGroups() { assertThat(firstMap.get("Patient")).hasSize(1); assertThat(firstMap.get("Group")).hasSize(1); } + @Test void testGroupExportWithMdmEnabled_EidMatchOnly() { - //FIXME GGG TEST FAILING START HERE. - BundleBuilder bb = new BundleBuilder(myFhirContext); //In this test, we create two patients with the same Eid value for the eid system specified in mdm rules From e65b52c547445c9cd3478dd8bcc6a69542c74cda Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 10 Oct 2025 12:44:12 -0400 Subject: [PATCH 08/29] Version bumped to 8.5.8-SNAPSHOT --- hapi-deployable-pom/pom.xml | 2 +- hapi-fhir-android/pom.xml | 2 +- hapi-fhir-base/pom.xml | 2 +- hapi-fhir-bom/pom.xml | 4 ++-- hapi-fhir-checkstyle/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-api/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-app/pom.xml | 2 +- hapi-fhir-cli/pom.xml | 2 +- hapi-fhir-client-apache-http5/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 +- hapi-fhir-jacoco/pom.xml | 2 +- hapi-fhir-jaxrsserver-base/pom.xml | 2 +- hapi-fhir-jpa-hibernate-services/pom.xml | 2 +- hapi-fhir-jpa/pom.xml | 2 +- hapi-fhir-jpaserver-base/pom.xml | 2 +- hapi-fhir-jpaserver-elastic-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-hfql/pom.xml | 2 +- hapi-fhir-jpaserver-ips/pom.xml | 2 +- hapi-fhir-jpaserver-mdm/pom.xml | 2 +- hapi-fhir-jpaserver-model/pom.xml | 2 +- hapi-fhir-jpaserver-searchparam/pom.xml | 2 +- hapi-fhir-jpaserver-subscription/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu2/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu3/pom.xml | 2 +- hapi-fhir-jpaserver-test-r4/pom.xml | 2 +- hapi-fhir-jpaserver-test-r4b/pom.xml | 2 +- hapi-fhir-jpaserver-test-r5/pom.xml | 2 +- hapi-fhir-jpaserver-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 2 +- hapi-fhir-repositories/pom.xml | 2 +- hapi-fhir-server-cds-hooks/pom.xml | 2 +- hapi-fhir-server-mdm/pom.xml | 2 +- hapi-fhir-server-openapi/pom.xml | 2 +- hapi-fhir-server/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml | 4 ++-- hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml | 2 +- hapi-fhir-serviceloaders/pom.xml | 2 +- .../hapi-fhir-spring-boot-autoconfigure/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-client-apache/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-client-okhttp/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-server-jersey/pom.xml | 2 +- hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml | 2 +- hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml | 2 +- hapi-fhir-spring-boot/pom.xml | 2 +- hapi-fhir-sql-migrate/pom.xml | 2 +- hapi-fhir-storage-batch2-jobs/pom.xml | 2 +- hapi-fhir-storage-batch2-test-utilities/pom.xml | 2 +- hapi-fhir-storage-batch2/pom.xml | 2 +- hapi-fhir-storage-mdm/pom.xml | 2 +- hapi-fhir-storage-test-utilities/pom.xml | 2 +- hapi-fhir-storage/pom.xml | 2 +- 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-r4b/pom.xml | 2 +- hapi-fhir-structures-r5/pom.xml | 2 +- hapi-fhir-test-utilities/pom.xml | 2 +- hapi-fhir-testpage-overlay/pom.xml | 2 +- hapi-fhir-validation-resources-dstu2.1/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-r4b/pom.xml | 2 +- hapi-fhir-validation-resources-r5/pom.xml | 2 +- hapi-fhir-validation/pom.xml | 2 +- hapi-tinder-plugin/pom.xml | 2 +- hapi-tinder-test/pom.xml | 2 +- pom.xml | 2 +- tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml | 2 +- tests/hapi-fhir-base-test-mindeps-client/pom.xml | 2 +- tests/hapi-fhir-base-test-mindeps-server/pom.xml | 2 +- 79 files changed, 81 insertions(+), 81 deletions(-) diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index 5e8da687ef8e..679ff78491f9 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index c714592e50a4..89c2f61a3300 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 9efde8ecb9b6..d5802222537a 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index d2d3790e2fa7..bd01e1093be8 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -4,7 +4,7 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT pom HAPI FHIR BOM @@ -12,7 +12,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml index 3472cb07026e..3a1bed6568ad 100644 --- a/hapi-fhir-checkstyle/pom.xml +++ b/hapi-fhir-checkstyle/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index 0bf6e4ef91bc..fb87e32e19b8 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index 203466ca667a..a7ad262cea26 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index 5ebb110ece9b..d8ba38a3a8f0 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-client-apache-http5/pom.xml b/hapi-fhir-client-apache-http5/pom.xml index 7105bb502afb..8c46eb2f5d90 100644 --- a/hapi-fhir-client-apache-http5/pom.xml +++ b/hapi-fhir-client-apache-http5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index 11a96d8f59b8..e4e6a31ff030 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index 17a7bbd77447..e4f1d87d2c26 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index 0fab3767c6af..a998003fafda 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index 31177994bb15..4e6a187e41b0 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index a7aa9692b223..0ac3501278a4 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index acbb7375d600..b787bd101116 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index fb687a044745..223d60c8550d 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa-hibernate-services/pom.xml b/hapi-fhir-jpa-hibernate-services/pom.xml index 29444535886e..45b6941f7c2b 100644 --- a/hapi-fhir-jpa-hibernate-services/pom.xml +++ b/hapi-fhir-jpa-hibernate-services/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml index 518e218e3573..e2086c71153d 100644 --- a/hapi-fhir-jpa/pom.xml +++ b/hapi-fhir-jpa/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index cbb4326cfdab..88128e1bfedc 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml index 92b8e6b284aa..e26422b77078 100644 --- a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-hfql/pom.xml b/hapi-fhir-jpaserver-hfql/pom.xml index feed03a0c04f..eb2f54df9e31 100644 --- a/hapi-fhir-jpaserver-hfql/pom.xml +++ b/hapi-fhir-jpaserver-hfql/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml index b8f768dec282..01b4ef820c2e 100644 --- a/hapi-fhir-jpaserver-ips/pom.xml +++ b/hapi-fhir-jpaserver-ips/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index ae0f7e6dc1b1..f76af6ddcfe3 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index 97e0f0f9c38e..1197c941cdf5 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 7f4ff8b915ab..eb61dadfe0ea 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index ea8d2f570bae..2c5fe8d3fa3e 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml index e8cf77a1232a..04bdb8432e68 100644 --- a/hapi-fhir-jpaserver-test-dstu2/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml index fd2d8c4694ef..2ddc185a44ae 100644 --- a/hapi-fhir-jpaserver-test-dstu3/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml index 5aeffb84d6a4..703deaea6692 100644 --- a/hapi-fhir-jpaserver-test-r4/pom.xml +++ b/hapi-fhir-jpaserver-test-r4/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml index 32e2f912263c..ae9d4b61d9c7 100644 --- a/hapi-fhir-jpaserver-test-r4b/pom.xml +++ b/hapi-fhir-jpaserver-test-r4b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml index dd53b1ca2f72..fbb6b320a67c 100644 --- a/hapi-fhir-jpaserver-test-r5/pom.xml +++ b/hapi-fhir-jpaserver-test-r5/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index b6c97df79d8e..3606c9c2df45 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index e583978f2a36..6f7d110fe8f3 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-repositories/pom.xml b/hapi-fhir-repositories/pom.xml index e9dac0f56b99..feb4f00037b3 100644 --- a/hapi-fhir-repositories/pom.xml +++ b/hapi-fhir-repositories/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-cds-hooks/pom.xml b/hapi-fhir-server-cds-hooks/pom.xml index 70a16adbc5df..28effcc22c81 100644 --- a/hapi-fhir-server-cds-hooks/pom.xml +++ b/hapi-fhir-server-cds-hooks/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index c40ac8a35819..0c686670adda 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml index 273ab1f9dc2b..b553bf998b29 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index a241c24e6f5b..9e59c9c854c6 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml index 15e96135c402..df824f8c07ad 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml index 7a590e0bfdee..c7066838c95d 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml @@ -21,7 +21,7 @@ ca.uhn.hapi.fhir hapi-fhir-caching-api - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml index a9b79001cd46..76541cc77e7c 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml index 887b82ff40f8..58a21730ea95 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml @@ -7,7 +7,7 @@ hapi-fhir ca.uhn.hapi.fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../../pom.xml diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml index 5a31a3494c37..336d5289546b 100644 --- a/hapi-fhir-serviceloaders/pom.xml +++ b/hapi-fhir-serviceloaders/pom.xml @@ -5,7 +5,7 @@ hapi-deployable-pom ca.uhn.hapi.fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml 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 7175d05d5812..86cfff600f97 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 - 8.5.7-SNAPSHOT + 8.5.8-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 b0448e69ae6c..018042032ddf 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 - 8.5.7-SNAPSHOT + 8.5.8-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 ea0ab9f2673a..ae6b01708d61 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT 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 3c2bdac52324..0244ab970411 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT 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 79d884e76082..bc118dc1fed5 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT 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 59cd485f5158..a395f7a872b1 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index 02d2d3c0d894..0cf0482ba0bd 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml index 24b842f9894d..b4ef048867de 100644 --- a/hapi-fhir-sql-migrate/pom.xml +++ b/hapi-fhir-sql-migrate/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml index 4e26180b4658..3170b48c3f20 100644 --- a/hapi-fhir-storage-batch2-jobs/pom.xml +++ b/hapi-fhir-storage-batch2-jobs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml index a225343eaeca..0c21cecfd7a8 100644 --- a/hapi-fhir-storage-batch2-test-utilities/pom.xml +++ b/hapi-fhir-storage-batch2-test-utilities/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml index a6fd0c38e66c..3817936b8aff 100644 --- a/hapi-fhir-storage-batch2/pom.xml +++ b/hapi-fhir-storage-batch2/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml index e5733bf87410..ae027c388788 100644 --- a/hapi-fhir-storage-mdm/pom.xml +++ b/hapi-fhir-storage-mdm/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml index 705c7c9487a4..6b3bb99a00a7 100644 --- a/hapi-fhir-storage-test-utilities/pom.xml +++ b/hapi-fhir-storage-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml index dc8c0bb0d4f9..0599b812cd05 100644 --- a/hapi-fhir-storage/pom.xml +++ b/hapi-fhir-storage/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index 24ac3145b11c..d9ba3b64ca39 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index 0df02aa50a95..6b069add2187 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index 491fdf78d7b8..79217d2a7c0d 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 - 8.5.7-SNAPSHOT + 8.5.8-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 7c670ae99d1e..52bcd3969a18 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index 122daba129cc..28c0ba983057 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml index b46a8a938ced..273baec9af1e 100644 --- a/hapi-fhir-structures-r4b/pom.xml +++ b/hapi-fhir-structures-r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index f5abb24efec3..1ef12e56dad9 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index 93078fecc802..db1a7bab91f4 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index 37280ceca5fa..edb00022adfb 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index 7037f1a44f11..f6d68b49f9c9 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 - 8.5.7-SNAPSHOT + 8.5.8-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 ab42bcd55caf..ceb6ee51b88b 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 - 8.5.7-SNAPSHOT + 8.5.8-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 4b3b588449bc..82a547317836 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 - 8.5.7-SNAPSHOT + 8.5.8-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 e12ef1a8d68b..742cc287c46c 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml index e67bd113ee08..b40ae34f3db9 100644 --- a/hapi-fhir-validation-resources-r4b/pom.xml +++ b/hapi-fhir-validation-resources-r4b/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-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 338528c69be4..a8b264266675 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index 4f2a5cc3f876..00b3608d5111 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index bafa6c98c7e9..4c0ab38850ab 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index e2650d0378ca..1263536b4d6a 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index d65683695a96..ac659aac3fd3 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-fhir pom - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT HAPI-FHIR An open-source implementation of the FHIR specification in Java. diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index fa70cb0dff4c..a53239947178 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.7-SNAPSHOT + 8.5.8-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 36d98d549c7e..10c8975a8895 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 - 8.5.7-SNAPSHOT + 8.5.8-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 016da1f3dd08..09b8bcea3904 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 - 8.5.7-SNAPSHOT + 8.5.8-SNAPSHOT ../../pom.xml From eb0953f509fcc09b8a123dac1823e8417a505b4d Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 10 Oct 2025 13:01:07 -0400 Subject: [PATCH 09/29] wip --- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 23 ++++++++++++++----- .../jpa/mdm/config/MdmConsumerConfig.java | 1 - .../mdm/svc/MdmEidMatchOnlyExpandSvc.java | 5 +++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 9ec6f8a48573..a75d0c55bec8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -38,11 +38,16 @@ import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; import ca.uhn.fhir.mdm.util.EIDHelper; +import jakarta.annotation.Nullable; +import net.sourceforge.plantuml.classdiagram.command.CommandUrl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MdmJpaConfig { + private static final Logger ourLog = LoggerFactory.getLogger(MdmJpaConfig.class); @Bean public MdmSearchExpansionSvc mdmSearchExpansionSvc() { @@ -64,11 +69,14 @@ public IMdmLinkImplFactory mdmLinkImplFactory() { // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! @Bean public IMdmLinkExpandSvc mdmLinkExpandSvc( - EIDHelper theEidHelper, - IMdmSettings theMdmSettings, - DaoRegistry theDaoRegistry, - FhirContext theFhirContext, - IIdHelperService theIdHelperService) { + EIDHelper theEidHelper, + @Nullable IMdmSettings theMdmSettings, + DaoRegistry theDaoRegistry, + FhirContext theFhirContext, + IIdHelperService theIdHelperService) { + if (theMdmSettings == null) { + return new DisabledMdmLinkExpandSvc(); + } if (theMdmSettings.supportsLinkBasedExpansion()) { return new MdmLinkExpandSvc(); } else if (theMdmSettings.supportsEidBasedExpansion()) { @@ -78,7 +86,10 @@ public IMdmLinkExpandSvc mdmLinkExpandSvc( } @Bean - EIDHelper eidHelper(FhirContext theFhirContext, IMdmSettings theMdmSettings) { + EIDHelper eidHelper(FhirContext theFhirContext, @Nullable IMdmSettings theMdmSettings) { + if (theMdmSettings == null) { + ourLog.warn("Loading up an EID helper without an IMdmSetting bean defined! MDM will _not_ work!"); + } return new EIDHelper(theFhirContext, theMdmSettings); } 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 0e4271c59cb2..0d8af3e6a656 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 @@ -229,7 +229,6 @@ IMdmLinkCreateSvc mdmLinkCreateSvc() { return new MdmLinkCreateSvcImpl(); } - @Bean MdmLoader mdmLoader() { return new MdmLoader(); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java index 7d5366eecb02..c4fe62e0d4bb 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmEidMatchOnlyExpandSvc.java @@ -58,7 +58,10 @@ public class MdmEidMatchOnlyExpandSvc implements IMdmLinkExpandSvc { private FhirContext myFhirContext; public MdmEidMatchOnlyExpandSvc( - DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService, EIDHelper theEidHelper) { + DaoRegistry theDaoRegistry, + FhirContext theFhirContext, + IIdHelperService theIdHelperService, + EIDHelper theEidHelper) { myDaoRegistry = theDaoRegistry; myFhirContext = theFhirContext; myIdHelperService = theIdHelperService; From 3844dc696ffb420e3baa0ffdab88902315b662de Mon Sep 17 00:00:00 2001 From: Gary Date: Tue, 14 Oct 2025 08:27:35 -0700 Subject: [PATCH 10/29] wip maybe revert --- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 23 +------------------ .../fhir/jpa/mdm/config/MdmCommonConfig.java | 1 + 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index a75d0c55bec8..f92efa3cceee 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -39,7 +39,6 @@ import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; import ca.uhn.fhir.mdm.util.EIDHelper; import jakarta.annotation.Nullable; -import net.sourceforge.plantuml.classdiagram.command.CommandUrl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; @@ -63,27 +62,7 @@ public IMdmLinkDao mdmLinkDao() { public IMdmLinkImplFactory mdmLinkImplFactory() { return new JpaMdmLinkImplFactory(); } - /** - * Based on the rules laid out in the {@link IMdmSettings} file, construct an {@link IMdmLinkExpandSvc} that is suitable - */ - // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! - @Bean - public IMdmLinkExpandSvc mdmLinkExpandSvc( - EIDHelper theEidHelper, - @Nullable IMdmSettings theMdmSettings, - DaoRegistry theDaoRegistry, - FhirContext theFhirContext, - IIdHelperService theIdHelperService) { - if (theMdmSettings == null) { - return new DisabledMdmLinkExpandSvc(); - } - if (theMdmSettings.supportsLinkBasedExpansion()) { - return new MdmLinkExpandSvc(); - } else if (theMdmSettings.supportsEidBasedExpansion()) { - return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService, theEidHelper); - } - return new DisabledMdmLinkExpandSvc(); - } + @Bean EIDHelper eidHelper(FhirContext theFhirContext, @Nullable IMdmSettings theMdmSettings) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java index b672152e5f93..3f3517ac0da7 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java @@ -71,4 +71,5 @@ public IMatcherFactory matcherFactory( FhirContext theFhirContext, IMdmSettings theSettings, INicknameSvc theNicknameSvc) { return new MdmMatcherFactory(theFhirContext, theSettings, theNicknameSvc); } + } From b01f50dea0ead2fa4ea2707643e567b20b56ca5d Mon Sep 17 00:00:00 2001 From: Gary Date: Tue, 14 Oct 2025 08:27:46 -0700 Subject: [PATCH 11/29] wip maybe revert --- .../src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 7 ------- .../java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java | 1 - 2 files changed, 8 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index f92efa3cceee..f4246a09e262 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -20,22 +20,16 @@ package ca.uhn.fhir.jpa.config; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.svc.IDeleteExpungeSvc; -import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IMdmClearHelperSvc; import ca.uhn.fhir.jpa.bulk.mdm.MdmClearHelperSvcImpl; import ca.uhn.fhir.jpa.dao.mdm.JpaMdmLinkImplFactory; import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl; import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.model.dao.JpaPid; -import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory; -import ca.uhn.fhir.mdm.svc.DisabledMdmLinkExpandSvc; -import ca.uhn.fhir.mdm.svc.MdmEidMatchOnlyExpandSvc; -import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; import ca.uhn.fhir.mdm.util.EIDHelper; import jakarta.annotation.Nullable; @@ -63,7 +57,6 @@ public IMdmLinkImplFactory mdmLinkImplFactory() { return new JpaMdmLinkImplFactory(); } - @Bean EIDHelper eidHelper(FhirContext theFhirContext, @Nullable IMdmSettings theMdmSettings) { if (theMdmSettings == null) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java index 3f3517ac0da7..b672152e5f93 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmCommonConfig.java @@ -71,5 +71,4 @@ public IMatcherFactory matcherFactory( FhirContext theFhirContext, IMdmSettings theSettings, INicknameSvc theNicknameSvc) { return new MdmMatcherFactory(theFhirContext, theSettings, theNicknameSvc); } - } From 7d452df7081cc4b06a329f1fc66038b087397b36 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 08:49:41 -0700 Subject: [PATCH 12/29] wip --- .../export/svc/JpaBulkExportProcessor.java | 24 ++++++++++++------- .../fhir/jpa/config/JpaBulkExportConfig.java | 4 +++- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 2 ++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index 18f17cd2acd6..3be552275b5c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -86,7 +86,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor { private EntityManager myEntityManager; private IHapiTransactionService myHapiTransactionService; private ISearchParamRegistry mySearchParamRegistry; - private IMdmLinkExpandSvc myMdmLinkExpandSvc; + private Optional myMdmLinkExpandSvc; @Autowired public JpaBulkExportProcessor( @@ -99,7 +99,7 @@ public JpaBulkExportProcessor( EntityManager theEntityManager, IHapiTransactionService theHapiTransactionService, ISearchParamRegistry theSearchParamRegistry, - IMdmLinkExpandSvc theMdmLinkExpandSvc) { + Optional theMdmLinkExpandSvc) { myContext = theContext; myBulkExportHelperSvc = theBulkExportHelperSvc; myStorageSettings = theStorageSettings; @@ -347,10 +347,14 @@ protected RuntimeSearchParam getPatientSearchParamForCurrentResourceType(String @Override public void expandMdmResources(List theResources) { - for (IBaseResource resource : theResources) { - if (!PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(resource.fhirType())) { - myMdmLinkExpandSvc.annotateResource(resource); + if (myMdmLinkExpandSvc.isPresent()) { + for (IBaseResource resource : theResources) { + if (!PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(resource.fhirType())) { + myMdmLinkExpandSvc.get().annotateResource(resource); + } } + } else { + ourLog.warn("Attempted to perform MDM expansion, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); } } @@ -389,7 +393,7 @@ private void validateSearchParametersForGroup(SearchParameterMap expandedSpMap, /** * Given the local myGroupId, perform an expansion to retrieve all resource IDs of member patients. * if myMdmEnabled is set to true, we also attempt to also expand it into matched - * patients. + * patients, assuming MDM is configured. * * @return a Set of Strings representing the resource IDs of all members of a group. */ @@ -404,8 +408,12 @@ private LinkedHashSet getExpandedPatientList( LinkedHashSet patientPidsToExport = new LinkedHashSet<>(members); if (theParameters.isExpandMdm()) { - RequestPartitionId partitionId = theParameters.getPartitionIdOrAllPartitions(); - patientPidsToExport.addAll(myMdmLinkExpandSvc.expandGroup(theParameters.getGroupId(), partitionId)); + if (myMdmLinkExpandSvc.isPresent()) { + RequestPartitionId partitionId = theParameters.getPartitionIdOrAllPartitions(); + patientPidsToExport.addAll(myMdmLinkExpandSvc.get().expandGroup(theParameters.getGroupId(), partitionId)); + } else { + ourLog.warn("Attempted to perform MDM expansion during a group-level export operation, but no IMdmLinkExpandSvc was configured. Is MDM Configured correctly?"); + } } return patientPidsToExport; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java index ead800822169..39d5c85e573b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaBulkExportConfig.java @@ -35,6 +35,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.Optional; + @Configuration public class JpaBulkExportConfig { @Bean @@ -48,7 +50,7 @@ public IBulkExportProcessor jpaBulkExportProcessor( EntityManager theEntityManager, IHapiTransactionService theHapiTransactionService, ISearchParamRegistry theSearchParamRegistry, - IMdmLinkExpandSvc theMdmLinkExpandSvc) { + Optional theMdmLinkExpandSvc) { return new JpaBulkExportProcessor( theFhirContext, theBulkExportHelperService, diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index f4246a09e262..6a043073035a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -35,10 +35,12 @@ import jakarta.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration +@ConditionalOnBean(IMdmSettings.class) public class MdmJpaConfig { private static final Logger ourLog = LoggerFactory.getLogger(MdmJpaConfig.class); From cc5d6827fe3c93a4efec8fb3d57b477397bf9ddf Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 08:50:01 -0700 Subject: [PATCH 13/29] Revert "wip maybe revert" This reverts commit 3844dc696ffb420e3baa0ffdab88902315b662de. --- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 6a043073035a..c683c5a68c26 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -33,6 +33,7 @@ import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; import ca.uhn.fhir.mdm.util.EIDHelper; import jakarta.annotation.Nullable; +import net.sourceforge.plantuml.classdiagram.command.CommandUrl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -58,7 +59,27 @@ public IMdmLinkDao mdmLinkDao() { public IMdmLinkImplFactory mdmLinkImplFactory() { return new JpaMdmLinkImplFactory(); } - +/** + * Based on the rules laid out in the {@link IMdmSettings} file, construct an {@link IMdmLinkExpandSvc} that is suitable + */ + // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! + @Bean + public IMdmLinkExpandSvc mdmLinkExpandSvc( + EIDHelper theEidHelper, + @Nullable IMdmSettings theMdmSettings, + DaoRegistry theDaoRegistry, + FhirContext theFhirContext, + IIdHelperService theIdHelperService) { + if (theMdmSettings == null) { + return new DisabledMdmLinkExpandSvc(); + } + if (theMdmSettings.supportsLinkBasedExpansion()) { + return new MdmLinkExpandSvc(); + } else if (theMdmSettings.supportsEidBasedExpansion()) { + return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService, theEidHelper); + } + return new DisabledMdmLinkExpandSvc(); + } @Bean EIDHelper eidHelper(FhirContext theFhirContext, @Nullable IMdmSettings theMdmSettings) { if (theMdmSettings == null) { From 16e7d2ebcd55759dc20d006f30da469e7095d424 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 08:58:01 -0700 Subject: [PATCH 14/29] Remove dead code --- .../java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 13 +++++++++---- .../ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java | 3 --- .../main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java | 4 ---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index c683c5a68c26..5cbec6432375 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -20,20 +20,25 @@ package ca.uhn.fhir.jpa.config; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.svc.IDeleteExpungeSvc; +import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IMdmClearHelperSvc; import ca.uhn.fhir.jpa.bulk.mdm.MdmClearHelperSvcImpl; import ca.uhn.fhir.jpa.dao.mdm.JpaMdmLinkImplFactory; import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl; import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.model.dao.JpaPid; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory; +import ca.uhn.fhir.mdm.svc.DisabledMdmLinkExpandSvc; +import ca.uhn.fhir.mdm.svc.MdmEidMatchOnlyExpandSvc; +import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; import ca.uhn.fhir.mdm.util.EIDHelper; import jakarta.annotation.Nullable; -import net.sourceforge.plantuml.classdiagram.command.CommandUrl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -59,14 +64,14 @@ public IMdmLinkDao mdmLinkDao() { public IMdmLinkImplFactory mdmLinkImplFactory() { return new JpaMdmLinkImplFactory(); } -/** + + /** * Based on the rules laid out in the {@link IMdmSettings} file, construct an {@link IMdmLinkExpandSvc} that is suitable */ - // FIXME GGG Why are we even loading this whole config file if MDM is disabled?!?! @Bean public IMdmLinkExpandSvc mdmLinkExpandSvc( EIDHelper theEidHelper, - @Nullable IMdmSettings theMdmSettings, + IMdmSettings theMdmSettings, DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) { diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java index 8147a86863a4..30a4d0774449 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java @@ -21,7 +21,6 @@ import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.Constants; @@ -120,8 +119,6 @@ public class BulkExportUseCaseTest extends BaseResourceProviderR4Test { private IInterceptorService myInterceptorService; @Autowired private MdmRuleValidator myMdmRulesValidator; - @Autowired - private IMdmLinkExpandSvc myMdmLinkExpandSvc; @BeforeEach public void beforeEach() { diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java index 148c4b4d3174..964c10a85e66 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java @@ -592,10 +592,6 @@ protected void logAllResourcesOfType(String type) { } } - protected int countAllMdmLinks() { - return runInTransaction(()-> myMdmLinkDao.findAll().size()); - } - protected int logAllMdmLinks() { return runInTransaction(()->{ List links = myMdmLinkDao.findAll(); From 12114488b123d0f335d8d8cd6eb9cf2e78424350 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 11:38:36 -0700 Subject: [PATCH 15/29] move MDM stuff down the test class stack --- .../ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java | 13 +++++ .../fhir/jpa/mdm/config/MdmConfigTest.java | 2 - .../fhir/jpa/bulk/BulkExportUseCaseTest.java | 5 +- .../MdmRulesWithEidMatchOnlyConfig.java | 53 +++++++++++++++++++ .../ca/uhn/fhir/jpa/test/BaseJpaR4Test.java | 12 ++--- .../ca/uhn/fhir/jpa/test/BaseJpaTest.java | 14 +---- .../fhir/jpa/test/config/TestJPAConfig.java | 14 +++++ .../fhir/jpa/test/config/TestR4Config.java | 2 +- .../ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 13 ++++- 9 files changed, 101 insertions(+), 27 deletions(-) delete mode 100644 hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/config/MdmConfigTest.java 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 d88775506b71..0605930f47d8 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 @@ -60,6 +60,7 @@ import java.util.Optional; import java.util.function.Function; +import static java.util.stream.Collectors.joining; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.slf4j.LoggerFactory.getLogger; @@ -155,6 +156,18 @@ protected void saveLink(MdmLink theMdmLink) { protected GoldenResourceMatchingAssert mdmAssertThat(IAnyResource theResource) { return GoldenResourceMatchingAssert.assertThat(theResource, myIdHelperService, myMdmLinkDaoSvc); } + + protected int logAllMdmLinks() { + return runInTransaction(()->{ + List links = myMdmLinkDao.findAll(); + if (links.isEmpty()) { + ourLog.info("MDM Links: NONE"); + } else { + ourLog.info("MDM Links:\n * {}", links.stream().map(t -> t.toString()).collect(joining("\n * "))); + } + return links.size(); + }); + } @Nonnull protected Patient createGoldenPatient() { return createPatient(new Patient(), true, false); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/config/MdmConfigTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/config/MdmConfigTest.java deleted file mode 100644 index 437f0d4106b1..000000000000 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/config/MdmConfigTest.java +++ /dev/null @@ -1,2 +0,0 @@ -package ca.uhn.fhir.jpa.mdm.config;public class MdmConfigTest { -} diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java index 30a4d0774449..ed92cae56dea 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/BulkExportUseCaseTest.java @@ -72,6 +72,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; import org.springframework.test.context.ContextConfiguration; import java.io.IOException; @@ -99,8 +100,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -//TODO GGG: we should be splitting out tests that enable MDM, as otherwise I am adding MDM config to all these tests for no reason. -@ContextConfiguration(classes = {MdmRulesWithEidMatchOnlyConfig.class}) + +@Import(MdmRulesWithEidMatchOnlyConfig.class) public class BulkExportUseCaseTest extends BaseResourceProviderR4Test { private static final Logger ourLog = LoggerFactory.getLogger(BulkExportUseCaseTest.class); diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java index 428d3d86299b..66bd1dfef5eb 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/bulk/config/MdmRulesWithEidMatchOnlyConfig.java @@ -1,12 +1,29 @@ package ca.uhn.fhir.jpa.bulk.config; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; +import ca.uhn.fhir.jpa.api.svc.IDeleteExpungeSvc; +import ca.uhn.fhir.jpa.api.svc.IIdHelperService; +import ca.uhn.fhir.jpa.api.svc.IMdmClearHelperSvc; +import ca.uhn.fhir.jpa.bulk.mdm.MdmClearHelperSvcImpl; +import ca.uhn.fhir.jpa.dao.mdm.JpaMdmLinkImplFactory; +import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl; +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.jpa.model.dao.JpaPid; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.mdm.api.IMdmRuleValidator; import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.api.MdmModeEnum; +import ca.uhn.fhir.mdm.dao.IMdmLinkDao; +import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory; import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; +import ca.uhn.fhir.mdm.svc.MdmEidMatchOnlyExpandSvc; +import ca.uhn.fhir.mdm.svc.MdmSearchExpansionSvc; +import ca.uhn.fhir.mdm.util.EIDHelper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import java.util.List; @@ -15,6 +32,7 @@ public class MdmRulesWithEidMatchOnlyConfig { public static final String TEST_PATIENT_EID_SYS = "http://patient-eid-sys"; @Bean + @Primary //Override any random test mdm settings that are setup above. public IMdmSettings mdmSettings(IMdmRuleValidator theMdmRuleValidator) { MdmSettings mdmSettings = new MdmSettings(theMdmRuleValidator); mdmSettings.setEnabled(true); @@ -25,4 +43,39 @@ public IMdmSettings mdmSettings(IMdmRuleValidator theMdmRuleValidator) { mdmSettings.setMdmRules(rules); return mdmSettings; } + + @Bean + public MdmSearchExpansionSvc mdmSearchExpansionSvc() { + return new MdmSearchExpansionSvc(); + } + + @Bean + public IMdmLinkDao mdmLinkDao() { + return new MdmLinkDaoJpaImpl(); + } + + @Bean + public IMdmLinkImplFactory mdmLinkImplFactory() { + return new JpaMdmLinkImplFactory(); + } + + @Bean + public IMdmLinkExpandSvc mdmLinkExpandSvc( + EIDHelper theEidHelper, + IMdmSettings theMdmSettings, + DaoRegistry theDaoRegistry, + FhirContext theFhirContext, + IIdHelperService theIdHelperService) { + return new MdmEidMatchOnlyExpandSvc(theDaoRegistry, theFhirContext, theIdHelperService, theEidHelper); + } + + @Bean + public EIDHelper eidHelper(FhirContext theFhirContext, IMdmSettings theMdmSettings) { + return new EIDHelper(theFhirContext, theMdmSettings); + } + + @Bean + public IMdmClearHelperSvc mdmClearHelperSvc(IDeleteExpungeSvc theDeleteExpungeSvc) { + return new MdmClearHelperSvcImpl(theDeleteExpungeSvc); + } } diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java index 9215ebebeaa4..f3c5a901c542 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java @@ -107,6 +107,7 @@ import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.validation.ValidationSettings; +import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.interceptor.MdmStorageInterceptor; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.StrictErrorHandler; @@ -235,7 +236,7 @@ @ContextConfiguration(classes = { TestR4Config.class, ReplaceReferencesAppCtx.class, // Batch job - MergeAppCtx.class // Batch job + MergeAppCtx.class, // Batch job }) public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuilder { public static final String MY_VALUE_SET = "my-value-set"; @@ -550,8 +551,6 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil @Autowired protected ValidationSettings myValidationSettings; @Autowired - protected IMdmLinkJpaRepository myMdmLinkRepository; - @Autowired protected IMdmLinkJpaRepository myMdmLinkHistoryDao; @Autowired private IValidationSupport myJpaValidationSupportChainR4; @@ -651,9 +650,8 @@ public void afterPurgeDatabase() { ourLog.info("Pausing Schedulers"); mySchedulerService.pause(); - myTerminologyDeferredStorageSvc.logQueueForUnitTest(); if (!myTermDeferredStorageSvc.isStorageQueueEmpty(true)) { - ourLog.warn("There is deferred terminology storage stuff still in the queue. Please verify your tests clean up ok."); + ourLog.warn("There is deferred terminology storage stuff still in the queue. Please verify your tests clean up ok. Please call myTerminologyDeferredStorageSvc.logQueueForUnitTest() to find out what is in there in your test."); if (myTermDeferredStorageSvc instanceof TermDeferredStorageSvcImpl t) { t.clearDeferred(); } @@ -666,8 +664,8 @@ public void afterPurgeDatabase() { } try { runInTransaction(() -> { + myMdmLinkDao.ifPresent(IMdmLinkDao::deleteAll); myMdmLinkHistoryDao.deleteAll(); - myMdmLinkDao.deleteAll(); }); purgeDatabase(myStorageSettings, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataScheduleHelper); @@ -685,7 +683,7 @@ public void afterPurgeDatabase() { // restart the jobs ourLog.info("Restarting the schedulers"); mySchedulerService.unpause(); - ourLog.info("5 - " + getClass().getSimpleName() + ".afterPurgeDatabases"); + ourLog.info("Finished executing afterPurgeDatabases() for class " + getClass().getSimpleName()); } @BeforeEach diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java index 964c10a85e66..c5cf0763f181 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java @@ -230,7 +230,7 @@ public abstract class BaseJpaTest extends BaseTest { protected ServletRequestDetails mySrd; protected InterceptorService mySrdInterceptorService; @Autowired - protected IMdmLinkDao myMdmLinkDao; + protected Optional> myMdmLinkDao; @Autowired protected FhirContext myFhirContext; @Autowired @@ -592,18 +592,6 @@ protected void logAllResourcesOfType(String type) { } } - protected int logAllMdmLinks() { - return runInTransaction(()->{ - List links = myMdmLinkDao.findAll(); - if (links.isEmpty()) { - ourLog.info("MDM Links: NONE"); - } else { - ourLog.info("MDM Links:\n * {}", links.stream().map(t -> t.toString()).collect(joining("\n * "))); - } - return links.size(); - }); - } - public void logAllResourceLinks() { runInTransaction(() -> { ourLog.info("Resource Links:\n * {}", myResourceLinkDao.findAll().stream().map(ResourceLink::toString).collect(Collectors.joining("\n * "))); diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java index 2125d35a7dc8..30ee6ceda32b 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestJPAConfig.java @@ -43,7 +43,9 @@ import ca.uhn.fhir.jpa.test.util.SubscriptionTestUtil; import ca.uhn.fhir.jpa.util.LoggingEmailSender; import ca.uhn.fhir.mdm.api.IMdmRuleValidator; +import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; +import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.system.HapiTestSystemProperties; import jakarta.persistence.EntityManagerFactory; @@ -141,4 +143,16 @@ public IEmailSender emailSender(){ public IMdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRegistry theSearchParamRetriever) { return new MdmRuleValidator(theFhirContext, theSearchParamRetriever); } + + /** + * N.B GGG: This bean only exists to support our existing busted test infrastructure that smooshes persistence contexts + * together with MDM contexts. In the future, this will be ripped out into mdm-specific JPA config for test. For now, + * if you need to override this MDM behaviour, add @Primary to your IMdmSettings bean definition in your implementing test class. + */ + @Bean + public IMdmSettings mdmSettings(IMdmRuleValidator theMdmRuleValidator) { + MdmSettings mdmSettings = new MdmSettings(theMdmRuleValidator); + mdmSettings.setEnabled(true); + return mdmSettings; + } } diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestR4Config.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestR4Config.java index a948773e6cd4..eb8580209590 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestR4Config.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/config/TestR4Config.java @@ -71,10 +71,10 @@ @Configuration @Import({ + TestJPAConfig.class, JpaR4Config.class, PackageLoaderConfig.class, TestHapiJpaConfig.class, - TestJPAConfig.class, SubscriptionTopicConfig.class, TestHSearchAddInConfig.DefaultLuceneHeap.class, JpaBatch2Config.class, diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 332094fb3523..bdd8466c279d 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -40,6 +40,7 @@ import ca.uhn.fhir.util.HapiExtensions; import ca.uhn.fhir.util.SearchParameterUtil; import jakarta.annotation.Nonnull; +import jakarta.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseReference; @@ -47,6 +48,8 @@ import org.hl7.fhir.instance.model.api.IIdType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -83,7 +86,13 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private IFhirPath myFhirPath; public MdmLinkExpandSvc() { - myFhirPath = myContext.newFhirPath(); + } + + private IFhirPath getFhirPath() { + if (myFhirPath == null) { + myFhirPath = myContext.newFhirPath(); + } + return myFhirPath; } /** @@ -304,7 +313,7 @@ private Optional getPatientReference(IBaseResource iBaseResource) { return Optional.of(iBaseResource.getIdElement().getIdPart()); } else { Optional optionalReference = - myFhirPath.evaluateFirst(iBaseResource, fhirPath, IBaseReference.class); + getFhirPath().evaluateFirst(iBaseResource, fhirPath, IBaseReference.class); if (optionalReference.isPresent()) { return optionalReference.map(theIBaseReference -> theIBaseReference.getReferenceElement().getIdPart()); From 95176ab1506a81405f1926294eba0554b57ebfc1 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 11:39:47 -0700 Subject: [PATCH 16/29] move MDM stuff down the test class stack --- .../fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java | 9 ++++++--- .../main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 1 + .../main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 6 +----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index 3be552275b5c..dffb6dcdccb2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -354,7 +354,8 @@ public void expandMdmResources(List theResources) { } } } else { - ourLog.warn("Attempted to perform MDM expansion, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); + ourLog.warn( + "Attempted to perform MDM expansion, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); } } @@ -410,9 +411,11 @@ private LinkedHashSet getExpandedPatientList( if (theParameters.isExpandMdm()) { if (myMdmLinkExpandSvc.isPresent()) { RequestPartitionId partitionId = theParameters.getPartitionIdOrAllPartitions(); - patientPidsToExport.addAll(myMdmLinkExpandSvc.get().expandGroup(theParameters.getGroupId(), partitionId)); + patientPidsToExport.addAll( + myMdmLinkExpandSvc.get().expandGroup(theParameters.getGroupId(), partitionId)); } else { - ourLog.warn("Attempted to perform MDM expansion during a group-level export operation, but no IMdmLinkExpandSvc was configured. Is MDM Configured correctly?"); + ourLog.warn( + "Attempted to perform MDM expansion during a group-level export operation, but no IMdmLinkExpandSvc was configured. Is MDM Configured correctly?"); } } return patientPidsToExport; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 5cbec6432375..4c350ab167f4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -85,6 +85,7 @@ public IMdmLinkExpandSvc mdmLinkExpandSvc( } return new DisabledMdmLinkExpandSvc(); } + @Bean EIDHelper eidHelper(FhirContext theFhirContext, @Nullable IMdmSettings theMdmSettings) { if (theMdmSettings == null) { diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index bdd8466c279d..7382c82d6a6a 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -40,7 +40,6 @@ import ca.uhn.fhir.util.HapiExtensions; import ca.uhn.fhir.util.SearchParameterUtil; import jakarta.annotation.Nonnull; -import jakarta.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseReference; @@ -48,8 +47,6 @@ import org.hl7.fhir.instance.model.api.IIdType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -85,8 +82,7 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private IFhirPath myFhirPath; - public MdmLinkExpandSvc() { - } + public MdmLinkExpandSvc() {} private IFhirPath getFhirPath() { if (myFhirPath == null) { From f38c4020d19b476f9b9d7d5a93dc285ab176b9ef Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 12:50:07 -0700 Subject: [PATCH 17/29] Push all mdm related stuff down into MDM-related classes --- .../ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java | 22 +++++++++++ .../clear/MdmLinkSlowDeletionSandboxIT.java | 3 +- .../ca/uhn/fhir/jpa/test/BaseJpaR4Test.java | 39 ++++++------------- .../ca/uhn/fhir/jpa/test/BaseJpaTest.java | 4 -- 4 files changed, 36 insertions(+), 32 deletions(-) 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 0605930f47d8..fd7f9214c8f3 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 @@ -28,6 +28,7 @@ import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.dao.IMdmLinkDao; +import ca.uhn.fhir.mdm.interceptor.MdmStorageInterceptor; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.mdm.rules.svc.MdmResourceMatcherSvc; @@ -92,6 +93,8 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { .setValue("555-555-5555"); private static final String NAME_GIVEN_FRANK = "Frank"; + @Autowired(required = false) + private MdmStorageInterceptor myMdmStorageInterceptor; @Autowired protected IFhirResourceDaoPatient myPatientDao; @Autowired @@ -157,6 +160,25 @@ protected GoldenResourceMatchingAssert mdmAssertThat(IAnyResource theResource) { return GoldenResourceMatchingAssert.assertThat(theResource, myIdHelperService, myMdmLinkDaoSvc); } + + @Override + public void afterPurgeDatabase() { + boolean registeredStorageInterceptor = false; + if (myMdmStorageInterceptor != null && !myInterceptorService.getAllRegisteredInterceptors().contains(myMdmStorageInterceptor)) { + myInterceptorService.registerInterceptor(myMdmStorageInterceptor); + registeredStorageInterceptor = true; + } + runInTransaction(() -> { + myMdmLinkDao.deleteAll(); + }); + super.afterPurgeDatabase(); + + if (registeredStorageInterceptor) { + myInterceptorService.unregisterInterceptor(myMdmStorageInterceptor); + } + + } + protected int logAllMdmLinks() { return runInTransaction(()->{ List links = myMdmLinkDao.findAll(); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java index 5cba19589010..882e628819a2 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java @@ -1,6 +1,7 @@ package ca.uhn.fhir.mdm.batch2.clear; import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.jpa.test.BaseJpaR4Test; import ca.uhn.fhir.jpa.test.config.TestR4Config; @@ -32,7 +33,7 @@ @Disabled("Keeping as a sandbox to be used whenever we need a lot of MdmLinks in DB for performance testing") @ContextConfiguration(classes = {MdmLinkSlowDeletionSandboxIT.TestDataSource.class}) -public class MdmLinkSlowDeletionSandboxIT extends BaseJpaR4Test { +public class MdmLinkSlowDeletionSandboxIT extends BaseMdmR4Test { private static final Logger ourLog = LoggerFactory.getLogger(MdmLinkSlowDeletionSandboxIT.class); private final int ourMdmLinksToCreate = 1_000_000; diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java index f3c5a901c542..181acd2d311f 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java @@ -107,8 +107,6 @@ import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.validation.ValidationSettings; -import ca.uhn.fhir.mdm.dao.IMdmLinkDao; -import ca.uhn.fhir.mdm.interceptor.MdmStorageInterceptor; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.StrictErrorHandler; import ca.uhn.fhir.rest.api.Constants; @@ -560,9 +558,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil @Autowired protected IResourceSearchUrlDao myResourceSearchUrlDao; @Autowired - private IInterceptorService myInterceptorService; - @Autowired(required = false) - private MdmStorageInterceptor myMdmStorageInterceptor; + protected IInterceptorService myInterceptorService; @Autowired protected TestDaoSearch myTestDaoSearch; @Autowired @@ -657,28 +653,17 @@ public void afterPurgeDatabase() { } } - boolean registeredStorageInterceptor = false; - if (myMdmStorageInterceptor != null && !myInterceptorService.getAllRegisteredInterceptors().contains(myMdmStorageInterceptor)) { - myInterceptorService.registerInterceptor(myMdmStorageInterceptor); - registeredStorageInterceptor = true; - } - try { - runInTransaction(() -> { - myMdmLinkDao.ifPresent(IMdmLinkDao::deleteAll); - myMdmLinkHistoryDao.deleteAll(); - }); - purgeDatabase(myStorageSettings, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataScheduleHelper); - - myBatch2JobHelper.cancelAllJobsAndAwaitCancellation(); - runInTransaction(() -> { - myWorkChunkRepository.deleteAll(); - myJobInstanceRepository.deleteAll(); - }); - } finally { - if (registeredStorageInterceptor) { - myInterceptorService.unregisterInterceptor(myMdmStorageInterceptor); - } - } + + runInTransaction(() -> { + myMdmLinkHistoryDao.deleteAll(); + }); + purgeDatabase(myStorageSettings, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataScheduleHelper); + + myBatch2JobHelper.cancelAllJobsAndAwaitCancellation(); + runInTransaction(() -> { + myWorkChunkRepository.deleteAll(); + myJobInstanceRepository.deleteAll(); + }); // restart the jobs ourLog.info("Restarting the schedulers"); diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java index c5cf0763f181..9250b142ac86 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaTest.java @@ -65,7 +65,6 @@ import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao; import ca.uhn.fhir.jpa.dao.data.ITermValueSetConceptDao; import ca.uhn.fhir.jpa.dao.data.ITermValueSetDao; -import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConceptDesignation; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; @@ -105,7 +104,6 @@ import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.util.CircularQueueCaptureQueriesListener; import ca.uhn.fhir.jpa.util.MemoryCacheService; -import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.RequestDetails; @@ -230,8 +228,6 @@ public abstract class BaseJpaTest extends BaseTest { protected ServletRequestDetails mySrd; protected InterceptorService mySrdInterceptorService; @Autowired - protected Optional> myMdmLinkDao; - @Autowired protected FhirContext myFhirContext; @Autowired protected JpaStorageSettings myStorageSettings; From c6834ccc7ec14f8559671581a72d119fea0ba186 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 13:22:01 -0700 Subject: [PATCH 18/29] Patch up mock tests --- .../fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java | 3 ++- .../jpa/bulk/export/svc/JpaBulkExportProcessorTest.java | 8 ++++++++ .../mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java | 9 ++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index dffb6dcdccb2..f48819e13828 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -411,8 +411,9 @@ private LinkedHashSet getExpandedPatientList( if (theParameters.isExpandMdm()) { if (myMdmLinkExpandSvc.isPresent()) { RequestPartitionId partitionId = theParameters.getPartitionIdOrAllPartitions(); + IMdmLinkExpandSvc iMdmLinkExpandSvc = myMdmLinkExpandSvc.get(); patientPidsToExport.addAll( - myMdmLinkExpandSvc.get().expandGroup(theParameters.getGroupId(), partitionId)); + iMdmLinkExpandSvc.expandGroup(theParameters.getGroupId(), partitionId)); } else { ourLog.warn( "Attempted to perform MDM expansion during a group-level export operation, but no IMdmLinkExpandSvc was configured. Is MDM Configured correctly?"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java index 71943f7e7e98..afaf39e946ff 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessorTest.java @@ -52,6 +52,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -130,6 +131,9 @@ public JpaPid next() { @Mock private IIdHelperService myIdHelperService; + @Mock + private Optional myOptionalMdmLinkExpanderService; + @Mock private IMdmLinkExpandSvc myMdmLinkExpanderService; @@ -297,6 +301,8 @@ public void getResourcePidIterator_groupExportStyleWithPatientResource_returnsIt if (theMdm) { // mock the call to expandGroup method of the expander + when(myOptionalMdmLinkExpanderService.isPresent()).thenReturn(true); + when(myOptionalMdmLinkExpanderService.get()).thenReturn(myMdmLinkExpanderService); when(myMdmLinkExpanderService.expandGroup(parameters.getGroupId(), getPartitionIdFromParams(thePartitioned))) .thenReturn(Set.of(mdmExpandedPatientId)); } @@ -392,6 +398,8 @@ public void getResourcePidIterator_groupExportStyleWithNonPatientResource_return if (theMdm) { // mock the call to expandGroup method of the expander + when(myOptionalMdmLinkExpanderService.isPresent()).thenReturn(true); + when(myOptionalMdmLinkExpanderService.get()).thenReturn(myMdmLinkExpanderService); when(myMdmLinkExpanderService.expandGroup(parameters.getGroupId(), getPartitionIdFromParams(thePartitioned))) .thenReturn(Collections.emptySet()); } diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java index 882e628819a2..0aebcda73488 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/mdm/batch2/clear/MdmLinkSlowDeletionSandboxIT.java @@ -39,11 +39,11 @@ public class MdmLinkSlowDeletionSandboxIT extends BaseMdmR4Test { private final int ourMdmLinksToCreate = 1_000_000; private final int ourLogMdmLinksEach = 1_000; + /** + * Overridden so we don't purge the DB in between tests. + */ @Override - public void afterPurgeDatabase() { - // keep the generated data! -// super.afterPurgeDatabase(); - } + public void afterPurgeDatabase() {} @Disabled @Test @@ -55,7 +55,6 @@ void createMdmLinks() { assertTrue(totalLinks > 0); } - private void generatePatientsAndMdmLinks(int theLinkCount) { StopWatch sw = new StopWatch(); int totalMdmLinksCreated = 0; From 9af256411f17ec83bb8439d28537ce61b61a7de1 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 13:22:07 -0700 Subject: [PATCH 19/29] Patch up mock tests --- .../uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index f48819e13828..fee4150b008b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -412,8 +412,7 @@ private LinkedHashSet getExpandedPatientList( if (myMdmLinkExpandSvc.isPresent()) { RequestPartitionId partitionId = theParameters.getPartitionIdOrAllPartitions(); IMdmLinkExpandSvc iMdmLinkExpandSvc = myMdmLinkExpandSvc.get(); - patientPidsToExport.addAll( - iMdmLinkExpandSvc.expandGroup(theParameters.getGroupId(), partitionId)); + patientPidsToExport.addAll(iMdmLinkExpandSvc.expandGroup(theParameters.getGroupId(), partitionId)); } else { ourLog.warn( "Attempted to perform MDM expansion during a group-level export operation, but no IMdmLinkExpandSvc was configured. Is MDM Configured correctly?"); From b40fca6d134945ec66fc3efcd604ce5f527a2a34 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Tue, 14 Oct 2025 14:04:41 -0700 Subject: [PATCH 20/29] Remove fixmes --- .../main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java | 1 - .../src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 1 - 2 files changed, 2 deletions(-) diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java index af488deaa259..18479417ea73 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java @@ -9,7 +9,6 @@ import java.util.Set; -// FIXME GGG unsupportedoperation for all of these. public class DisabledMdmLinkExpandSvc implements IMdmLinkExpandSvc { @Override public Set expandMdmBySourceResource(RequestPartitionId theRequestPartitionId, IBaseResource theResource) { diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 7382c82d6a6a..711b6e430514 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -216,7 +216,6 @@ public Set expandGroup(String theGroupResourceId, RequestPartitionId the SystemRequestDetails requestDetails = new SystemRequestDetails(); requestDetails.setRequestPartitionId(theRequestPartitionId); IBaseResource group = myDaoRegistry.getResourceDao("Group").read(groupId, requestDetails); - // FIXME GGG think more about this cast. How does mongo do this? JpaPid pidOrNull = (JpaPid) myIdHelperService.getPidOrNull(theRequestPartitionId, group); // Attempt to perform MDM Expansion of membership return performMembershipExpansionViaMdmTable(pidOrNull); From 8f2ebcef0b0c64387c23ca1516d7fa6b9e41c309 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Wed, 15 Oct 2025 14:05:11 -0700 Subject: [PATCH 21/29] Remove conditionalonbean --- .../ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 2 -- .../mdm/svc/DisabledMdmLinkExpandSvc.java | 19 +++++++++++++++++++ .../fhir/mdm/util/GoldenResourceHelper.java | 1 - 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 4c350ab167f4..64030926abf8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -41,12 +41,10 @@ import jakarta.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration -@ConditionalOnBean(IMdmSettings.class) public class MdmJpaConfig { private static final Logger ourLog = LoggerFactory.getLogger(MdmJpaConfig.class); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java index 18479417ea73..331e605db561 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/DisabledMdmLinkExpandSvc.java @@ -1,3 +1,22 @@ +/*- + * #%L + * HAPI FHIR - Master Data Management + * %% + * Copyright (C) 2014 - 2025 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% + */ package ca.uhn.fhir.mdm.svc; import ca.uhn.fhir.interceptor.model.RequestPartitionId; diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java index 4b1b061375bb..c318ad6c851a 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java @@ -52,7 +52,6 @@ import static ca.uhn.fhir.context.FhirVersionEnum.R4; import static ca.uhn.fhir.context.FhirVersionEnum.R5; -@Service public class GoldenResourceHelper { private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); From 00547d56e1eddc1449836b8a4f38df930f0a5d1f Mon Sep 17 00:00:00 2001 From: Tadgh Date: Wed, 15 Oct 2025 14:14:38 -0700 Subject: [PATCH 22/29] Remove service annotation --- .../src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java index c318ad6c851a..f2a3e80aadf4 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java @@ -40,7 +40,6 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; From 8547472fb66f9bdcb0c47cd2aaea852da4854ba4 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 17 Oct 2025 10:42:44 -0700 Subject: [PATCH 23/29] bump hapi version --- hapi-deployable-pom/pom.xml | 2 +- hapi-fhir-android/pom.xml | 2 +- hapi-fhir-base/pom.xml | 2 +- hapi-fhir-bom/pom.xml | 4 ++-- hapi-fhir-checkstyle/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-api/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-app/pom.xml | 2 +- hapi-fhir-cli/pom.xml | 2 +- hapi-fhir-client-apache-http5/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 +- hapi-fhir-jacoco/pom.xml | 2 +- hapi-fhir-jaxrsserver-base/pom.xml | 2 +- hapi-fhir-jpa-hibernate-services/pom.xml | 2 +- hapi-fhir-jpa/pom.xml | 2 +- hapi-fhir-jpaserver-base/pom.xml | 2 +- hapi-fhir-jpaserver-elastic-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-hfql/pom.xml | 2 +- hapi-fhir-jpaserver-ips/pom.xml | 2 +- hapi-fhir-jpaserver-mdm/pom.xml | 2 +- hapi-fhir-jpaserver-model/pom.xml | 2 +- hapi-fhir-jpaserver-searchparam/pom.xml | 2 +- hapi-fhir-jpaserver-subscription/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu2/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu3/pom.xml | 2 +- hapi-fhir-jpaserver-test-r4/pom.xml | 2 +- hapi-fhir-jpaserver-test-r4b/pom.xml | 2 +- hapi-fhir-jpaserver-test-r5/pom.xml | 2 +- hapi-fhir-jpaserver-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 2 +- hapi-fhir-repositories/pom.xml | 2 +- hapi-fhir-server-cds-hooks/pom.xml | 2 +- hapi-fhir-server-mdm/pom.xml | 2 +- hapi-fhir-server-openapi/pom.xml | 2 +- hapi-fhir-server/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml | 4 ++-- hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml | 2 +- hapi-fhir-serviceloaders/pom.xml | 2 +- .../hapi-fhir-spring-boot-autoconfigure/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-client-apache/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-client-okhttp/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-server-jersey/pom.xml | 2 +- hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml | 2 +- hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml | 2 +- hapi-fhir-spring-boot/pom.xml | 2 +- hapi-fhir-sql-migrate/pom.xml | 2 +- hapi-fhir-storage-batch2-jobs/pom.xml | 2 +- hapi-fhir-storage-batch2-test-utilities/pom.xml | 2 +- hapi-fhir-storage-batch2/pom.xml | 2 +- hapi-fhir-storage-mdm/pom.xml | 2 +- hapi-fhir-storage-test-utilities/pom.xml | 2 +- hapi-fhir-storage/pom.xml | 2 +- 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-r4b/pom.xml | 2 +- hapi-fhir-structures-r5/pom.xml | 2 +- hapi-fhir-test-utilities/pom.xml | 2 +- hapi-fhir-testpage-overlay/pom.xml | 2 +- hapi-fhir-validation-resources-dstu2.1/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-r4b/pom.xml | 2 +- hapi-fhir-validation-resources-r5/pom.xml | 2 +- hapi-fhir-validation/pom.xml | 2 +- hapi-tinder-plugin/pom.xml | 2 +- hapi-tinder-test/pom.xml | 2 +- pom.xml | 2 +- tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml | 2 +- tests/hapi-fhir-base-test-mindeps-client/pom.xml | 2 +- tests/hapi-fhir-base-test-mindeps-server/pom.xml | 2 +- 79 files changed, 81 insertions(+), 81 deletions(-) diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index 679ff78491f9..e9d55ae19448 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index 89c2f61a3300..54c9d3e9e5b3 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index d5802222537a..5a2c656cc57e 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index bd01e1093be8..d1d6c5e37f21 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -4,7 +4,7 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT pom HAPI FHIR BOM @@ -12,7 +12,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml index 3a1bed6568ad..a7189caa9e58 100644 --- a/hapi-fhir-checkstyle/pom.xml +++ b/hapi-fhir-checkstyle/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index fb87e32e19b8..d7af4d92d1b5 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index a7ad262cea26..516d8566214a 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index d8ba38a3a8f0..af4a1b3368ab 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-client-apache-http5/pom.xml b/hapi-fhir-client-apache-http5/pom.xml index 8c46eb2f5d90..cec442d3711e 100644 --- a/hapi-fhir-client-apache-http5/pom.xml +++ b/hapi-fhir-client-apache-http5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index e4e6a31ff030..8fb698a45222 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index e4f1d87d2c26..0648ea91b72f 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index a998003fafda..be917c96633c 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index 4e6a187e41b0..a294dcf213fc 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index 0ac3501278a4..e2c4e577e4fc 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index b787bd101116..3d1901905859 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 223d60c8550d..a7dfc93b6c5d 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa-hibernate-services/pom.xml b/hapi-fhir-jpa-hibernate-services/pom.xml index 45b6941f7c2b..fdd21f7a1c26 100644 --- a/hapi-fhir-jpa-hibernate-services/pom.xml +++ b/hapi-fhir-jpa-hibernate-services/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml index e2086c71153d..769ec1ac97d6 100644 --- a/hapi-fhir-jpa/pom.xml +++ b/hapi-fhir-jpa/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index 88128e1bfedc..f1185a849ea8 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml index e26422b77078..39a40a9f7e8b 100644 --- a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-hfql/pom.xml b/hapi-fhir-jpaserver-hfql/pom.xml index eb2f54df9e31..d7f113da7778 100644 --- a/hapi-fhir-jpaserver-hfql/pom.xml +++ b/hapi-fhir-jpaserver-hfql/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml index 01b4ef820c2e..90872888c6f1 100644 --- a/hapi-fhir-jpaserver-ips/pom.xml +++ b/hapi-fhir-jpaserver-ips/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index f76af6ddcfe3..b4d49c247b2b 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index 1197c941cdf5..93e882625d54 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index eb61dadfe0ea..85272b6aedb5 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index 2c5fe8d3fa3e..dc241ec57a75 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml index 04bdb8432e68..0b415a3a87f8 100644 --- a/hapi-fhir-jpaserver-test-dstu2/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml index 2ddc185a44ae..bb5f234daa31 100644 --- a/hapi-fhir-jpaserver-test-dstu3/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml index 703deaea6692..6e020d27c1b4 100644 --- a/hapi-fhir-jpaserver-test-r4/pom.xml +++ b/hapi-fhir-jpaserver-test-r4/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml index ae9d4b61d9c7..10f3a673e986 100644 --- a/hapi-fhir-jpaserver-test-r4b/pom.xml +++ b/hapi-fhir-jpaserver-test-r4b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml index fbb6b320a67c..9fa06c056cbf 100644 --- a/hapi-fhir-jpaserver-test-r5/pom.xml +++ b/hapi-fhir-jpaserver-test-r5/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index 3606c9c2df45..45bf5082a661 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 6f7d110fe8f3..8cc4a924d168 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-repositories/pom.xml b/hapi-fhir-repositories/pom.xml index feb4f00037b3..bd47c2ef8f78 100644 --- a/hapi-fhir-repositories/pom.xml +++ b/hapi-fhir-repositories/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-cds-hooks/pom.xml b/hapi-fhir-server-cds-hooks/pom.xml index 28effcc22c81..0753bfc3f663 100644 --- a/hapi-fhir-server-cds-hooks/pom.xml +++ b/hapi-fhir-server-cds-hooks/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index 0c686670adda..afc227dc2d05 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml index b553bf998b29..1fc3c67f9950 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index 9e59c9c854c6..8cd00fd09cfb 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml index df824f8c07ad..cc8e7e9eea7f 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml index c7066838c95d..a50b679e8890 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml @@ -21,7 +21,7 @@ ca.uhn.hapi.fhir hapi-fhir-caching-api - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml index 76541cc77e7c..daf5cc937978 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml index 58a21730ea95..c98cb4acc770 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml @@ -7,7 +7,7 @@ hapi-fhir ca.uhn.hapi.fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../../pom.xml diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml index 336d5289546b..bda1afc4967f 100644 --- a/hapi-fhir-serviceloaders/pom.xml +++ b/hapi-fhir-serviceloaders/pom.xml @@ -5,7 +5,7 @@ hapi-deployable-pom ca.uhn.hapi.fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml 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 86cfff600f97..c8b996ec3c6a 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 - 8.5.8-SNAPSHOT + 8.5.9-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 018042032ddf..e2f7296f12b8 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 - 8.5.8-SNAPSHOT + 8.5.9-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 ae6b01708d61..6609a9420dca 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT 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 0244ab970411..d62cf6236d38 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT 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 bc118dc1fed5..0aa934a377dd 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT 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 a395f7a872b1..2aa580e8f941 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index 0cf0482ba0bd..3b4151ba87f3 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml index b4ef048867de..f192f9c5f1f4 100644 --- a/hapi-fhir-sql-migrate/pom.xml +++ b/hapi-fhir-sql-migrate/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml index 3170b48c3f20..ac80ab573884 100644 --- a/hapi-fhir-storage-batch2-jobs/pom.xml +++ b/hapi-fhir-storage-batch2-jobs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml index 0c21cecfd7a8..ef24a8fb795d 100644 --- a/hapi-fhir-storage-batch2-test-utilities/pom.xml +++ b/hapi-fhir-storage-batch2-test-utilities/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml index 3817936b8aff..e1be0659072c 100644 --- a/hapi-fhir-storage-batch2/pom.xml +++ b/hapi-fhir-storage-batch2/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml index ae027c388788..b3cccb1da632 100644 --- a/hapi-fhir-storage-mdm/pom.xml +++ b/hapi-fhir-storage-mdm/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml index 6b3bb99a00a7..99c2c3e0e502 100644 --- a/hapi-fhir-storage-test-utilities/pom.xml +++ b/hapi-fhir-storage-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml index 0599b812cd05..c59464709a41 100644 --- a/hapi-fhir-storage/pom.xml +++ b/hapi-fhir-storage/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index d9ba3b64ca39..f88cc79dc9d6 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index 6b069add2187..91b585491cf8 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index 79217d2a7c0d..23be709c377a 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 - 8.5.8-SNAPSHOT + 8.5.9-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 52bcd3969a18..aa940d628102 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index 28c0ba983057..e8a1d946b533 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml index 273baec9af1e..f7035b677a9b 100644 --- a/hapi-fhir-structures-r4b/pom.xml +++ b/hapi-fhir-structures-r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index 1ef12e56dad9..f9712d900706 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index db1a7bab91f4..c4cd67a465eb 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index edb00022adfb..2238abe336e7 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index f6d68b49f9c9..85051214607c 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 - 8.5.8-SNAPSHOT + 8.5.9-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 ceb6ee51b88b..963b26cb47f5 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 - 8.5.8-SNAPSHOT + 8.5.9-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 82a547317836..2472e26646c1 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 - 8.5.8-SNAPSHOT + 8.5.9-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 742cc287c46c..813e6464b6fd 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml index b40ae34f3db9..dd1e5f317e3b 100644 --- a/hapi-fhir-validation-resources-r4b/pom.xml +++ b/hapi-fhir-validation-resources-r4b/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-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 a8b264266675..f6e41d04a699 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index 00b3608d5111..296f5f9252a0 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index 4c0ab38850ab..ffbe4ef923df 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index 1263536b4d6a..2d5ae9a778b9 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index ac659aac3fd3..e356ffe60bf8 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-fhir pom - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT HAPI-FHIR An open-source implementation of the FHIR specification in Java. diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index a53239947178..59bc17eb2a91 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-fhir - 8.5.8-SNAPSHOT + 8.5.9-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 10c8975a8895..9722b6b65288 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 - 8.5.8-SNAPSHOT + 8.5.9-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 09b8bcea3904..991e1e027bc7 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 - 8.5.8-SNAPSHOT + 8.5.9-SNAPSHOT ../../pom.xml From 4d46c84ab15c17dabc8972ecf0c0da01997b73a5 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 17 Oct 2025 12:25:29 -0700 Subject: [PATCH 24/29] Remove another useless configuration class --- .../uhn/fhir/jpa/batch2/JpaBatch2Config.java | 10 +++-- .../bulk/export/job/BulkExportJobConfig.java | 37 ------------------- .../export/svc/JpaBulkExportProcessor.java | 14 ------- .../uhn/fhir/mdm/api/IMdmLinkExpandSvc.java | 1 + hapi-fhir-storage-batch2-jobs/pom.xml | 5 +++ .../ExpandResourceAndWriteBinaryStep.java | 16 +++++++- .../jobs/export/ExpandResourcesStep.java | 16 +++++++- .../bulk/export/api/IBulkExportProcessor.java | 6 --- 8 files changed, 43 insertions(+), 62 deletions(-) delete mode 100644 hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobConfig.java diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java index 0ed2de94855a..7308dbe44fd9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java @@ -22,20 +22,24 @@ import ca.uhn.fhir.batch2.api.IJobPersistence; import ca.uhn.fhir.batch2.config.BaseBatch2Config; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; -import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig; import ca.uhn.fhir.jpa.dao.data.IBatch2JobInstanceRepository; import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkMetadataViewRepository; import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkRepository; import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; +import ca.uhn.fhir.mdm.svc.MdmExpansionCacheSvc; import jakarta.persistence.EntityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; @Configuration -@Import({BulkExportJobConfig.class}) public class JpaBatch2Config extends BaseBatch2Config { + //FIXME GGG move this to a specific job definition + @Bean + public MdmExpansionCacheSvc mdmExpansionCacheSvc() { + return new MdmExpansionCacheSvc(); + } + @Bean public IJobPersistence batch2JobInstancePersister( IBatch2JobInstanceRepository theJobInstanceRepository, diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobConfig.java deleted file mode 100644 index 2c6286bc78f5..000000000000 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/job/BulkExportJobConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * #%L - * HAPI FHIR JPA Server - * %% - * Copyright (C) 2014 - 2025 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% - */ -package ca.uhn.fhir.jpa.bulk.export.job; - -import ca.uhn.fhir.mdm.svc.MdmExpansionCacheSvc; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Spring batch Job configuration file. Contains all necessary plumbing to run a - * Bulk Export job. - */ -@Configuration -public class BulkExportJobConfig { - - @Bean - public MdmExpansionCacheSvc mdmExpansionCacheSvc() { - return new MdmExpansionCacheSvc(); - } -} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index fee4150b008b..e37c52bb6e49 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -345,20 +345,6 @@ protected RuntimeSearchParam getPatientSearchParamForCurrentResourceType(String return searchParam; } - @Override - public void expandMdmResources(List theResources) { - if (myMdmLinkExpandSvc.isPresent()) { - for (IBaseResource resource : theResources) { - if (!PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(resource.fhirType())) { - myMdmLinkExpandSvc.get().annotateResource(resource); - } - } - } else { - ourLog.warn( - "Attempted to perform MDM expansion, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); - } - } - /** * For Patient **/ diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java index 8ec772f89d9e..7453f187ee6f 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmLinkExpandSvc.java @@ -48,6 +48,7 @@ Set expandMdmByGoldenResourcePid( * the members of the group + the mdm matched resources to a member in the group */ Set expandGroup(String groupResourceId, RequestPartitionId requestPartitionId); + /** * annotates the given resource to be exported with the implementation specific extra information if applicable */ diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml index ac80ab573884..9df61304f6f7 100644 --- a/hapi-fhir-storage-batch2-jobs/pom.xml +++ b/hapi-fhir-storage-batch2-jobs/pom.xml @@ -19,6 +19,11 @@ hapi-fhir-base ${project.version} + + ca.uhn.hapi.fhir + hapi-fhir-server-mdm + ${project.version} + ca.uhn.hapi.fhir hapi-fhir-storage-batch2 diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java index 87a22b8b1b3a..78109a945ca6 100644 --- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java +++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java @@ -48,6 +48,7 @@ import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryMatchResult; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; import ca.uhn.fhir.jpa.util.RandomTextUtils; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.IBundleProvider; @@ -91,6 +92,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import static ca.uhn.fhir.batch2.jobs.export.BulkDataExportUtil.PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES; import static ca.uhn.fhir.batch2.jobs.imprt.BulkImportAppCtx.PARAM_MAXIMUM_BATCH_SIZE_DEFAULT; import static ca.uhn.fhir.rest.api.Constants.PARAM_ID; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -133,6 +135,9 @@ public class ExpandResourceAndWriteBinaryStep @Autowired private IBulkDataExportHistoryHelper myExportHelper; + @Autowired(required = false) + private Optional myMdmLinkExpandSvc; + private volatile ResponseTerminologyTranslationSvc myResponseTerminologyTranslationSvc; /** @@ -518,7 +523,16 @@ public void accept(List theResources) throws JobExecutionFailedEx // if necessary, expand resources if (parameters.isExpandMdm()) { - myBulkExportProcessor.expandMdmResources(theResources); + if (myMdmLinkExpandSvc.isPresent()) { + for (IBaseResource resource : theResources) { + if (!PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(resource.fhirType())) { + myMdmLinkExpandSvc.get().annotateResource(resource); + } + } + } else { + ourLog.warn( + "Attempted to annotate a resource with an extension identifying it's associated golden resource, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); + } } // Normalize terminology diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java index dbf60025b7a1..bef97017b4fc 100644 --- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java +++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java @@ -42,6 +42,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryMatchResult; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; +import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.SystemRequestDetails; @@ -66,6 +67,7 @@ import java.util.Set; import java.util.stream.Collectors; +import static ca.uhn.fhir.batch2.jobs.export.BulkDataExportUtil.PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES; import static ca.uhn.fhir.rest.api.Constants.PARAM_ID; import static org.slf4j.LoggerFactory.getLogger; @@ -100,6 +102,9 @@ public class ExpandResourcesStep @Autowired private InterceptorService myInterceptorService; + @Autowired(required = false) + private Optional myMdmLinkExpandSvc; + private volatile ResponseTerminologyTranslationSvc myResponseTerminologyTranslationSvc; @Nonnull @@ -139,7 +144,16 @@ public RunOutcome run( // if necessary, expand resources if (parameters.isExpandMdm()) { - myBulkExportProcessor.expandMdmResources(allResources); + if (myMdmLinkExpandSvc.isPresent()) { + for (IBaseResource resource : allResources) { + if (!PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(resource.fhirType())) { + myMdmLinkExpandSvc.get().annotateResource(resource); + } + } + } else { + ourLog.warn( + "Attempted to annotate a resource with an extension identifying it's associated golden resource, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); + } } // Normalize terminology diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java index c1b297ee4b4e..d159494554f9 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java @@ -34,10 +34,4 @@ public interface IBulkExportProcessor { * @return */ Iterator getResourcePidIterator(ExportPIDIteratorParameters theParams); - - /** - * Does the MDM expansion of resources if necessary - * @param theResources - the list of resources to expand - */ - void expandMdmResources(List theResources); } From 5f154708548833902df0e31a76c1aea08ba8dc6e Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 17 Oct 2025 12:35:43 -0700 Subject: [PATCH 25/29] Make the cacher no longer a bean, as its used only inside of the mdmlinkexpandsvc --- .../java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java | 5 ----- .../java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 10 +++++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java index 7308dbe44fd9..c83774956ef0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java @@ -34,11 +34,6 @@ @Configuration public class JpaBatch2Config extends BaseBatch2Config { - //FIXME GGG move this to a specific job definition - @Bean - public MdmExpansionCacheSvc mdmExpansionCacheSvc() { - return new MdmExpansionCacheSvc(); - } @Bean public IJobPersistence batch2JobInstancePersister( diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 711b6e430514..5266148a218b 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -60,7 +60,6 @@ import java.util.Set; import java.util.stream.Collectors; -@Service @Transactional public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); @@ -77,12 +76,13 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { @Autowired private DaoRegistry myDaoRegistry; - @Autowired - private MdmExpansionCacheSvc myMdmExpansionCacheSvc; - private IFhirPath myFhirPath; - public MdmLinkExpandSvc() {} + private MdmExpansionCacheSvc myMdmExpansionCacheSvc; + + public MdmLinkExpandSvc() { + myMdmExpansionCacheSvc = new MdmExpansionCacheSvc(); + } private IFhirPath getFhirPath() { if (myFhirPath == null) { From 557da593ea8fe16001901af5411d7a90dcbe6d61 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 17 Oct 2025 12:38:27 -0700 Subject: [PATCH 26/29] Make the cacher no longer a bean, as its used only inside of the mdmlinkexpandsvc --- .../src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java | 2 -- .../src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 1 - .../batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java | 2 +- .../ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java | 2 +- .../ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java | 2 -- 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java index c83774956ef0..c2da71730f74 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/batch2/JpaBatch2Config.java @@ -26,7 +26,6 @@ import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkMetadataViewRepository; import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkRepository; import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; -import ca.uhn.fhir.mdm.svc.MdmExpansionCacheSvc; import jakarta.persistence.EntityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,7 +33,6 @@ @Configuration public class JpaBatch2Config extends BaseBatch2Config { - @Bean public IJobPersistence batch2JobInstancePersister( IBatch2JobInstanceRepository theJobInstanceRepository, diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 5266148a218b..bcca69c0ec19 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -47,7 +47,6 @@ import org.hl7.fhir.instance.model.api.IIdType; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Collection; diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java index 78109a945ca6..ec9073c15d84 100644 --- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java +++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourceAndWriteBinaryStep.java @@ -531,7 +531,7 @@ public void accept(List theResources) throws JobExecutionFailedEx } } else { ourLog.warn( - "Attempted to annotate a resource with an extension identifying it's associated golden resource, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); + "Attempted to annotate a resource with an extension identifying it's associated golden resource, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); } } diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java index bef97017b4fc..df503f49f2de 100644 --- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java +++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/ExpandResourcesStep.java @@ -152,7 +152,7 @@ public RunOutcome run( } } else { ourLog.warn( - "Attempted to annotate a resource with an extension identifying it's associated golden resource, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); + "Attempted to annotate a resource with an extension identifying it's associated golden resource, but no IMdmLinkExpandSvc was configured. Is MDM configured correctly?"); } } diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java index d159494554f9..a70ab7a3e29e 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/bulk/export/api/IBulkExportProcessor.java @@ -21,10 +21,8 @@ import ca.uhn.fhir.jpa.bulk.export.model.ExportPIDIteratorParameters; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; -import org.hl7.fhir.instance.model.api.IBaseResource; import java.util.Iterator; -import java.util.List; public interface IBulkExportProcessor { From c6843664fd4521b3e4ca6652e271c13c8b73a808 Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 17 Oct 2025 12:48:29 -0700 Subject: [PATCH 27/29] Remove usage of the mdm expansion cache entirely. It doesnt work distributed, and we need a better approach. --- .../fhir/mdm/svc/MdmExpansionCacheSvc.java | 106 ------------------ .../ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 60 +--------- 2 files changed, 4 insertions(+), 162 deletions(-) delete mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpansionCacheSvc.java diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpansionCacheSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpansionCacheSvc.java deleted file mode 100644 index 1bc409ba3123..000000000000 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmExpansionCacheSvc.java +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * #%L - * HAPI FHIR - Master Data Management - * %% - * Copyright (C) 2014 - 2025 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% - */ -package ca.uhn.fhir.mdm.svc; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import static org.slf4j.LoggerFactory.getLogger; - -/** - * The purpose of this class is to share context between steps of a given GroupBulkExport job. - * - * This cache allows you to port state between reader/processor/writer. In this case, we are maintaining - * a cache of Source Resource ID -> Golden Resource ID, so that we can annotate outgoing resources with their golden owner - * if applicable. - * - */ -public class MdmExpansionCacheSvc { - private static final Logger ourLog = getLogger(MdmExpansionCacheSvc.class); - - private final ConcurrentHashMap mySourceToGoldenIdCache = new ConcurrentHashMap<>(); - - /** - * Lookup a given resource's golden resource ID in the cache. Note that if you pass this function the resource ID of a - * golden resource, it will just return itself. - * - * @param theSourceId the resource ID of the source resource ,e.g. PAT123 - * @return the resource ID of the associated golden resource. - */ - public String getGoldenResourceId(String theSourceId) { - ourLog.debug(buildLogMessage("About to lookup cached resource ID " + theSourceId)); - String goldenResourceId = mySourceToGoldenIdCache.get(theSourceId); - - // A golden resources' golden resource ID is itself. - if (StringUtils.isBlank(goldenResourceId)) { - if (mySourceToGoldenIdCache.containsValue(theSourceId)) { - goldenResourceId = theSourceId; - } - } - return goldenResourceId; - } - - private String buildLogMessage(String theMessage) { - return buildLogMessage(theMessage, false); - } - - /** - * Builds a log message, potentially enriched with the cache content. - * - * @param message The log message - * @param theAddCacheContentContent If true, will annotate the log message with the current cache contents. - * @return a built log message, which may include the cache content. - */ - public String buildLogMessage(String message, boolean theAddCacheContentContent) { - StringBuilder builder = new StringBuilder(); - builder.append(message); - if (ourLog.isDebugEnabled() || theAddCacheContentContent) { - builder.append("\n").append("Current cache content is:").append("\n"); - mySourceToGoldenIdCache.entrySet().stream().forEach(entry -> builder.append(entry.getKey()) - .append(" -> ") - .append(entry.getValue()) - .append("\n")); - return builder.toString(); - } - return builder.toString(); - } - - /** - * Populate the cache - * - * @param theSourceResourceIdToGoldenResourceIdMap the source ID -> golden ID map to populate the cache with. - */ - public void setCacheContents(Map theSourceResourceIdToGoldenResourceIdMap) { - if (mySourceToGoldenIdCache.isEmpty()) { - this.mySourceToGoldenIdCache.putAll(theSourceResourceIdToGoldenResourceIdMap); - } - } - - /** - * Since this cache is used at @JobScope, we can skip a whole whack of expansions happening by simply checking - * if one of our child steps has populated the cache yet. . - */ - public boolean hasBeenPopulated() { - return !mySourceToGoldenIdCache.isEmpty(); - } -} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index bcca69c0ec19..1459c5c0f1a8 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -77,10 +77,8 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private IFhirPath myFhirPath; - private MdmExpansionCacheSvc myMdmExpansionCacheSvc; public MdmLinkExpandSvc() { - myMdmExpansionCacheSvc = new MdmExpansionCacheSvc(); } private IFhirPath getFhirPath() { @@ -243,59 +241,8 @@ private Set performMembershipExpansionViaMdmTable(JpaPid pidOrNull) { uniquePids.add(tuple.getGoldenPid()); uniquePids.add(tuple.getSourcePid()); }); - populateMdmResourceCache(goldenPidTargetPidTuples); return uniquePids; } - /** - * @param thePidTuples - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - private void populateMdmResourceCache(List> thePidTuples) { - if (myMdmExpansionCacheSvc.hasBeenPopulated()) { - return; - } - // First, convert this zipped set of tuples to a map of - // { - // patient/gold-1 -> [patient/1, patient/2] - // patient/gold-2 -> [patient/3, patient/4] - // } - Map> goldenResourceToSourcePidMap = new HashMap<>(); - extract(thePidTuples, goldenResourceToSourcePidMap); - - // Next, lets convert it to an inverted index for fast lookup - // { - // patient/1 -> patient/gold-1 - // patient/2 -> patient/gold-1 - // patient/3 -> patient/gold-2 - // patient/4 -> patient/gold-2 - // } - Map sourceResourceIdToGoldenResourceIdMap = new HashMap<>(); - goldenResourceToSourcePidMap.forEach((key, value) -> { - String goldenResourceId = (String) - myIdHelperService.translatePidIdToForcedIdWithCache(key).orElseGet(key::toString); - PersistentIdToForcedIdMap pidsToForcedIds = myIdHelperService.translatePidsToForcedIds(value); - - Set sourceResourceIds = pidsToForcedIds.getResolvedResourceIds(); - - sourceResourceIds.forEach( - sourceResourceId -> sourceResourceIdToGoldenResourceIdMap.put(sourceResourceId, goldenResourceId)); - }); - - // Now that we have built our cached expansion, store it. - myMdmExpansionCacheSvc.setCacheContents(sourceResourceIdToGoldenResourceIdMap); - } - - private void extract( - List> theGoldenPidTargetPidTuples, - Map> theGoldenResourceToSourcePidMap) { - for (MdmPidTuple goldenPidTargetPidTuple : theGoldenPidTargetPidTuples) { - JpaPid goldenPid = goldenPidTargetPidTuple.getGoldenPid(); - JpaPid sourcePid = goldenPidTargetPidTuple.getSourcePid(); - theGoldenResourceToSourcePidMap - .computeIfAbsent(goldenPid, key -> new HashSet<>()) - .add(sourcePid); - } - } private Optional getPatientReference(IBaseResource iBaseResource) { String fhirPath; @@ -318,10 +265,11 @@ private Optional getPatientReference(IBaseResource iBaseResource) { } private void addGoldenResourceExtension(IBaseResource iBaseResource, String sourceResourceId) { - String goldenResourceId = myMdmExpansionCacheSvc.getGoldenResourceId(sourceResourceId); - IBaseExtension extension = ExtensionUtil.getOrCreateExtension( - iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); + // TODO, reimplement this, it is currently completely broken given the distributed nature of the job. + String goldenResourceId = "";//TODO we must be able to fetch this, for now, will be no-op if (!StringUtils.isBlank(goldenResourceId)) { + IBaseExtension extension = ExtensionUtil.getOrCreateExtension( + iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); ExtensionUtil.setExtension(myContext, extension, "reference", prefixPatient(goldenResourceId)); } } From 37dad05c27ff34d953d09dbb59d6a5b8ef9ef5ef Mon Sep 17 00:00:00 2001 From: Gary Date: Fri, 17 Oct 2025 12:50:01 -0700 Subject: [PATCH 28/29] Spotless --- .../java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java index 1459c5c0f1a8..a080672d4a13 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/svc/MdmLinkExpandSvc.java @@ -25,7 +25,6 @@ import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap; import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.mdm.api.IMdmLinkExpandSvc; @@ -51,10 +50,8 @@ import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -77,9 +74,7 @@ public class MdmLinkExpandSvc implements IMdmLinkExpandSvc { private IFhirPath myFhirPath; - - public MdmLinkExpandSvc() { - } + public MdmLinkExpandSvc() {} private IFhirPath getFhirPath() { if (myFhirPath == null) { @@ -265,11 +260,11 @@ private Optional getPatientReference(IBaseResource iBaseResource) { } private void addGoldenResourceExtension(IBaseResource iBaseResource, String sourceResourceId) { - // TODO, reimplement this, it is currently completely broken given the distributed nature of the job. - String goldenResourceId = "";//TODO we must be able to fetch this, for now, will be no-op + // TODO, reimplement this, it is currently completely broken given the distributed nature of the job. + String goldenResourceId = ""; // TODO we must be able to fetch this, for now, will be no-op if (!StringUtils.isBlank(goldenResourceId)) { IBaseExtension extension = ExtensionUtil.getOrCreateExtension( - iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); + iBaseResource, HapiExtensions.ASSOCIATED_GOLDEN_RESOURCE_EXTENSION_URL); ExtensionUtil.setExtension(myContext, extension, "reference", prefixPatient(goldenResourceId)); } } From 42bc3e03b9b16e839f23915e9c1f52604e450413 Mon Sep 17 00:00:00 2001 From: Gary Date: Sun, 19 Oct 2025 11:32:55 -0700 Subject: [PATCH 29/29] Make IMdmSettings nullable --- .../src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java index 64030926abf8..a7d3aac9931f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/MdmJpaConfig.java @@ -69,7 +69,7 @@ public IMdmLinkImplFactory mdmLinkImplFactory() { @Bean public IMdmLinkExpandSvc mdmLinkExpandSvc( EIDHelper theEidHelper, - IMdmSettings theMdmSettings, + @Nullable IMdmSettings theMdmSettings, DaoRegistry theDaoRegistry, FhirContext theFhirContext, IIdHelperService theIdHelperService) {