Bundles for history did not validate

This commit is contained in:
James Agnew 2016-09-18 10:28:24 -04:00
parent e686ff7aa7
commit b20a5e6b90
3 changed files with 32 additions and 25 deletions

View File

@ -66,6 +66,7 @@ import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler; import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SummaryEnum; import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
@ -1720,10 +1721,18 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
assertEquals(id.withVersion("2").getValue(), history.getEntry().get(1).getResource().getId()); assertEquals(id.withVersion("2").getValue(), history.getEntry().get(1).getResource().getId());
assertEquals(HTTPVerb.DELETE, history.getEntry().get(1).getRequest().getMethodElement().getValue()); assertEquals(HTTPVerb.DELETE, history.getEntry().get(1).getRequest().getMethodElement().getValue());
assertEquals("http://localhost:" + ourPort + "/fhir/context/Patient/" + id.getIdPart() + "/_history/2", history.getEntry().get(1).getRequest().getUrl());
assertEquals(0, ((Patient) history.getEntry().get(1).getResource()).getName().size()); assertEquals(0, ((Patient) history.getEntry().get(1).getResource()).getName().size());
assertEquals(id.withVersion("1").getValue(), history.getEntry().get(2).getResource().getId()); assertEquals(id.withVersion("1").getValue(), history.getEntry().get(2).getResource().getId());
assertEquals(1, ((Patient) history.getEntry().get(2).getResource()).getName().size()); assertEquals(1, ((Patient) history.getEntry().get(2).getResource()).getName().size());
try {
myBundleDao.validate(history, null, null, null, null, null, mySrd);
} catch (PreconditionFailedException e) {
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
throw e;
}
} }
/** /**

View File

@ -21,13 +21,7 @@ package org.hl7.fhir.dstu3.hapi.rest.server;
*/ */
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle;
@ -35,25 +29,17 @@ import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleLinkComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleLinkComponent;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb; import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.Bundle.SearchEntryMode; import org.hl7.fhir.dstu3.model.Bundle.SearchEntryMode;
import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.dstu3.model.DomainResource; import org.hl7.fhir.dstu3.model.DomainResource;
import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Resource; import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.server.BundleInclusionRule; import ca.uhn.fhir.rest.server.*;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.IRestfulServer;
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.ResourceReferenceInfo; import ca.uhn.fhir.util.ResourceReferenceInfo;
@ -135,6 +121,7 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(next); String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(next);
if (httpVerb != null) { if (httpVerb != null) {
entry.getRequest().getMethodElement().setValueAsString(httpVerb); entry.getRequest().getMethodElement().setValueAsString(httpVerb);
entry.getRequest().getUrlElement().setValue(next.getId());
} }
} }
@ -161,7 +148,7 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
for (IBaseResource next : theResult) { for (IBaseResource next : theResult) {
if (next.getIdElement().isEmpty() == false) { if (next.getIdElement().isEmpty() == false) {
addedResourceIds.add((IdType) next.getIdElement()); addedResourceIds.add(next.getIdElement());
} }
} }
@ -221,11 +208,14 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
BundleEntryComponent entry = myBundle.addEntry().setResource((Resource) next); BundleEntryComponent entry = myBundle.addEntry().setResource((Resource) next);
Resource nextAsResource = (Resource)next; Resource nextAsResource = (Resource)next;
IIdType id = populateBundleEntryFullUrl(next, entry);
String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(nextAsResource); String httpVerb = ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(nextAsResource);
if (httpVerb != null) { if (httpVerb != null) {
entry.getRequest().getMethodElement().setValueAsString(httpVerb); entry.getRequest().getMethodElement().setValueAsString(httpVerb);
if (id != null) {
entry.getRequest().setUrl(id.getValue());
}
} }
populateBundleEntryFullUrl(next, entry);
String searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(nextAsResource); String searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(nextAsResource);
if (searchMode != null) { if (searchMode != null) {
@ -244,16 +234,19 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
} }
private void populateBundleEntryFullUrl(IBaseResource next, BundleEntryComponent entry) { private IIdType populateBundleEntryFullUrl(IBaseResource next, BundleEntryComponent entry) {
IIdType idElement = null;
if (next.getIdElement().hasBaseUrl()) { if (next.getIdElement().hasBaseUrl()) {
entry.setFullUrl(next.getIdElement().toVersionless().getValue()); idElement = next.getIdElement();
entry.setFullUrl(idElement.toVersionless().getValue());
} else { } else {
if (isNotBlank(myBase) && next.getIdElement().hasIdPart()) { if (isNotBlank(myBase) && next.getIdElement().hasIdPart()) {
IIdType id = next.getIdElement().toVersionless(); idElement = next.getIdElement();
id = id.withServerBase(myBase, myContext.getResourceDefinition(next).getName()); idElement = idElement.withServerBase(myBase, myContext.getResourceDefinition(next).getName());
entry.setFullUrl(id.getValue()); entry.setFullUrl(idElement.toVersionless().getValue());
} }
} }
return idElement;
} }
@Override @Override
@ -392,7 +385,7 @@ public class Dstu3BundleFactory implements IVersionSpecificBundleFactory {
Resource next = (Resource) nextBaseRes; Resource next = (Resource) nextBaseRes;
BundleEntryComponent nextEntry = myBundle.addEntry(); BundleEntryComponent nextEntry = myBundle.addEntry();
nextEntry.setResource((Resource) next); nextEntry.setResource(next);
if (next.getIdElement().isEmpty()) { if (next.getIdElement().isEmpty()) {
nextEntry.getRequest().setMethod(HTTPVerb.POST); nextEntry.getRequest().setMethod(HTTPVerb.POST);
} else { } else {

View File

@ -81,6 +81,11 @@
DELETE fails because of constraint issues, instead of DELETE fails because of constraint issues, instead of
<![CDATA[<code>HTTP 400 Invalid Request</code>]]> <![CDATA[<code>HTTP 400 Invalid Request</code>]]>
</action> </action>
<action type="fix">
Server history operation did not populate the Bundle.entry.request.url
field, which is required in order for the bundle to pass validation.
Thanks to Richard Kavanaugh for spotting this!
</action>
</release> </release>
<release version="2.0" date="2016-08-30"> <release version="2.0" date="2016-08-30">
<action type="fix"> <action type="fix">