Update resources on package reinstall (#2078)

* Start testing

* Update resources on package install

* Add changelog
This commit is contained in:
James Agnew 2020-09-15 08:46:43 -04:00 committed by GitHub
parent ea5fba6dfb
commit 9711b5ed18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 3 deletions

View File

@ -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."

View File

@ -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.dao.data.INpmPackageVersionDao;
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 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.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.param.UriParam; import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 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.FhirTerser;
import ca.uhn.fhir.util.SearchParameterUtil; import ca.uhn.fhir.util.SearchParameterUtil;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -94,6 +96,8 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
private PlatformTransactionManager myTxManager; private PlatformTransactionManager myTxManager;
@Autowired @Autowired
private INpmPackageVersionDao myPackageVersionDao; private INpmPackageVersionDao myPackageVersionDao;
@Autowired
private ISearchParamRegistry mySearchParamRegistry;
/** /**
* Constructor * Constructor
@ -161,6 +165,9 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
if (theInstallationSpec.getInstallMode() == PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL) { if (theInstallationSpec.getInstallMode() == PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL) {
install(npmPackage, theInstallationSpec, retVal); install(npmPackage, theInstallationSpec, retVal);
// If any SearchParameters were installed, let's load them right away
mySearchParamRegistry.refreshCacheIfNecessary();
} }
} catch (IOException e) { } catch (IOException e) {
@ -304,11 +311,20 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResource.getClass()); IFhirResourceDao dao = myDaoRegistry.getResourceDao(theResource.getClass());
SearchParameterMap map = createSearchParameterMapFor(theResource); SearchParameterMap map = createSearchParameterMapFor(theResource);
IBundleProvider searchResult = dao.search(map); 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)); theOutcome.incrementResourcesInstalled(myFhirContext.getResourceType(theResource));
dao.create(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);
} }
} }

View File

@ -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.NpmPackageVersionEntity;
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 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.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; 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.param.UriParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.test.utilities.JettyUtil; 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.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.api.IBaseResource; 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.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.r4.model.StructureDefinition;
import org.hl7.fhir.utilities.cache.NpmPackage; import org.hl7.fhir.utilities.cache.NpmPackage;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
@ -230,7 +239,6 @@ public class NpmTestR4 extends BaseJpaR4Test {
} }
@Test @Test
public void testInstallR4PackageWithNoDescription() throws Exception { public void testInstallR4PackageWithNoDescription() throws Exception {
myDaoConfig.setAllowExternalReferences(true); 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 @Test
public void testLoadContents() throws IOException { public void testLoadContents() throws IOException {
byte[] contents0111 = loadClasspathBytes("/packages/hl7.fhir.uv.shorthand-0.11.1.tgz"); byte[] contents0111 = loadClasspathBytes("/packages/hl7.fhir.uv.shorthand-0.11.1.tgz");