From 852b96df579005b11918199552e19b9636b77642 Mon Sep 17 00:00:00 2001 From: Dylan Krause Date: Sun, 29 Jun 2025 13:16:14 -0400 Subject: [PATCH] Bug Fix in PackageInstallerSvcImpl when using MultiTenancy with Default Tenant ID Set -deprecated method RequestPartitionId.defaultPartition() returns null even when default id is set -under a multitenancy installation; this causes BaseRequestPartitionHelperSvc to throw an error when installing non-partionable resources via system ig loading after changes implimented in version 8.2 -replace with getting id from the partition settings --- .../jpa/packages/PackageInstallerSvcImpl.java | 6 ++- .../packages/PackageInstallerSvcImplTest.java | 52 +++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java index 54a247aa59f4..82126eea325d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java @@ -184,7 +184,8 @@ public PackageInstallOutcomeJson install(PackageInstallationSpec theInstallation boolean exists = myTxService .withSystemRequest() - .withRequestPartitionId(RequestPartitionId.defaultPartition()) + .withRequestPartitionId( + RequestPartitionId.fromPartitionId(myPartitionSettings.getDefaultPartitionId())) .execute(() -> { Optional existing = myPackageVersionDao.findByPackageIdAndVersion( theInstallationSpec.getName(), theInstallationSpec.getVersion()); @@ -524,7 +525,8 @@ private DaoMethodOutcome updateResource(IFhirResourceDao theDao, IBaseResource t private RequestDetails createRequestDetails() { SystemRequestDetails requestDetails = new SystemRequestDetails(); if (myPartitionSettings.isPartitioningEnabled()) { - requestDetails.setRequestPartitionId(RequestPartitionId.defaultPartition()); + requestDetails.setRequestPartitionId( + RequestPartitionId.fromPartitionId(myPartitionSettings.getDefaultPartitionId())); } return requestDetails; } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImplTest.java index 67ea60b3ecd4..76618eb5cc86 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImplTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImplTest.java @@ -3,6 +3,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.support.IValidationSupport; +import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -17,6 +18,7 @@ import ca.uhn.fhir.jpa.searchparam.util.SearchParameterHelper; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.SystemRequestDetails; import ca.uhn.fhir.rest.server.SimpleBundleProvider; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.hapi.converters.canonical.VersionCanonicalizer; @@ -65,6 +67,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.params.provider.Arguments.arguments; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; @@ -317,6 +320,55 @@ public void testCreateOrUpdate_withSearchParameter(String theExistingId, Collect assertEquals(theInstallBase, capturedSP.getBase().stream().map(CodeType::getCode).toList()); } + @Test + void testInstall_WithPartitioningEnabled_UsesDefaultPartition() throws IOException { + + myPartitionSettings.setPartitioningEnabled(true); + myPartitionSettings.setDefaultPartitionId(0); + + CodeSystem codeSystem = new CodeSystem(); + codeSystem.setId("CodeSystem/test-cs"); + codeSystem.setUrl("http://example.com/test-codesystem"); + codeSystem.setStatus(Enumerations.PublicationStatus.ACTIVE); + + PackageInstallationSpec spec = setupResourceInPackage(null, codeSystem, myCodeSystemDao); + + mySvc.install(spec); + + verify(myCodeSystemDao, times(1)).search(any(SearchParameterMap.class), myRequestDetailsCaptor.capture()); + verify(myCodeSystemDao, times(1)).update(any(CodeSystem.class), myRequestDetailsCaptor.capture()); + + List allRequestDetails = myRequestDetailsCaptor.getAllValues(); + RequestPartitionId defaultPartitionId = RequestPartitionId.fromPartitionId(myPartitionSettings.getDefaultPartitionId()); + for (RequestDetails requestDetails : allRequestDetails) { + SystemRequestDetails systemRequest = (SystemRequestDetails) requestDetails; + assertEquals(defaultPartitionId, systemRequest.getRequestPartitionId()); + } + } + + @Test + void testInstall_WithPartitioningDisabled_NoPartitionSet() throws IOException { + myPartitionSettings.setPartitioningEnabled(false); + + CodeSystem codeSystem = new CodeSystem(); + codeSystem.setId("CodeSystem/test-cs"); + codeSystem.setUrl("http://example.com/test-codesystem"); + codeSystem.setStatus(Enumerations.PublicationStatus.ACTIVE); + + PackageInstallationSpec spec = setupResourceInPackage(null, codeSystem, myCodeSystemDao); + + mySvc.install(spec); + + verify(myCodeSystemDao, times(1)).search(any(SearchParameterMap.class), myRequestDetailsCaptor.capture()); + verify(myCodeSystemDao, times(1)).update(any(CodeSystem.class), myRequestDetailsCaptor.capture()); + + List allRequestDetails = myRequestDetailsCaptor.getAllValues(); + for (RequestDetails requestDetails : allRequestDetails) { + SystemRequestDetails systemRequest = (SystemRequestDetails) requestDetails; + assertNull(systemRequest.getRequestPartitionId()); + } + } + private PackageInstallationSpec setupResourceInPackage(IBaseResource myExistingResource, IBaseResource myInstallResource, IFhirResourceDao myFhirResourceDao) throws IOException { NpmPackage pkg = createPackage(myInstallResource, myInstallResource.getClass().getSimpleName());