From 756432e61ac60b3ee2e3924a92838f4a0d5b3350 Mon Sep 17 00:00:00 2001 From: ianmarshall Date: Wed, 21 Oct 2020 15:47:31 -0400 Subject: [PATCH] Enable package installer to load resources other than conformance resources. --- .../jpa/packages/PackageInstallerSvcImpl.java | 25 ++++++++++++- .../ca/uhn/fhir/jpa/packages/NpmTestR4.java | 35 ++++++++++++++++++ .../packages/test-organizations-package.tgz | Bin 0 -> 869 bytes 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 hapi-fhir-jpaserver-base/src/test/resources/packages/test-organizations-package.tgz 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 46256602d0a..4cb69ff28d9 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 @@ -20,6 +20,9 @@ package ca.uhn.fhir.jpa.packages; * #L% */ +import ca.uhn.fhir.context.BaseRuntimeChildDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.support.IValidationSupport; @@ -46,6 +49,7 @@ import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; +import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.utilities.cache.IPackageCacheManager; import org.hl7.fhir.utilities.cache.NpmPackage; import org.slf4j.Logger; @@ -384,9 +388,12 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { } else if (resource.getClass().getSimpleName().equals("Subscription")) { String id = extractIdFromSubscription(resource); return SearchParameterMap.newSynchronous().add("_id", new TokenParam(id)); - } else { + } else if (resourceHasUrlElement(resource)) { String url = extractUniqueUrlFromMetadataResource(resource); return SearchParameterMap.newSynchronous().add("url", new UriParam(url)); + } else { + TokenParam identifierToken = extractIdentifierFromOtherResourceTypes(resource); + return SearchParameterMap.newSynchronous().add("identifier", identifierToken); } } @@ -412,6 +419,22 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { return (String) asPrimitiveType.getValue(); } + private TokenParam extractIdentifierFromOtherResourceTypes(IBaseResource resource) { + FhirTerser terser = myFhirContext.newTerser(); + Identifier myIdentifier = (Identifier) terser.getSingleValueOrNull(resource, "identifier"); + return new TokenParam(myIdentifier.getSystem(), myIdentifier.getValue()); + } + + private boolean resourceHasUrlElement(IBaseResource resource) { + BaseRuntimeElementDefinition def = myFhirContext.getElementDefinition(resource.getClass()); + if (!(def instanceof BaseRuntimeElementCompositeDefinition)) { + throw new IllegalArgumentException("Resource is not a composite type: " + resource.getClass().getName()); + } + BaseRuntimeElementCompositeDefinition currentDef = (BaseRuntimeElementCompositeDefinition) def; + BaseRuntimeChildDefinition nextDef = currentDef.getChildByName("url"); + return nextDef != null; + } + @VisibleForTesting void setFhirContextForUnitTest(FhirContext theCtx) { myFhirContext = theCtx; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/NpmTestR4.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/NpmTestR4.java index bee6c8ffbec..ac78da94fb6 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/NpmTestR4.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/packages/NpmTestR4.java @@ -48,6 +48,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -236,6 +237,40 @@ public class NpmTestR4 extends BaseJpaR4Test { }); } + @Test + public void testInstallR4Package_NonConformanceResources() throws Exception { + myDaoConfig.setAllowExternalReferences(true); + + byte[] bytes = loadClasspathBytes("/packages/test-organizations-package.tgz"); + myFakeNpmServlet.myResponses.put("/test-organizations/1.0.0", bytes); + + List resourceList = new ArrayList<>(); + resourceList.add("Organization"); + PackageInstallationSpec spec = new PackageInstallationSpec().setName("test-organizations").setVersion("1.0.0").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL); + spec.setInstallResourceTypes(resourceList); + PackageInstallOutcomeJson outcome = igInstaller.install(spec); + assertEquals(3, outcome.getResourcesInstalled().get("Organization")); + + // Be sure no further communication with the server + JettyUtil.closeServer(myServer); + + // Search for the installed resources + runInTransaction(() -> { + SearchParameterMap map = SearchParameterMap.newSynchronous(); + map.add(Organization.SP_IDENTIFIER, new TokenParam("https://github.com/synthetichealth/synthea", "organization1")); + IBundleProvider result = myOrganizationDao.search(map); + assertEquals(1, result.sizeOrThrowNpe()); + map = SearchParameterMap.newSynchronous(); + map.add(Organization.SP_IDENTIFIER, new TokenParam("https://github.com/synthetichealth/synthea", "organization2")); + result = myOrganizationDao.search(map); + assertEquals(1, result.sizeOrThrowNpe()); + map = SearchParameterMap.newSynchronous(); + map.add(Organization.SP_IDENTIFIER, new TokenParam("https://github.com/synthetichealth/synthea", "organization3")); + result = myOrganizationDao.search(map); + assertEquals(1, result.sizeOrThrowNpe()); + }); + + } @Test public void testInstallR4Package_DraftResourcesNotInstalled() throws Exception { diff --git a/hapi-fhir-jpaserver-base/src/test/resources/packages/test-organizations-package.tgz b/hapi-fhir-jpaserver-base/src/test/resources/packages/test-organizations-package.tgz new file mode 100644 index 0000000000000000000000000000000000000000..a3f53110d0c5b5968591bdbc2f42b954d0973868 GIT binary patch literal 869 zcmV-r1DgCFiwFRYS&&}<1MOGebDKC2&U60?4bR1vkPy%}pTk`;b?l7oB zEd~#WOx;ZW_X^=3^y2#JY3j5M-vhE&tJO*?eY;vP{*lc@_v9x6Lg?5w&@HW7Xpy>I z0U+!U0&QX|1&9c;$O*82rc-N_g=D#MC1&ZIb}# zOXJT>##xFwABrq}ygAfLe`Ha*i9fcfioatM=LEpVbK%=~=JCIK0f3Qt*dMjTXfOgW?>56pmt$i%`9O_zGy3?U1l3q9^~vep-=jKf&uYTR2T z0pL!5RbR0zq?lLsA}JTet8RA|%c#8R@NC{KmZ^+{jCmwjBBRxRrmgDHw=5~OlUeh` z8oK*lec$Q%8JF>Gr6%)IXo;-X_8(t(7R2dnBX9QY@Kw1gMLv(yEXiiePLwzu|=$IW?X3eUWFkU-txYu}Ijm>O9jc=PVcCQt7F!%#Dre{p#1d&4x(v zN$wrC-IbKh_4JqhOGG?^tvXmN2-FEE9_~&Or{b%xHfHMXNKtoeg^Nsylm2Q)poNHQI?!^r8ayjgnQMzzlg3(J+&}fL`E#&~|E(kQ zzdDE;{wD-!{>QZC|6|}F{tu{U3CqPMbTKxu1(E3r+crt)QkQugI+#8Q|648pAHx4< zy}{t3H+~Jy{N7-C1}1MNQ~#oloD_*rf!G(eMU{Ma>DfA}^{`pj1!?c3>?n^Q4l5aUv8kmW2q*xNOBU)NT) zEMO32OqcG@=DPiI*j4}GW7mJAasMH1>%Sx7p!&~)JXFs#ZcEEOA=|Od%g>1Vm16#Cc@r>~WE4kA!02}}STAR7B literal 0 HcmV?d00001