From c588e01a4d2709274e4ac345edad6af74e8db08d Mon Sep 17 00:00:00 2001 From: James Agnew Date: Wed, 16 May 2018 21:45:23 -0400 Subject: [PATCH] Handle invalid paths in Consent resource --- .../uhn/fhir/cli/ValidationDataUploader.java | 12 +- .../ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java | 4 + .../dao/dstu3/SearchParamExtractorDstu3.java | 6 +- .../fhir/jpa/dao/r4/FhirResourceDaoR4.java | 50 +++-- .../jpa/dao/r4/SearchParamExtractorR4.java | 13 +- .../fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java | 3 + .../dao/dstu3/FhirResourceDaoDstu3Test.java | 192 ++++++++++-------- .../ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java | 3 + .../jpa/dao/r4/FhirResourceDaoR4Test.java | 25 ++- src/changes/changes.xml | 6 + sync_ri4.sh | 1 + 11 files changed, 191 insertions(+), 124 deletions(-) diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationDataUploader.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationDataUploader.java index 23bfca18f7e..6a38ecc918d 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationDataUploader.java +++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationDataUploader.java @@ -506,19 +506,19 @@ public class ValidationDataUploader extends BaseCommand { } } - private void uploadR4Profiles(FhirContext ctx, IGenericClient client, String name) throws CommandFailureException { + private void uploadR4Profiles(FhirContext theContext, IGenericClient theClient, String theName) throws CommandFailureException { int total; int count; org.hl7.fhir.r4.model.Bundle bundle; - ourLog.info("Uploading " + name); + ourLog.info("Uploading " + theName); String vsContents; try { - vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/profile/" + name + ".xml"), "UTF-8"); + vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/" + theName + ".xml"), "UTF-8"); } catch (IOException e) { throw new CommandFailureException(e.toString()); } - bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents); + bundle = theContext.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents); filterBundle(bundle); total = bundle.getEntry().size(); count = 1; @@ -547,9 +547,9 @@ public class ValidationDataUploader extends BaseCommand { continue; } - ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {name, count, total, next.getIdElement().getValue()}); + ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {theName, count, total, next.getIdElement().getValue()}); try { - client.update().resource(next).execute(); + theClient.update().resource(next).execute(); } catch (BaseServerResponseException e) { ourLog.warn("Server responded HTTP " + e.getStatusCode() + ": " + e.toString()); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java index 4e5d499a599..edd7a244779 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java @@ -511,6 +511,7 @@ public abstract class BaseHapiFhirDao implements IDao, @SuppressWarnings("unchecked") protected Set extractResourceLinks(ResourceTable theEntity, IBaseResource theResource, Set theLinks, Date theUpdateTime) { HashSet retVal = new HashSet<>(); + String resourceType = theEntity.getResourceType(); /* * For now we don't try to load any of the links in a bundle if it's the actual bundle we're storing.. @@ -580,6 +581,9 @@ public abstract class BaseHapiFhirDao implements IDao, } } else if (myContext.getElementDefinition((Class) nextObject.getClass()).getName().equals("uri")) { continue; + } else if (resourceType.equals("Consent") && nextPathAndRef.getPath().equals("Consent.source")) { + // Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that + continue; } else { if (!multiType) { if (nextSpDef.getName().equals("sourceuri")) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java index 7513d25ea8f..ca2ff8df921 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java @@ -105,7 +105,8 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen */ @Override public Set extractSearchParamDates(ResourceTable theEntity, IBaseResource theResource) { - HashSet retVal = new HashSet(); + HashSet retVal = new HashSet<>(); + String resourceType = theEntity.getResourceType(); Collection searchParams = getSearchParams(theResource); for (RuntimeSearchParam nextSpDef : searchParams) { @@ -164,6 +165,9 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen } else if (nextObject instanceof StringType) { // CarePlan.activitydate can be a string continue; + } else if (resourceType.equals("Consent") && nextPath.equals("Consent.source")) { + // Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that + continue; } else { if (!multiType) { throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass()); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4.java index a951f3de275..e11ed2e39ff 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4.java @@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao.r4; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,12 +20,28 @@ package ca.uhn.fhir.jpa.dao.r4; * #L% */ -import static org.apache.commons.lang3.StringUtils.isNotBlank; - -import java.util.*; - +import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; +import ca.uhn.fhir.jpa.dao.IFhirResourceDao; +import ca.uhn.fhir.jpa.entity.ResourceTable; +import ca.uhn.fhir.jpa.util.DeleteConflict; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.api.ValidationModeEnum; +import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; +import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; +import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; +import ca.uhn.fhir.validation.FhirValidator; +import ca.uhn.fhir.validation.IValidationContext; +import ca.uhn.fhir.validation.IValidatorModule; +import ca.uhn.fhir.validation.ValidationResult; import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.instance.model.api.*; +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.OperationOutcome; import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity; @@ -33,20 +49,10 @@ import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import ca.uhn.fhir.context.RuntimeResourceDefinition; -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; -import ca.uhn.fhir.jpa.dao.IFhirResourceDao; -import ca.uhn.fhir.jpa.entity.ResourceTable; -import ca.uhn.fhir.jpa.util.DeleteConflict; -import ca.uhn.fhir.model.api.Include; -import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; -import ca.uhn.fhir.rest.api.*; -import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.exceptions.*; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.util.FhirTerser; -import ca.uhn.fhir.validation.*; +import java.util.ArrayList; +import java.util.List; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; public class FhirResourceDaoR4 extends BaseHapiFhirResourceDao { @@ -107,7 +113,7 @@ public class FhirResourceDaoR4 extends BaseHapiFhirResou IFhirResourceDao dao = getDao(type); resourceToValidateById = dao.read(theId, theRequestDetails); } - + ValidationResult result; if (theResource == null) { if (resourceToValidateById != null) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java index b47b6a7c558..8aab08abb97 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java @@ -468,6 +468,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements continue; } + String resourceType = theEntity.getResourceType(); String nextPath = nextSpDef.getPath(); if (isBlank(nextPath)) { continue; @@ -478,8 +479,8 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements multiType = true; } - List systems = new ArrayList(); - List codes = new ArrayList(); + List systems = new ArrayList<>(); + List codes = new ArrayList<>(); for (Object nextObject : extractValues(nextPath, theResource)) { @@ -555,9 +556,15 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements } else if (nextObject instanceof LocationPositionComponent) { ourLog.warn("Position search not currently supported, not indexing location"); continue; + } else if (nextObject instanceof StructureDefinition.StructureDefinitionContextComponent) { + ourLog.warn("StructureDefinition context indexing not currently supported"); // TODO: implement this + continue; + } else if (resourceType.equals("Consent") && nextPath.equals("Consent.source")) { + // Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that + continue; } else { if (!multiType) { - throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass()); + throw new ConfigurationException("Search param " + nextSpDef.getName() + " with path " + nextPath + " is of unexpected datatype: " + nextObject.getClass()); } else { continue; } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java index 056cb36f440..7c04b2d22eb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java @@ -160,6 +160,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest { @Qualifier("myOrganizationDaoDstu3") protected IFhirResourceDao myOrganizationDao; @Autowired + @Qualifier("myConsentDaoDstu3") + protected IFhirResourceDao myConsentDao; + @Autowired protected DatabaseBackedPagingProvider myPagingProvider; @Autowired @Qualifier("myPatientDaoDstu3") diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java index 9ec2f8e5add..f363e68ff75 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java @@ -1,49 +1,53 @@ package ca.uhn.fhir.jpa.dao.dstu3; -import static org.apache.commons.lang3.StringUtils.defaultString; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; - -import java.util.*; - +import ca.uhn.fhir.jpa.dao.*; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString; +import ca.uhn.fhir.jpa.entity.TagTypeEnum; +import ca.uhn.fhir.model.api.Include; +import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; +import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; +import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.*; +import ca.uhn.fhir.rest.server.exceptions.*; +import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; +import ca.uhn.fhir.util.TestUtil; +import com.google.common.collect.Lists; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.hamcrest.Matchers; import org.hamcrest.core.StringContains; import org.hl7.fhir.dstu3.model.*; -import org.hl7.fhir.dstu3.model.Bundle.*; +import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; +import org.hl7.fhir.dstu3.model.Bundle.BundleType; +import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb; import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender; import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus; import org.hl7.fhir.dstu3.model.Observation.ObservationStatus; import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity; import org.hl7.fhir.dstu3.model.OperationOutcome.IssueType; import org.hl7.fhir.dstu3.model.Quantity.QuantityComparator; -import org.hl7.fhir.instance.model.api.*; +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import org.junit.*; import org.mockito.ArgumentCaptor; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import com.google.common.collect.Lists; +import java.util.*; -import ca.uhn.fhir.jpa.dao.*; -import ca.uhn.fhir.jpa.entity.*; -import ca.uhn.fhir.model.api.Include; -import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; -import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; -import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum; -import ca.uhn.fhir.rest.api.*; -import ca.uhn.fhir.rest.api.Constants; -import ca.uhn.fhir.rest.api.server.IBundleProvider; -import ca.uhn.fhir.rest.param.*; -import ca.uhn.fhir.rest.server.exceptions.*; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.util.TestUtil; +import static org.apache.commons.lang3.StringUtils.defaultString; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; -@SuppressWarnings({ "unchecked", "deprecation" }) +@SuppressWarnings({"unchecked", "deprecation"}) public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3Test.class); @@ -78,7 +82,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } } - + @Before public void beforeDisableResultReuse() { myDaoConfig.setReuseCachedSearchResultsForMillis(null); @@ -117,7 +121,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } } - private void sortCodings(List theSecLabels) { Collections.sort(theSecLabels, new Comparator() { @Override @@ -126,7 +129,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } }); } - + private List sortIds(List theProfiles) { ArrayList retVal = new ArrayList(theProfiles); Collections.sort(retVal, new Comparator() { @@ -137,7 +140,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { }); return retVal; } - + @Test public void testCantSearchForDeletedResourceByLanguageOrTag() { String methodName = "testCantSearchForDeletedResourceByLanguageOrTag"; @@ -478,8 +481,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { myBundleDao.create(bundle, mySrd); } - - + @Test public void testCreateDifferentTypesWithSameForcedId() { String idName = "forcedId"; @@ -500,12 +502,11 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { obs = myObservationDao.read(obsId.toUnqualifiedVersionless(), mySrd); } - @Test public void testCreateDuplicateTagsDoesNotCauseDuplicates() { Patient p = new Patient(); p.setActive(true); - + p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR"); @@ -513,9 +514,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR"); - + myPatientDao.create(p); - + new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus theStatus) { @@ -523,24 +524,24 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { assertThat(myTagDefinitionDao.findAll(), hasSize(1)); } }); - + } @Test public void testCreateEmptyTagsIsIgnored() { Patient p = new Patient(); p.setActive(true); - + // Add an empty tag p.getMeta().addTag(); - + // Add another empty tag p.getMeta().addTag().setSystem(""); p.getMeta().addTag().setCode(""); p.getMeta().addTag().setDisplay(""); - + myPatientDao.create(p); - + new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus theStatus) { @@ -548,29 +549,29 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { assertThat(myTagDefinitionDao.findAll(), empty()); } }); - + } @Test public void testCreateLongString() { //@formatter:off - String input = "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " "; + String input = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " "; //@formatter:on NamingSystem res = myFhirCtx.newXmlParser().parseResource(NamingSystem.class, input); @@ -633,9 +634,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { Organization org = new Organization(); org.setActive(true); IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); - + myOrganizationDao.delete(orgId); - + Patient p = new Patient(); p.getManagingOrganization().setReferenceElement(orgId); try { @@ -809,7 +810,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } } - @Test public void testCreateWithInvalidReferenceFailsGracefully() { Patient patient = new Patient(); @@ -1088,7 +1088,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { patient.addIdentifier().setSystem("ZZZZZZZ").setValue("ZZZZZZZZZ"); id2b = myPatientDao.update(patient, mySrd).getId(); } - ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] { id1, id2, id2b }); + ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] {id1, id2, id2b}); SearchParameterMap params = new SearchParameterMap(); params.setLoadSynchronous(true); @@ -1697,7 +1697,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { preDates.add(new Date()); Thread.sleep(100); patient.setId(id); - patient.getName().get(0).getFamilyElement().setValue(methodName + "_i"+i); + patient.getName().get(0).getFamilyElement().setValue(methodName + "_i" + i); ids.add(myPatientDao.update(patient, mySrd).getId().toUnqualified().getValue()); } @@ -2056,27 +2056,27 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { public void testOrganizationName() { //@formatter:off - String inputStr = - "{" + - " \"resourceType\":\"Organization\",\n" + - " \"extension\":[\n" + - " {\n" + - " \"url\":\"http://fhir.connectinggta.ca/Profile/organization#providerIdPool\",\n" + - " \"valueUri\":\"urn:oid:2.16.840.1.113883.3.239.23.21.1\"\n" + - " }\n" + - " ],\n" + - " \"text\":{\n" + - " \"status\":\"empty\",\n" + - " \"div\":\"
No narrative template available for resource profile: http://fhir.connectinggta.ca/Profile/organization
\"\n" + - " },\n" + - " \"identifier\":[\n" + - " {\n" + - " \"use\":\"official\",\n" + - " \"system\":\"urn:cgta:hsp_ids\",\n" + - " \"value\":\"urn:oid:2.16.840.1.113883.3.239.23.21\"\n" + - " }\n" + - " ],\n" + - " \"name\":\"Peterborough Regional Health Centre\"\n" + + String inputStr = + "{" + + " \"resourceType\":\"Organization\",\n" + + " \"extension\":[\n" + + " {\n" + + " \"url\":\"http://fhir.connectinggta.ca/Profile/organization#providerIdPool\",\n" + + " \"valueUri\":\"urn:oid:2.16.840.1.113883.3.239.23.21.1\"\n" + + " }\n" + + " ],\n" + + " \"text\":{\n" + + " \"status\":\"empty\",\n" + + " \"div\":\"
No narrative template available for resource profile: http://fhir.connectinggta.ca/Profile/organization
\"\n" + + " },\n" + + " \"identifier\":[\n" + + " {\n" + + " \"use\":\"official\",\n" + + " \"system\":\"urn:cgta:hsp_ids\",\n" + + " \"value\":\"urn:oid:2.16.840.1.113883.3.239.23.21\"\n" + + " }\n" + + " ],\n" + + " \"name\":\"Peterborough Regional Health Centre\"\n" + "}\n"; //@formatter:on @@ -2131,7 +2131,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { dr01.setSubject(new Reference(patientId01)); IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId(); - ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 }); + ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] {patientId01, patientId02, obsId01, obsId02, drId01}); List result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getIdPart())).setLoadSynchronous(true))); assertEquals(1, result.size()); @@ -2141,7 +2141,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { assertEquals(1, result.size()); assertEquals(obsId02.getIdPart(), result.get(0).getIdElement().getIdPart()); - result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true)));; + result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true))); + ; assertEquals(0, result.size()); } @@ -2224,7 +2225,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { long id = outcome.getId().getIdPartAsLong(); TokenParam value = new TokenParam("urn:system", "001testPersistSearchParams"); - List found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true)));; + List found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true))); + ; assertEquals(1, found.size()); assertEquals(id, found.get(0).getIdElement().getIdPartAsLong().longValue()); @@ -2797,7 +2799,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { pm.setSort(new SortSpec(Patient.SP_BIRTHDATE).setOrder(SortOrderEnum.DESC)); actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm)); assertEquals(4, actual.size()); - // The first would be better, but JPA doesn't do NULLS LAST + // The first would be better, but JPA doesn't do NULLS LAST // assertThat(actual, contains(id3, id2, id1, id4)); assertThat(actual, contains(id4, id3, id2, id1)); @@ -3081,7 +3083,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { pm.setSort(new SortSpec(Patient.SP_FAMILY).setOrder(SortOrderEnum.DESC)); actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm)); assertEquals(4, actual.size()); - // The first would be better, but JPA doesn't do NULLS LAST + // The first would be better, but JPA doesn't do NULLS LAST // assertThat(actual, contains(id3, id2, id1, id4)); assertThat(actual, contains(id4, id3, id2, id1)); } @@ -3535,6 +3537,16 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } + /** + * Make sure this can upload successfully (indexer failed at one point) + */ + @Test + public void testUploadConsentWithSourceAttachment() { + Consent consent = new Consent(); + consent.setSource(new Attachment().setUrl("http://foo")); + myConsentDao.create(consent); + } + @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); @@ -3542,7 +3554,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { public static void assertConflictException(ResourceVersionConflictException e) { assertThat(e.getMessage(), matchesPattern( - "Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+")); + "Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+")); } private static List toStringList(List theUriType) { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java index a5e11d536c2..bcea6129cd7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java @@ -212,6 +212,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest { @Qualifier("myStructureDefinitionDaoR4") protected IFhirResourceDao myStructureDefinitionDao; @Autowired + @Qualifier("myConsentDaoR4") + protected IFhirResourceDao myConsentDao; + @Autowired @Qualifier("mySubscriptionDaoR4") protected IFhirResourceDaoSubscription mySubscriptionDao; @Autowired diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java index b6441b3daca..7299e08fdda 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java @@ -21,6 +21,7 @@ import com.google.common.collect.Lists; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; import org.hamcrest.Matchers; import org.hamcrest.core.StringContains; import org.hl7.fhir.instance.model.api.IAnyResource; @@ -2966,7 +2967,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test { pm.setSort(new SortSpec(Patient.SP_BIRTHDATE).setOrder(SortOrderEnum.DESC)); actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm)); assertEquals(4, actual.size()); - // The first would be better, but JPA doesn't do NULLS LAST + // The first would be better, but JPA doesn't do NULLS LAST // assertThat(actual, contains(id3, id2, id1, id4)); assertThat(actual, contains(id4, id3, id2, id1)); @@ -3284,7 +3285,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test { pm.setSort(new SortSpec(Patient.SP_FAMILY).setOrder(SortOrderEnum.DESC)); actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm)); assertEquals(4, actual.size()); - // The first would be better, but JPA doesn't do NULLS LAST + // The first would be better, but JPA doesn't do NULLS LAST // assertThat(actual, contains(id3, id2, id1, id4)); assertThat(actual, contains(id4, id3, id2, id1)); } @@ -3738,6 +3739,26 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test { } + /** + * Make sure this can upload successfully (indexer failed at one point) + */ + @Test + public void testUploadConsentWithSourceAttachment() { + Consent consent = new Consent(); + consent.setSource(new Attachment().setUrl("http://foo")); + myConsentDao.create(consent); + } + + /** + * Make sure this can upload successfully (indexer failed at one point) + */ + @Test + public void testUploadExtensionStructureDefinition() { + StructureDefinition ext = myValidationSupport.fetchStructureDefinition(myFhirCtx, "http://hl7.org/fhir/StructureDefinition/familymemberhistory-type"); + Validate.notNull(ext); + myStructureDefinitionDao.update(ext); + } + @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/src/changes/changes.xml b/src/changes/changes.xml index c707601ebd5..1a1dfa68b0b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -178,6 +178,12 @@ pull request! These have also been added to the list of definitions uploaded by the CLI "upload-definitions" command. + + A workaround for an invalid search parameter path in the R4 consent + resource has been implemented. This path was preventing some Consent + resources from successfully being uploaded to the JPA server. Thanks to + Anthony Sute for identifying this. + diff --git a/sync_ri4.sh b/sync_ri4.sh index a2540d134f1..2a59e205949 100755 --- a/sync_ri4.sh +++ b/sync_ri4.sh @@ -60,3 +60,4 @@ cp ~/workspace/fhir/trunk/build/publish/profiles-*.xml hapi-fhir-validatio cp ~/workspace/fhir/trunk/build/publish/v2-tables.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/ cp ~/workspace/fhir/trunk/build/publish/v3-codesystems.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/ cp ~/workspace/fhir/trunk/build/publish/valuesets.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/ +cp ~/workspace/fhir/trunk/build/publish/extension-definitions.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/extension/