From 9711b5ed1876e1566435a86873be5ee40f0ffc62 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Tue, 15 Sep 2020 08:46:43 -0400 Subject: [PATCH] Update resources on package reinstall (#2078) * Start testing * Update resources on package install * Add changelog --- ...update-resources-on-package-reinstall.yaml | 5 ++ .../jpa/packages/PackageInstallerSvcImpl.java | 20 +++++- .../ca/uhn/fhir/jpa/packages/NpmTestR4.java | 57 +++++++++++++++++- .../packages/test-exchange-sample-2.tgz | Bin 0 -> 1096 bytes .../packages/test-exchange-sample.tgz | Bin 0 -> 1094 bytes 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_2_0/2078-update-resources-on-package-reinstall.yaml create mode 100644 hapi-fhir-jpaserver-base/src/test/resources/packages/test-exchange-sample-2.tgz create mode 100644 hapi-fhir-jpaserver-base/src/test/resources/packages/test-exchange-sample.tgz diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_2_0/2078-update-resources-on-package-reinstall.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_2_0/2078-update-resources-on-package-reinstall.yaml new file mode 100644 index 00000000000..41586bc3b48 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_2_0/2078-update-resources-on-package-reinstall.yaml @@ -0,0 +1,5 @@ +--- +type: add +issue: 2078 +title: "When using package support to install a package with STORE_AND_INSTALL mode, resources that are already + present in the database will now be updated to the contents of the version in the package." 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 60cbe4b5e7c..53c8579ced0 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 @@ -29,11 +29,13 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.UriParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.SearchParameterUtil; import com.google.common.annotations.VisibleForTesting; @@ -94,6 +96,8 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { private PlatformTransactionManager myTxManager; @Autowired private INpmPackageVersionDao myPackageVersionDao; + @Autowired + private ISearchParamRegistry mySearchParamRegistry; /** * Constructor @@ -161,6 +165,9 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { if (theInstallationSpec.getInstallMode() == PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL) { install(npmPackage, theInstallationSpec, retVal); + + // If any SearchParameters were installed, let's load them right away + mySearchParamRegistry.refreshCacheIfNecessary(); } } catch (IOException e) { @@ -304,11 +311,20 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResource.getClass()); SearchParameterMap map = createSearchParameterMapFor(theResource); IBundleProvider searchResult = dao.search(map); - if (searchResult.isEmpty()) { + if (validForUpload(theResource)) { + if (searchResult.isEmpty()) { - if (validForUpload(theResource)) { + ourLog.info("Creating new resource matching {}", map.toNormalizedQueryString(myFhirContext)); theOutcome.incrementResourcesInstalled(myFhirContext.getResourceType(theResource)); dao.create(theResource); + + } else { + + ourLog.info("Updating existing resource matching {}", map.toNormalizedQueryString(myFhirContext)); + theOutcome.incrementResourcesInstalled(myFhirContext.getResourceType(theResource)); + theResource.setId(searchResult.getResources(0,1).get(0).getIdElement().toUnqualifiedVersionless()); + dao.update(theResource); + } } 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 03cdeb14aff..dd09c8f92d8 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 @@ -11,8 +11,11 @@ import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.ReferenceParam; +import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.UriParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.test.utilities.JettyUtil; @@ -22,7 +25,13 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.ImplementationGuide; +import org.hl7.fhir.r4.model.Organization; +import org.hl7.fhir.r4.model.PractitionerRole; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r4.model.StructureDefinition; import org.hl7.fhir.utilities.cache.NpmPackage; import org.junit.jupiter.api.AfterEach; @@ -230,7 +239,6 @@ public class NpmTestR4 extends BaseJpaR4Test { } - @Test public void testInstallR4PackageWithNoDescription() throws Exception { myDaoConfig.setAllowExternalReferences(true); @@ -433,6 +441,53 @@ public class NpmTestR4 extends BaseJpaR4Test { } + @Test + public void testInstallPkgContainingSearchParameter() throws IOException { + myDaoConfig.setAllowExternalReferences(true); + + byte[] contents0111 = loadClasspathBytes("/packages/test-exchange-sample.tgz"); + myFakeNpmServlet.myResponses.put("/test-exchange.fhir.us.com/2.1.1", contents0111); + + contents0111 = loadClasspathBytes("/packages/test-exchange-sample-2.tgz"); + myFakeNpmServlet.myResponses.put("/test-exchange.fhir.us.com/2.1.2", contents0111); + + // Install older version + PackageInstallationSpec spec = new PackageInstallationSpec().setName("test-exchange.fhir.us.com").setVersion("2.1.1").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL); + igInstaller.install(spec); + + IBundleProvider spSearch = mySearchParameterDao.search(SearchParameterMap.newSynchronous("code", new TokenParam("network-id"))); + assertEquals(1, spSearch.sizeOrThrowNpe()); + SearchParameter sp = (SearchParameter) spSearch.getResources(0, 1).get(0); + assertEquals("network-id", sp.getCode()); + assertEquals("2.1", sp.getVersion()); + assertEquals(Enumerations.PublicationStatus.ACTIVE, sp.getStatus()); + + Organization org = new Organization(); + org.setName("Hello"); + IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); + + PractitionerRole pr = new PractitionerRole(); + pr.addExtension().setUrl("http://test-exchange.com/fhir/us/providerdataexchange/StructureDefinition/networkreference").setValue(new Reference(orgId)); + myPractitionerRoleDao.create(pr); + + SearchParameterMap map = SearchParameterMap.newSynchronous("network-id", new ReferenceParam(orgId.getValue())); + spSearch = myPractitionerRoleDao.search(map); + assertEquals(1, spSearch.sizeOrThrowNpe()); + + // Install newer version + spec = new PackageInstallationSpec().setName("test-exchange.fhir.us.com").setVersion("2.1.2").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL); + igInstaller.install(spec); + + spSearch = mySearchParameterDao.search(SearchParameterMap.newSynchronous("code", new TokenParam("network-id"))); + assertEquals(1, spSearch.sizeOrThrowNpe()); + sp = (SearchParameter) spSearch.getResources(0, 1).get(0); + assertEquals("network-id", sp.getCode()); + assertEquals(Enumerations.PublicationStatus.ACTIVE, sp.getStatus()); + assertEquals("2.2", sp.getVersion()); + + } + + @Test public void testLoadContents() throws IOException { byte[] contents0111 = loadClasspathBytes("/packages/hl7.fhir.uv.shorthand-0.11.1.tgz"); diff --git a/hapi-fhir-jpaserver-base/src/test/resources/packages/test-exchange-sample-2.tgz b/hapi-fhir-jpaserver-base/src/test/resources/packages/test-exchange-sample-2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d486d37064c512591f0519d2f1d2bf8b70d0db70 GIT binary patch literal 1096 zcmV-O1h@MiiwFP!000001MOGMZreBz_PI|%=+YFh{w&#Uj5O%qqMJjDq7C*Eeg zo2@Jf6lFUo@??A1N7`4|;g2HQNt!T3hnyMB%*TqRU+EnD-UA{)jK@Ry z49CM@``MxwM&rSFgr9KG3&JoShCMQT$V0VgYC$<6y)SeL^$+B3oBu^onfQMO%G1S1 z%F#>#+!as@7dGjF7ISbbPE)}ID+}Pf%)u={tV{mYWtsP-E{h-UAp<;$}z90h|O2_C}%|MU2NdqRlAp)MPq!s$f?&V)F7FN4#ULM)S0cYZJQA^{tL z%j7Qj3tcUmTB?}?uAl<67*1tuCC88ONjA&8s9z+`LWpYO`|I`ETSs2W=YDv2c<65y zVwoq-@lkbrG(CRTY9b#f$1iLJNB;Eq$j4b9wH-US!KFG(!*jWZQM+S_mzGO^wqV?E zYQN&;ie$o6=g2pE>)X zarDl@WDAEGa41p}6WCOkPi?UG*Ls)`P{>(tjRAoJbl;1o_k1MPs<~GsTMoBv;=i%RuG-&)fGENH zkPx--C-#2b&$j!2*o|LrBD%xj|MSPF#%=za=Ytf0Tkd~hjLB~J|0oP%ng3&(|Br*e z|NQIQHW%H^44D;PQ!D0moyLYOkric`*IV@?+Tlk^37cPMtikgr3?q#GSkL7wMQWtE zSSj4Hg2L5x!4NfClm$!a{WICwz6Z!ch8o^Xk|cvwlI*BTl3Be-l4-;8EJ?~nRE;pk zGLfq@o}xVY&B&9JB{Hccl1wTq0eRQp-p)-7_4Z}tKyE9@`?BbhSIwM6VV_8c5k>Bi z*$089_lC$xlmF1(?+UgPdjVD&SxC$=(4WYHQ>LoAA^eMctfS0h^d47+>4p70foA1R zoBXSErxXfNDCq81v=NI^-7j9hdHvb&OUlqLhGp@FHnMa1>FS}r2DCSjm)+Ijrb_<3 z3r1%%1 O75@N)XD8?YC;$MBTpM)& literal 0 HcmV?d00001 diff --git a/hapi-fhir-jpaserver-base/src/test/resources/packages/test-exchange-sample.tgz b/hapi-fhir-jpaserver-base/src/test/resources/packages/test-exchange-sample.tgz new file mode 100644 index 0000000000000000000000000000000000000000..c2251825349ea6ba1a9158afe7cecfcb79941a86 GIT binary patch literal 1094 zcmV-M1iAYkiwFP!000001MOGMZreBz&bd!P=+YFh{w&FE4A^DM7k#MVrRa^Skl< zT>w?WSt%Ol>M)V<6;X>w<3@6tLN3^Z0Vl`rX-Q7slHghEg;edd8?rI2N-CFWBb?A^5vCIsYi)>&de;27Qa;^_llNx|zx)EwTzgym`zw=v@8 zOi!OV%9ReSjz6`7jp6e;6RgbORW4H-mBEwiUtNz34vV(`J1kFOb&qEL0Nm04y;Vb}EkLqPR^6?=Q#qI^{zCM*Nlan4oEy(!spxNQ^vjWw>T{e1|C5_|{= zQ44=z@7Mk8cK_GC^;Q$n9S;9r9HJVx`QJPrr2yP<|MNpk_BQ`zEx`Pj(`4+=3<4g zixP5M*M)|t(Y(l6LLZ*V*5*Ax7BbZEW)R0IEaG@eRUA*MSsagRmZfoA)S|3KV=NPy zI^!A2lRp}HaymyQHAj+3WhEf*YTVn}$58KHMvmpSg1j&C4tZ5iN#J*gbQn?O9+|!8 zX?oufIcf42?frGZwnE3l0Lenq90UD{EI47RsyBpxmi2X%d5GTQ$}qjKvm;P1oN=99 zN_R>jABDX2-HO&?R;c^M>o>1IH~f+^w2NU`+|x$3Eaeep|LB6T zwwZBAM8UUA&e&L8EOf