Enable package installer to load resources other than conformance resources.

This commit is contained in:
ianmarshall 2020-10-21 15:47:31 -04:00
parent 3738297354
commit 756432e61a
3 changed files with 59 additions and 1 deletions

View File

@ -20,6 +20,9 @@ package ca.uhn.fhir.jpa.packages;
* #L% * #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.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.IValidationSupport; 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.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType; 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.IPackageCacheManager;
import org.hl7.fhir.utilities.cache.NpmPackage; import org.hl7.fhir.utilities.cache.NpmPackage;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -384,9 +388,12 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
} else if (resource.getClass().getSimpleName().equals("Subscription")) { } else if (resource.getClass().getSimpleName().equals("Subscription")) {
String id = extractIdFromSubscription(resource); String id = extractIdFromSubscription(resource);
return SearchParameterMap.newSynchronous().add("_id", new TokenParam(id)); return SearchParameterMap.newSynchronous().add("_id", new TokenParam(id));
} else { } else if (resourceHasUrlElement(resource)) {
String url = extractUniqueUrlFromMetadataResource(resource); String url = extractUniqueUrlFromMetadataResource(resource);
return SearchParameterMap.newSynchronous().add("url", new UriParam(url)); 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(); 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 @VisibleForTesting
void setFhirContextForUnitTest(FhirContext theCtx) { void setFhirContextForUnitTest(FhirContext theCtx) {
myFhirContext = theCtx; myFhirContext = theCtx;

View File

@ -48,6 +48,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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<String> 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 @Test
public void testInstallR4Package_DraftResourcesNotInstalled() throws Exception { public void testInstallR4Package_DraftResourcesNotInstalled() throws Exception {