diff --git a/examples/src/main/java/example/customtype/CustomCompositeExtension.java b/examples/src/main/java/example/customtype/CustomCompositeExtension.java new file mode 100644 index 00000000000..49a1ce5f5ce --- /dev/null +++ b/examples/src/main/java/example/customtype/CustomCompositeExtension.java @@ -0,0 +1,84 @@ +package example.customtype; + +import org.hl7.fhir.dstu3.model.BackboneElement; +import org.hl7.fhir.dstu3.model.Patient; +import org.hl7.fhir.dstu3.model.StringType; + +import ca.uhn.fhir.model.api.annotation.Block; +import ca.uhn.fhir.model.api.annotation.Child; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.api.annotation.ResourceDef; +import ca.uhn.fhir.util.ElementUtil; + +//START SNIPPET: resource +@ResourceDef(name = "Patient") +public class CustomCompositeExtension extends Patient { + + private static final long serialVersionUID = 1L; + + /** + * A custom extension + */ + @Child(name = "foo") + @Extension(url="http://acme.org/fooParent", definedLocally = false, isModifier = false) + protected FooParentExtension fooParentExtension; + + public FooParentExtension getFooParentExtension() { + return fooParentExtension; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(fooParentExtension); + } + + public void setFooParentExtension(FooParentExtension theFooParentExtension) { + fooParentExtension = theFooParentExtension; + } + + @Block + public static class FooParentExtension extends BackboneElement { + + private static final long serialVersionUID = 4522090347756045145L; + + @Child(name = "childA") + @Extension(url = "http://acme.org/fooChildA", definedLocally = false, isModifier = false) + private StringType myChildA; + + @Child(name = "childB") + @Extension(url = "http://acme.org/fooChildB", definedLocally = false, isModifier = false) + private StringType myChildB; + + @Override + public FooParentExtension copy() { + FooParentExtension copy = new FooParentExtension(); + copy.myChildA = myChildA; + copy.myChildB = myChildB; + return copy; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(myChildA, myChildB); + } + + public StringType getChildA() { + return myChildA; + } + + public StringType getChildB() { + return myChildB; + } + + public void setChildA(StringType theChildA) { + myChildA = theChildA; + } + + public void setChildB(StringType theChildB) { + myChildB = theChildB; + } + + } + +} +//END SNIPPET: resource diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirVersionEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirVersionEnum.java index 94496f2bfd6..00deaf72057 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirVersionEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirVersionEnum.java @@ -88,6 +88,10 @@ public enum FhirVersionEnum { return ordinal() > theVersion.ordinal(); } + public boolean isOlderThan(FhirVersionEnum theVersion) { + return ordinal() < theVersion.ordinal(); + } + /** * Returns true if the given version is present on the classpath */ diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/i18n/HapiLocalizer.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/i18n/HapiLocalizer.java index 4d4024310f9..9c3143fe04d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/i18n/HapiLocalizer.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/i18n/HapiLocalizer.java @@ -1,5 +1,7 @@ package ca.uhn.fhir.i18n; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + /* * #%L * HAPI FHIR - Core Library @@ -10,7 +12,7 @@ package ca.uhn.fhir.i18n; * 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 + * 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, @@ -21,6 +23,8 @@ package ca.uhn.fhir.i18n; */ import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.concurrent.ConcurrentHashMap; @@ -30,40 +34,56 @@ import java.util.concurrent.ConcurrentHashMap; */ public class HapiLocalizer { - private ResourceBundle myBundle; + private List myBundle = new ArrayList(); private final Map myKeyToMessageFormat = new ConcurrentHashMap(); public HapiLocalizer() { - myBundle = ResourceBundle.getBundle(HapiLocalizer.class.getPackage().getName() + ".hapi-messages"); + this(HapiLocalizer.class.getPackage().getName() + ".hapi-messages"); + } + + public HapiLocalizer(String... theBundleNames) { + for (String nextName : theBundleNames) { + myBundle.add(ResourceBundle.getBundle(nextName)); + } } public String getMessage(Class theType, String theKey, Object... theParameters) { return getMessage(theType.getName() + '.' + theKey, theParameters); } - + public String getMessage(String theQualifiedKey, Object... theParameters) { if (theParameters != null && theParameters.length > 0) { MessageFormat format = myKeyToMessageFormat.get(theQualifiedKey); if (format != null) { return format.format(theParameters).toString(); } - - String formatString = myBundle.getString(theQualifiedKey); - if (formatString== null) { - formatString = "!MESSAGE!"; - } - + + String formatString = findFormatString(theQualifiedKey); + format = new MessageFormat(formatString.trim()); myKeyToMessageFormat.put(theQualifiedKey, format); return format.format(theParameters).toString(); } else { - String retVal = myBundle.getString(theQualifiedKey); - if (retVal == null) { - retVal = "!MESSAGE!"; - } + String retVal = findFormatString(theQualifiedKey); return retVal; } } - - + + private String findFormatString(String theQualifiedKey) { + String formatString = null; + for (ResourceBundle nextBundle : myBundle) { + if (nextBundle.containsKey(theQualifiedKey)) { + formatString = nextBundle.getString(theQualifiedKey); + } + if (isNotBlank(formatString)) { + break; + } + } + + if (formatString == null) { + formatString = "!MESSAGE!"; + } + return formatString; + } + } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java index 0df72d48812..17c00535a52 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.parser; * 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 + * 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, @@ -285,13 +285,17 @@ public abstract class BaseParser implements IParser { IIdType refId = theRef.getResource().getIdElement(); if (refId != null) { if (refId.hasIdPart()) { - if (!refId.hasResourceType()) { - refId = refId.withResourceType(myContext.getResourceDefinition(theRef.getResource()).getName()); - } - if (isStripVersionsFromReferences(theCompositeChildElement)) { - reference = refId.toVersionless().getValue(); - } else { + if (refId.getValue().startsWith("urn:")) { reference = refId.getValue(); + } else { + if (!refId.hasResourceType()) { + refId = refId.withResourceType(myContext.getResourceDefinition(theRef.getResource()).getName()); + } + if (isStripVersionsFromReferences(theCompositeChildElement)) { + reference = refId.toVersionless().getValue(); + } else { + reference = refId.getValue(); + } } } } @@ -388,7 +392,8 @@ public abstract class BaseParser implements IParser { Validate.notNull(theWriter, "theWriter can not be null"); if (theResource.getStructureFhirVersionEnum() != myContext.getVersion().getVersion()) { - throw new IllegalArgumentException("This parser is for FHIR version " + myContext.getVersion().getVersion() + " - Can not encode a structure for version " + theResource.getStructureFhirVersionEnum()); + throw new IllegalArgumentException( + "This parser is for FHIR version " + myContext.getVersion().getVersion() + " - Can not encode a structure for version " + theResource.getStructureFhirVersionEnum()); } doEncodeResourceToWriter(theResource, theWriter); @@ -430,9 +435,9 @@ public abstract class BaseParser implements IParser { String childName = theChild.getChildNameByDatatype(type); BaseRuntimeElementDefinition childDef = theChild.getChildElementDefinitionByDatatype(type); if (childDef == null) { - // if (theValue instanceof IBaseExtension) { - // return null; - // } + // if (theValue instanceof IBaseExtension) { + // return null; + // } /* * For RI structures Enumeration class, this replaces the child def @@ -578,7 +583,8 @@ public abstract class BaseParser implements IParser { } protected boolean isChildContained(BaseRuntimeElementDefinition childDef, boolean theIncludedResource) { - return (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES || childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) && getContainedResources().isEmpty() == false && theIncludedResource == false; + return (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES || childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) && getContainedResources().isEmpty() == false + && theIncludedResource == false; } @Override @@ -623,7 +629,7 @@ public abstract class BaseParser implements IParser { @Override public T parseResource(Class theResourceType, Reader theReader) throws DataFormatException { - /* + /* * We do this so that the context can verify that the structure is for * the correct FHIR version */ @@ -698,7 +704,8 @@ public abstract class BaseParser implements IParser { return parseTagList(new StringReader(theString)); } - protected List preProcessValues(BaseRuntimeChildDefinition theMetaChildUncast, IBaseResource theResource, List theValues, CompositeChildElement theCompositeChildElement) { + protected List preProcessValues(BaseRuntimeChildDefinition theMetaChildUncast, IBaseResource theResource, List theValues, + CompositeChildElement theCompositeChildElement) { if (myContext.getVersion().getVersion().isRi()) { /* @@ -1156,11 +1163,11 @@ public abstract class BaseParser implements IParser { retVal = !checkIfParentShouldNotBeEncodedAndBuildPath(new StringBuilder(), true); } } - // if (retVal == false && myEncodeElements.contains("*.(mandatory)")) { - // if (myDef.getMin() > 0) { - // retVal = true; - // } - // } + // if (retVal == false && myEncodeElements.contains("*.(mandatory)")) { + // if (myDef.getMin() > 0) { + // retVal = true; + // } + // } return retVal; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBindingWithResourceParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBindingWithResourceParam.java index 5b2fdcf569c..7bab0439cd3 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBindingWithResourceParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBindingWithResourceParam.java @@ -104,6 +104,10 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu if (getContext().getVersion().getVersion() == FhirVersionEnum.DSTU1) { resource.setId(urlId); } else { + if (getContext().getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3) == false) { + resource.setId(theRequest.getId()); + } + String matchUrl = null; if (myConditionalUrlIndex != -1) { matchUrl = (String) theParams[myConditionalUrlIndex]; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConditionalParamBinder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConditionalParamBinder.java index 073bd67a09c..69266d0efb2 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConditionalParamBinder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConditionalParamBinder.java @@ -67,29 +67,7 @@ class ConditionalParamBinder implements IParameter { @Override public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - - if (myOperationType == RestOperationTypeEnum.CREATE) { - String retVal = theRequest.getHeader(Constants.HEADER_IF_NONE_EXIST); - if (isBlank(retVal)) { - return null; - } - if (retVal.startsWith(theRequest.getFhirServerBase())) { - retVal = retVal.substring(theRequest.getFhirServerBase().length()); - } - return retVal; - } else if (myOperationType != RestOperationTypeEnum.DELETE && myOperationType != RestOperationTypeEnum.UPDATE) { - return null; - } - - if (theRequest.getId() != null && theRequest.getId().hasIdPart()) { - return null; - } - - int questionMarkIndex = theRequest.getCompleteUrl().indexOf('?'); - if (questionMarkIndex == -1) { - return null; - } - return theRequest.getResourceName() + theRequest.getCompleteUrl().substring(questionMarkIndex); + return theRequest.getConditionalUrl(myOperationType); } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/CreateMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/CreateMethodBinding.java index de189c87b08..1eb140ad27b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/CreateMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/CreateMethodBinding.java @@ -27,8 +27,10 @@ import java.util.Collections; import java.util.Set; import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.rest.annotation.Create; import ca.uhn.fhir.rest.api.RequestTypeEnum; @@ -79,9 +81,13 @@ public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInUrlForCreate", theUrlId); throw new InvalidRequestException(msg); } - if (isNotBlank(theResourceId)) { - String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInBodyForCreate", theResourceId); - throw new InvalidRequestException(msg); + if (getContext().getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { + if (isNotBlank(theResourceId)) { + String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInBodyForCreate", theResourceId); + throw new InvalidRequestException(msg); + } + } else { + theResource.setId((IIdType)null); } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java index 0087d56c442..08180502c07 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java @@ -1,5 +1,7 @@ package ca.uhn.fhir.rest.method; +import static org.apache.commons.lang3.StringUtils.isBlank; + import java.io.IOException; import java.io.InputStream; import java.io.Reader; @@ -38,6 +40,7 @@ import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.IRestfulResponse; import ca.uhn.fhir.rest.server.IRestfulServerDefaults; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; @@ -52,6 +55,7 @@ public abstract class RequestDetails { private String myOperation; private Map myParameters; private byte[] myRequestContents; + private IRequestOperationCallback myRequestOperationCallback = new RequestOperationCallback(); private String myRequestPath; private RequestTypeEnum myRequestType; private String myResourceName; @@ -59,7 +63,6 @@ public abstract class RequestDetails { private IRestfulResponse myResponse; private RestOperationTypeEnum myRestOperationType; private String mySecondaryOperation; - private IRequestOperationCallback myRequestOperationCallback = new RequestOperationCallback(); private Map> myUnqualifiedToQualifiedNames; private Map myUserData; protected abstract byte[] getByteStreamRequestContents(); @@ -76,6 +79,40 @@ public abstract class RequestDetails { return myCompleteUrl; } + /** + * Returns the conditional URL if this request has one, or null otherwise. For an + * update or delete method, this is the part of the URL after the ?. For a create, this + * is the value of the If-None-Exist header. + * + * @param theOperationType The operation type to find the conditional URL for + * @return Returns the conditional URL if this request has one, or null otherwise + */ + public String getConditionalUrl(RestOperationTypeEnum theOperationType) { + if (theOperationType == RestOperationTypeEnum.CREATE) { + String retVal = this.getHeader(Constants.HEADER_IF_NONE_EXIST); + if (isBlank(retVal)) { + return null; + } + if (retVal.startsWith(this.getFhirServerBase())) { + retVal = retVal.substring(this.getFhirServerBase().length()); + } + return retVal; + } else if (theOperationType != RestOperationTypeEnum.DELETE && theOperationType != RestOperationTypeEnum.UPDATE) { + return null; + } + + if (this.getId() != null && this.getId().hasIdPart()) { + return null; + } + + int questionMarkIndex = this.getCompleteUrl().indexOf('?'); + if (questionMarkIndex == -1) { + return null; + } + + return this.getResourceName() + this.getCompleteUrl().substring(questionMarkIndex); + } + /** * The fhir server base url, independant of the query being executed * @@ -138,6 +175,15 @@ public abstract class RequestDetails { */ public abstract Reader getReader() throws IOException; + /** + * Returns an invoker that can be called from user code to advise the server interceptors + * of any nested operations being invoked within operations. This invoker acts as a proxy for + * all interceptors + */ + public IRequestOperationCallback getRequestOperationCallback() { + return myRequestOperationCallback; + } + /** * The part of the request URL that comes after the server base. *

@@ -175,15 +221,6 @@ public abstract class RequestDetails { */ public abstract String getServerBaseForRequest(); - /** - * Returns an invoker that can be called from user code to advise the server interceptors - * of any nested operations being invoked within operations. This invoker acts as a proxy for - * all interceptors - */ - public IRequestOperationCallback getRequestOperationCallback() { - return myRequestOperationCallback; - } - public Map> getUnqualifiedToQualifiedNames() { return myUnqualifiedToQualifiedNames; } @@ -290,13 +327,20 @@ public abstract class RequestDetails { public void setRestOperationType(RestOperationTypeEnum theRestOperationType) { myRestOperationType = theRestOperationType; } - + public void setSecondaryOperation(String theSecondaryOperation) { mySecondaryOperation = theSecondaryOperation; } - + private class RequestOperationCallback implements IRequestOperationCallback { + private List getInterceptors() { + if (getServer() == null) { + return Collections.emptyList(); + } + return getServer().getInterceptors(); + } + @Override public void resourceCreated(IBaseResource theResource) { for (IServerInterceptor next : getInterceptors()) { @@ -306,13 +350,6 @@ public abstract class RequestDetails { } } - private List getInterceptors() { - if (getServer() == null) { - return Collections.emptyList(); - } - return getServer().getInterceptors(); - } - @Override public void resourceDeleted(IBaseResource theResource) { for (IServerInterceptor next : getInterceptors()) { @@ -322,15 +359,6 @@ public abstract class RequestDetails { } } - @Override - public void resourceUpdated(IBaseResource theResource) { - for (IServerInterceptor next : getInterceptors()) { - if (next instanceof IServerOperationInterceptor) { - ((IServerOperationInterceptor) next).resourceUpdated(RequestDetails.this, theResource); - } - } - } - @Override public void resourcesCreated(Collection theResource) { for (IBaseResource next : theResource) { @@ -352,6 +380,15 @@ public abstract class RequestDetails { } } + @Override + public void resourceUpdated(IBaseResource theResource) { + for (IServerInterceptor next : getInterceptors()) { + if (next instanceof IServerOperationInterceptor) { + ((IServerOperationInterceptor) next).resourceUpdated(RequestDetails.this, theResource); + } + } + } + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/UpdateMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/UpdateMethodBinding.java index acef735e3e6..d30f57b4554 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/UpdateMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/UpdateMethodBinding.java @@ -11,7 +11,7 @@ import static org.apache.commons.lang3.StringUtils.isBlank; * 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 + * 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, @@ -30,6 +30,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.annotation.Update; @@ -62,7 +63,8 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe id.setValue(locationHeader); if (isNotBlank(id.getResourceType())) { if (!getResourceName().equals(id.getResourceType())) { - throw new InvalidRequestException("Attempting to update '" + getResourceName() + "' but content-location header specifies different resource type '" + id.getResourceType() + "' - header value: " + locationHeader); + throw new InvalidRequestException( + "Attempting to update '" + getResourceName() + "' but content-location header specifies different resource type '" + id.getResourceType() + "' - header value: " + locationHeader); } } } @@ -140,17 +142,20 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "noIdInUrlForUpdate"); throw new InvalidRequestException(msg); } - if (isBlank(theResourceId)) { -// String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "noIdInBodyForUpdate"); - ourLog.warn("No resource ID found in resource body for update"); - theResource.setId(theUrlId); - } else { - if (!theResourceId.equals(theUrlId)) { - String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "incorrectIdForUpdate", theResourceId, theUrlId); - throw new InvalidRequestException(msg); + if (getContext().getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { + if (isBlank(theResourceId)) { + ourLog.warn("No resource ID found in resource body for update"); + theResource.setId(theUrlId); + } else { + if (!theResourceId.equals(theUrlId)) { + String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "incorrectIdForUpdate", theResourceId, theUrlId); + throw new InvalidRequestException(msg); + } } } + } else { + theResource.setId((IIdType)null); } + } - } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java index 89ab445fd65..37cc777853a 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptor.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.Bundle; @@ -78,8 +79,8 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer setDefaultPolicy(theDefaultPolicy); } - private void applyRulesAndFailIfDeny(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IBaseResource theOutputResource) { - Verdict decision = applyRulesAndReturnDecision(theOperation, theRequestDetails, theInputResource, theOutputResource); + private void applyRulesAndFailIfDeny(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource) { + Verdict decision = applyRulesAndReturnDecision(theOperation, theRequestDetails, theInputResource, theInputResourceId, theOutputResource); if (decision.getDecision() == PolicyEnum.ALLOW) { return; @@ -89,13 +90,13 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer } @Override - public Verdict applyRulesAndReturnDecision(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IBaseResource theOutputResource) { + public Verdict applyRulesAndReturnDecision(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource) { List rules = buildRuleList(theRequestDetails); ourLog.trace("Applying {} rules to render an auth decision for operation {}", rules.size(), theOperation); Verdict verdict = null; for (IAuthRule nextRule : rules) { - verdict = nextRule.applyRule(theOperation, theRequestDetails, theInputResource, theOutputResource, this); + verdict = nextRule.applyRule(theOperation, theRequestDetails, theInputResource, theInputResourceId, theOutputResource, this); if (verdict != null) { ourLog.trace("Rule {} returned decision {}", nextRule, verdict.getDecision()); break; @@ -126,7 +127,7 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer } - private OperationExamineDirection determineOperationDirection(RestOperationTypeEnum theOperation) { + private OperationExamineDirection determineOperationDirection(RestOperationTypeEnum theOperation, IBaseResource theRequestResource) { switch (theOperation) { case ADD_TAGS: case DELETE_TAGS: @@ -147,6 +148,13 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer case CREATE: case UPDATE: +// if (theRequestResource != null) { +// if (theRequestResource.getIdElement() != null) { +// if (theRequestResource.getIdElement().hasIdPart() == false) { +// return OperationExamineDirection.IN_UNCATEGORIZED; +// } +// } +// } return OperationExamineDirection.IN; case META: @@ -204,14 +212,26 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer } private void handleUserOperation(RequestDetails theRequest, IBaseResource theResource, RestOperationTypeEnum operation) { - applyRulesAndFailIfDeny(operation, theRequest, theResource, null); + applyRulesAndFailIfDeny(operation, theRequest, theResource, theResource.getIdElement(), null); } @Override public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theProcessedRequest) { - switch (determineOperationDirection(theOperation)) { + IBaseResource inputResource = null; + IIdType inputResourceId = null; + + switch (determineOperationDirection(theOperation, theProcessedRequest.getResource())) { + case IN_UNCATEGORIZED: + inputResourceId = theProcessedRequest.getId(); + if (inputResourceId == null || inputResourceId.hasIdPart() == false) { + return; + } else { + break; + } case IN: case BOTH: + inputResource = theProcessedRequest.getResource(); + inputResourceId = theProcessedRequest.getId(); break; case NONE: case OUT: @@ -219,7 +239,7 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer } RequestDetails requestDetails = theProcessedRequest.getRequestDetails(); - applyRulesAndFailIfDeny(theOperation, requestDetails, theProcessedRequest.getResource(), null); + applyRulesAndFailIfDeny(theOperation, requestDetails, inputResource, inputResourceId, null); } @Override @@ -236,7 +256,9 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer @Override public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject) { - switch (determineOperationDirection(theRequestDetails.getRestOperationType())) { + switch (determineOperationDirection(theRequestDetails.getRestOperationType(), null)) { + case IN_UNCATEGORIZED: + return true; case IN: case NONE: return true; @@ -246,8 +268,6 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer } FhirContext fhirContext = theRequestDetails.getServer().getFhirContext(); - List rules = buildRuleList(theRequestDetails); - List resources = Collections.emptyList(); switch (theRequestDetails.getRestOperationType()) { @@ -272,7 +292,7 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer } for (IBaseResource nextResponse : resources) { - applyRulesAndFailIfDeny(theRequestDetails.getRestOperationType(), theRequestDetails, null, nextResponse); + applyRulesAndFailIfDeny(theRequestDetails.getRestOperationType(), theRequestDetails, null, null, nextResponse); } return true; @@ -334,9 +354,10 @@ public class AuthorizationInterceptor extends InterceptorAdapter implements ISer private enum OperationExamineDirection { IN, + IN_UNCATEGORIZED, NONE, OUT, - BOTH + BOTH, } public static class Verdict { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/BaseRule.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/BaseRule.java index b874b253d75..9898ad868c4 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/BaseRule.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/BaseRule.java @@ -35,7 +35,7 @@ abstract class BaseRule implements IAuthRule { return myName; } - public void setMode(PolicyEnum theRuleMode) { + void setMode(PolicyEnum theRuleMode) { myMode = theRuleMode; } @@ -43,7 +43,7 @@ abstract class BaseRule implements IAuthRule { return new Verdict(myMode, this); } - public PolicyEnum getMode() { + PolicyEnum getMode() { return myMode; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRule.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRule.java index 2e49d2caadb..4750f92dc53 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRule.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRule.java @@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.server.interceptor.auth; */ import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.method.RequestDetails; @@ -37,6 +38,7 @@ public interface IAuthRule { * The request * @param theInputResource * The resource being input by the client, or null + * @param theInputResourceId TODO * @param theOutputResource * The resource being returned by the server, or null * @param theRuleApplier @@ -44,7 +46,7 @@ public interface IAuthRule { * nested objects in the request, such as nested requests in a transaction) * @return Returns a policy decision, or null if the rule does not apply */ - Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IBaseResource theOutputResource, IRuleApplier theRuleApplier); + Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource, IRuleApplier theRuleApplier); /** * Returns a name for this rule, to be used in logs and error messages diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderAppliesTo.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderAppliesTo.java new file mode 100644 index 00000000000..d4e6d013d34 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderAppliesTo.java @@ -0,0 +1,17 @@ +package ca.uhn.fhir.rest.server.interceptor.auth; + +import org.hl7.fhir.instance.model.api.IBaseResource; + +public interface IAuthRuleBuilderAppliesTo { + + /** + * Rule applies to resources of the given type + */ + T resourcesOfType(Class theType); + + /** + * Rule applies to all resources + */ + T allResources(); + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRule.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRule.java index 3e324f60895..4fe9b4352a0 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRule.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRule.java @@ -22,11 +22,39 @@ package ca.uhn.fhir.rest.server.interceptor.auth; public interface IAuthRuleBuilderRule { + /** + * This rule applies to create operations with a conditional + * URL as a part of the request. Note that this rule will allow the conditional + * operation to proceed, but the server is expected to determine the actual target + * of the conditional request and send a subsequent event to the {@link AuthorizationInterceptor} + * in order to authorize the actual target. + *

+ * In other words, if the server is configured correctly, this chain will allow the + * client to perform a conditional update, but a different rule is required to actually + * authorize the target that the conditional update is determined to match. + *

+ */ + IAuthRuleBuilderRuleConditional createConditional(); + /** * This rule applies to the FHIR delete operation */ IAuthRuleBuilderRuleOp delete(); + /** + * This rule applies to create operations with a conditional + * URL as a part of the request. Note that this rule will allow the conditional + * operation to proceed, but the server is expected to determine the actual target + * of the conditional request and send a subsequent event to the {@link AuthorizationInterceptor} + * in order to authorize the actual target. + *

+ * In other words, if the server is configured correctly, this chain will allow the + * client to perform a conditional update, but a different rule is required to actually + * authorize the target that the conditional update is determined to match. + *

+ */ + IAuthRuleBuilderRuleConditional deleteConditional(); + /** * This rules applies to the metadata operation (retrieve the * server's conformance statement) @@ -36,6 +64,11 @@ public interface IAuthRuleBuilderRule { */ IAuthRuleBuilderRuleOpClassifierFinished metadata(); + /** + * This rule applies to a FHIR operation (e.g. $validate) + */ + IAuthRuleBuilderOperation operation(); + /** * This rule applies to any FHIR operation involving reading, including * read, vread, search, and @@ -49,15 +82,24 @@ public interface IAuthRuleBuilderRule { */ IAuthRuleBuilderRuleTransaction transaction(); + /** + * This rule applies to update operations with a conditional + * URL as a part of the request. Note that this rule will allow the conditional + * operation to proceed, but the server is expected to determine the actual target + * of the conditional request and send a subsequent event to the {@link AuthorizationInterceptor} + * in order to authorize the actual target. + *

+ * In other words, if the server is configured correctly, this chain will allow the + * client to perform a conditional update, but a different rule is required to actually + * authorize the target that the conditional update is determined to match. + *

+ */ + IAuthRuleBuilderRuleConditional updateConditional(); + /** * This rule applies to any FHIR operation involving writing, including * create, and update */ IAuthRuleBuilderRuleOp write(); - /** - * This rule applies to a FHIR operation (e.g. $validate) - */ - IAuthRuleBuilderOperation operation(); - } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleConditional.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleConditional.java new file mode 100644 index 00000000000..b8576fc34f2 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleConditional.java @@ -0,0 +1,5 @@ +package ca.uhn.fhir.rest.server.interceptor.auth; + +public interface IAuthRuleBuilderRuleConditional extends IAuthRuleBuilderAppliesTo { + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleConditionalClassifier.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleConditionalClassifier.java new file mode 100644 index 00000000000..0693c0e8216 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleConditionalClassifier.java @@ -0,0 +1,27 @@ +package ca.uhn.fhir.rest.server.interceptor.auth; + +import java.util.List; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2016 University Health Network + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +public interface IAuthRuleBuilderRuleConditionalClassifier extends IAuthRuleFinished { + // nothing +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java index 9c9f05d1dc1..1b66894ca90 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOp.java @@ -1,37 +1,5 @@ package ca.uhn.fhir.rest.server.interceptor.auth; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2016 University Health Network - * %% - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import org.hl7.fhir.instance.model.api.IBaseResource; - -public interface IAuthRuleBuilderRuleOp { - - /** - * Rule applies to resources of the given type - */ - IAuthRuleBuilderRuleOpClassifier resourcesOfType(Class theType); - - /** - * Rule applies to all resources - */ - IAuthRuleBuilderRuleOpClassifier allResources(); - +public interface IAuthRuleBuilderRuleOp extends IAuthRuleBuilderAppliesTo { + // nothing } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOpClassifierFinished.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOpClassifierFinished.java index 5cc3844bc73..b4231e1325d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOpClassifierFinished.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleBuilderRuleOpClassifierFinished.java @@ -1,7 +1,5 @@ package ca.uhn.fhir.rest.server.interceptor.auth; -import java.util.List; - /* * #%L * HAPI FHIR - Core Library @@ -22,15 +20,6 @@ import java.util.List; * #L% */ -public interface IAuthRuleBuilderRuleOpClassifierFinished { - /** - * Start another rule - */ - IAuthRuleBuilder andThen(); - - /** - * Build the rule list - */ - List build(); - +public interface IAuthRuleBuilderRuleOpClassifierFinished extends IAuthRuleFinished { + // nothing } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleFinished.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleFinished.java new file mode 100644 index 00000000000..820d38d14a4 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IAuthRuleFinished.java @@ -0,0 +1,17 @@ +package ca.uhn.fhir.rest.server.interceptor.auth; + +import java.util.List; + +public interface IAuthRuleFinished { + + /** + * Start another rule + */ + IAuthRuleBuilder andThen(); + + /** + * Build the rule list + */ + List build(); + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IRuleApplier.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IRuleApplier.java index fecd7326ca3..dd7898c02a8 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IRuleApplier.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/IRuleApplier.java @@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.server.interceptor.auth; */ import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.method.RequestDetails; @@ -28,6 +29,6 @@ import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor.Verdict public interface IRuleApplier { - Verdict applyRulesAndReturnDecision(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IBaseResource theOutputResource); + Verdict applyRulesAndReturnDecision(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/OperationRule.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/OperationRule.java index 1e97a1b0c6d..e2cc9baa44f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/OperationRule.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/OperationRule.java @@ -54,7 +54,7 @@ class OperationRule extends BaseRule implements IAuthRule { } @Override - public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IBaseResource theOutputResource, IRuleApplier theRuleApplier) { + public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource, IRuleApplier theRuleApplier) { FhirContext ctx = theRequestDetails.getServer().getFhirContext(); boolean applies = false; @@ -67,7 +67,7 @@ class OperationRule extends BaseRule implements IAuthRule { case EXTENDED_OPERATION_TYPE: if (myAppliesToTypes != null) { for (Class next : myAppliesToTypes) { - String resName = ctx.getResourceDefinition(theRequestDetails.getResourceName()).getName(); + String resName = ctx.getResourceDefinition(next).getName(); if (resName.equals(theRequestDetails.getResourceName())) { applies = true; break; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleBuilder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleBuilder.java index 7ffeeaa92c1..45a65ef4af5 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleBuilder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleBuilder.java @@ -1,7 +1,5 @@ package ca.uhn.fhir.rest.server.interceptor.auth; -import java.util.ArrayList; - /* * #%L * HAPI FHIR - Core Library @@ -12,7 +10,7 @@ import java.util.ArrayList; * 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 + * 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, @@ -21,17 +19,14 @@ import java.util.ArrayList; * limitations under the License. * #L% */ - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; +import ca.uhn.fhir.rest.api.RestOperationTypeEnum; + public class RuleBuilder implements IAuthRuleBuilder { private ArrayList myRules; @@ -39,7 +34,7 @@ public class RuleBuilder implements IAuthRuleBuilder { public RuleBuilder() { myRules = new ArrayList(); } - + @Override public IAuthRuleBuilderRule allow() { return allow(null); @@ -57,7 +52,7 @@ public class RuleBuilder implements IAuthRuleBuilder { @Override public IAuthRuleBuilderRuleOpClassifierFinished allowAll(String theRuleName) { - myRules.add(new Rule(theRuleName).setOp(RuleOpEnum.ALLOW_ALL)); + myRules.add(new RuleImplOp(theRuleName).setOp(RuleOpEnum.ALLOW_ALL)); return new RuleBuilderFinished(); } @@ -83,21 +78,30 @@ public class RuleBuilder implements IAuthRuleBuilder { @Override public IAuthRuleBuilderRuleOpClassifierFinished denyAll(String theRuleName) { - myRules.add(new Rule(theRuleName).setOp(RuleOpEnum.DENY_ALL)); + myRules.add(new RuleImplOp(theRuleName).setOp(RuleOpEnum.DENY_ALL)); return new RuleBuilderFinished(); } - private final class RuleBuilderFinished implements IAuthRuleBuilderRuleOpClassifierFinished { + private class RuleBuilderFinished implements IAuthRuleFinished, IAuthRuleBuilderRuleOpClassifierFinished { @Override public IAuthRuleBuilder andThen() { + doBuildRule(); return RuleBuilder.this; } @Override public List build() { + doBuildRule(); return myRules; } + + /** + * Subclasses may override + */ + protected void doBuildRule() { + // nothing + } } private class RuleBuilderRule implements IAuthRuleBuilderRule { @@ -111,39 +115,100 @@ public class RuleBuilder implements IAuthRuleBuilder { myRuleName = theRuleName; } + @Override + public IAuthRuleBuilderRuleConditional createConditional() { + return new RuleBuilderRuleConditional(RestOperationTypeEnum.CREATE); + } + @Override public IAuthRuleBuilderRuleOp delete() { myRuleOp = RuleOpEnum.DELETE; return new RuleBuilderRuleOp(); } - + + @Override + public IAuthRuleBuilderRuleConditional deleteConditional() { + return new RuleBuilderRuleConditional(RestOperationTypeEnum.DELETE); + } + @Override public RuleBuilderFinished metadata() { - Rule rule = new Rule(myRuleName); + RuleImplOp rule = new RuleImplOp(myRuleName); rule.setOp(RuleOpEnum.METADATA); rule.setMode(myRuleMode); myRules.add(rule); return new RuleBuilderFinished(); } + @Override + public IAuthRuleBuilderOperation operation() { + return new RuleBuilderRuleOperation(); + } + @Override public IAuthRuleBuilderRuleOp read() { myRuleOp = RuleOpEnum.READ; return new RuleBuilderRuleOp(); } - + @Override public IAuthRuleBuilderRuleTransaction transaction() { myRuleOp = RuleOpEnum.TRANSACTION; return new RuleBuilderRuleTransaction(); } - + + @Override + public IAuthRuleBuilderRuleConditional updateConditional() { + return new RuleBuilderRuleConditional(RestOperationTypeEnum.UPDATE); + } + @Override public IAuthRuleBuilderRuleOp write() { myRuleOp = RuleOpEnum.WRITE; return new RuleBuilderRuleOp(); } + private class RuleBuilderRuleConditional implements IAuthRuleBuilderRuleConditional { + + private AppliesTypeEnum myAppliesTo; + + private Set myAppliesToTypes; + private RestOperationTypeEnum myOperationType; + + public RuleBuilderRuleConditional(RestOperationTypeEnum theOperationType) { + myOperationType = theOperationType; + } + + @Override + public IAuthRuleBuilderRuleConditionalClassifier allResources() { + myAppliesTo = AppliesTypeEnum.ALL_RESOURCES; + return new RuleBuilderRuleConditionalClassifier(); + } + + @Override + public IAuthRuleBuilderRuleConditionalClassifier resourcesOfType(Class theType) { + Validate.notNull(theType, "theType must not be null"); + myAppliesTo = AppliesTypeEnum.TYPES; + myAppliesToTypes = Collections.singleton(theType); + return new RuleBuilderRuleConditionalClassifier(); + } + + public class RuleBuilderRuleConditionalClassifier extends RuleBuilderFinished implements IAuthRuleBuilderRuleConditionalClassifier { + + @Override + protected void doBuildRule() { + RuleImplConditional rule = new RuleImplConditional(myRuleName); + rule.setMode(myRuleMode); + rule.setOperationType(myOperationType); + rule.setAppliesTo(myAppliesTo); + rule.setAppliesToTypes(myAppliesToTypes); + myRules.add(rule); + + } + } + + } + private class RuleBuilderRuleOp implements IAuthRuleBuilderRuleOp { private AppliesTypeEnum myAppliesTo; @@ -170,8 +235,8 @@ public class RuleBuilder implements IAuthRuleBuilder { private Collection myInCompartmentOwners; private IAuthRuleBuilderRuleOpClassifierFinished finished() { - - Rule rule = new Rule(myRuleName); + + RuleImplOp rule = new RuleImplOp(myRuleName); rule.setMode(myRuleMode); rule.setOp(myRuleOp); rule.setAppliesTo(myAppliesTo); @@ -180,7 +245,7 @@ public class RuleBuilder implements IAuthRuleBuilder { rule.setClassifierCompartmentName(myInCompartmentName); rule.setClassifierCompartmentOwners(myInCompartmentOwners); myRules.add(rule); - + return new RuleBuilderFinished(); } @@ -222,29 +287,18 @@ public class RuleBuilder implements IAuthRuleBuilder { } - private class RuleBuilderRuleTransaction implements IAuthRuleBuilderRuleTransaction { + private class RuleBuilderRuleOperation implements IAuthRuleBuilderOperation { @Override - public IAuthRuleBuilderRuleTransactionOp withAnyOperation() { - return new RuleBuilderRuleTransactionOp(); + public IAuthRuleBuilderOperationNamed named(String theOperationName) { + Validate.notBlank(theOperationName, "theOperationName must not be null or empty"); + return new RuleBuilderRuleOperationNamed(theOperationName); } - private class RuleBuilderRuleTransactionOp implements IAuthRuleBuilderRuleTransactionOp { - @Override - public IAuthRuleBuilderRuleOpClassifierFinished andApplyNormalRules() { - Rule rule = new Rule(myRuleName); - rule.setMode(myRuleMode); - rule.setOp(myRuleOp); - rule.setTransactionAppliesToOp(TransactionAppliesToEnum.ANY_OPERATION); - myRules.add(rule); - return new RuleBuilderFinished(); - } - + @Override + public IAuthRuleBuilderOperationNamed withAnyName() { + return new RuleBuilderRuleOperationNamed(null); } - - } - - private class RuleBuilderRuleOperation implements IAuthRuleBuilderOperation { private class RuleBuilderRuleOperationNamed implements IAuthRuleBuilderOperationNamed { @@ -258,14 +312,6 @@ public class RuleBuilder implements IAuthRuleBuilder { } } - @Override - public IAuthRuleBuilderRuleOpClassifierFinished onServer() { - OperationRule rule = createRule(); - rule.appliesToServer(); - myRules.add(rule); - return new RuleBuilderFinished(); - } - private OperationRule createRule() { OperationRule rule = new OperationRule(myRuleName); rule.setOperationName(myOperationName); @@ -273,24 +319,12 @@ public class RuleBuilder implements IAuthRuleBuilder { return rule; } - @Override - public IAuthRuleBuilderRuleOpClassifierFinished onType(Class theType) { - Validate.notNull(theType, "theType must not be null"); - - OperationRule rule = createRule(); - HashSet> appliesToTypes = new HashSet>(); - appliesToTypes.add(theType); - rule.appliesToTypes(appliesToTypes); - myRules.add(rule); - return new RuleBuilderFinished(); - } - @Override public IAuthRuleBuilderRuleOpClassifierFinished onInstance(IIdType theInstanceId) { Validate.notNull(theInstanceId, "theInstanceId must not be null"); Validate.notBlank(theInstanceId.getResourceType(), "theInstanceId does not have a resource type"); Validate.notBlank(theInstanceId.getIdPart(), "theInstanceId does not have an ID part"); - + OperationRule rule = createRule(); ArrayList ids = new ArrayList(); ids.add(theInstanceId); @@ -298,26 +332,54 @@ public class RuleBuilder implements IAuthRuleBuilder { myRules.add(rule); return new RuleBuilderFinished(); } - - } - - @Override - public IAuthRuleBuilderOperationNamed named(String theOperationName) { - Validate.notBlank(theOperationName, "theOperationName must not be null or empty"); - return new RuleBuilderRuleOperationNamed(theOperationName); + + @Override + public IAuthRuleBuilderRuleOpClassifierFinished onServer() { + OperationRule rule = createRule(); + rule.appliesToServer(); + myRules.add(rule); + return new RuleBuilderFinished(); + } + + @Override + public IAuthRuleBuilderRuleOpClassifierFinished onType(Class theType) { + Validate.notNull(theType, "theType must not be null"); + + OperationRule rule = createRule(); + HashSet> appliesToTypes = new HashSet>(); + appliesToTypes.add(theType); + rule.appliesToTypes(appliesToTypes); + myRules.add(rule); + return new RuleBuilderFinished(); + } + } - @Override - public IAuthRuleBuilderOperationNamed withAnyName() { - return new RuleBuilderRuleOperationNamed(null); - } - } - @Override - public IAuthRuleBuilderOperation operation() { - return new RuleBuilderRuleOperation(); + private class RuleBuilderRuleTransaction implements IAuthRuleBuilderRuleTransaction { + + @Override + public IAuthRuleBuilderRuleTransactionOp withAnyOperation() { + return new RuleBuilderRuleTransactionOp(); + } + + private class RuleBuilderRuleTransactionOp implements IAuthRuleBuilderRuleTransactionOp { + + @Override + public IAuthRuleBuilderRuleOpClassifierFinished andApplyNormalRules() { + RuleImplOp rule = new RuleImplOp(myRuleName); + rule.setMode(myRuleMode); + rule.setOp(myRuleOp); + rule.setTransactionAppliesToOp(TransactionAppliesToEnum.ANY_OPERATION); + myRules.add(rule); + return new RuleBuilderFinished(); + } + + } + } + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplConditional.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplConditional.java new file mode 100644 index 00000000000..01367b86c87 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplConditional.java @@ -0,0 +1,63 @@ +package ca.uhn.fhir.rest.server.interceptor.auth; + +import java.util.Set; + +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; + +import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.method.RequestDetails; +import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor.Verdict; + +public class RuleImplConditional extends BaseRule implements IAuthRule { + + private AppliesTypeEnum myAppliesTo; + private Set myAppliesToTypes; + private RestOperationTypeEnum myOperationType; + + public RuleImplConditional(String theRuleName) { + super(theRuleName); + } + + @Override + public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource, + IRuleApplier theRuleApplier) { + + if (theInputResourceId != null) { + return null; + } + + if (theOperation == myOperationType) { + switch (myAppliesTo) { + case ALL_RESOURCES: + break; + case TYPES: + if (theInputResource == null || !myAppliesToTypes.contains(theInputResource.getClass())) { + return null; + } + break; + } + + if (theRequestDetails.getConditionalUrl(myOperationType) == null) { + return null; + } + + return newVerdict(); + } + + return null; + } + + void setAppliesTo(AppliesTypeEnum theAppliesTo) { + myAppliesTo = theAppliesTo; + } + + void setAppliesToTypes(Set theAppliesToTypes) { + myAppliesToTypes = theAppliesToTypes; + } + + void setOperationType(RestOperationTypeEnum theOperationType) { + myOperationType = theOperationType; + } + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/Rule.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java similarity index 81% rename from hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/Rule.java rename to hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java index ffd6fad82f6..05af00d3d98 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/Rule.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/interceptor/auth/RuleImplOp.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.server.interceptor.auth; * 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 + * 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, @@ -39,7 +39,7 @@ import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.BundleUtil.BundleEntryParts; import ca.uhn.fhir.util.FhirTerser; -class Rule extends BaseRule implements IAuthRule { +class RuleImplOp extends BaseRule implements IAuthRule { private AppliesTypeEnum myAppliesTo; private Set myAppliesToTypes; @@ -49,34 +49,37 @@ class Rule extends BaseRule implements IAuthRule { private RuleOpEnum myOp; private TransactionAppliesToEnum myTransactionAppliesToOp; - public Rule(String theRuleName) { + public RuleImplOp(String theRuleName) { super(theRuleName); } @Override - public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IBaseResource theOutputResource, IRuleApplier theRuleApplier) { + public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource, + IRuleApplier theRuleApplier) { FhirContext ctx = theRequestDetails.getServer().getFhirContext(); - IBaseResource appliesTo; + IBaseResource appliesToResource; + IIdType appliesToResourceId = null; switch (myOp) { case READ: if (theOutputResource == null) { return null; } - appliesTo = theOutputResource; + appliesToResource = theOutputResource; break; case WRITE: - if (theInputResource == null) { + if (theInputResource == null && theInputResourceId == null) { return null; } - appliesTo = theInputResource; + appliesToResource = theInputResource; + appliesToResourceId = theInputResourceId; break; case DELETE: if (theOperation == RestOperationTypeEnum.DELETE) { if (theInputResource == null) { return newVerdict(); } else { - appliesTo = theInputResource; + appliesToResource = theInputResource; } } else { return null; @@ -115,7 +118,7 @@ class Rule extends BaseRule implements IAuthRule { throw new InvalidRequestException("Can not handle transaction with nested resource of type " + resourceDef.getName()); } - Verdict newVerdict = theRuleApplier.applyRulesAndReturnDecision(operation, theRequestDetails, inputResource, null); + Verdict newVerdict = theRuleApplier.applyRulesAndReturnDecision(operation, theRequestDetails, inputResource, null, null); if (newVerdict == null) { continue; } else if (verdict == null) { @@ -133,7 +136,7 @@ class Rule extends BaseRule implements IAuthRule { if (nextPart.getResource() == null) { continue; } - Verdict newVerdict = theRuleApplier.applyRulesAndReturnDecision(RestOperationTypeEnum.READ, theRequestDetails, null, nextPart.getResource()); + Verdict newVerdict = theRuleApplier.applyRulesAndReturnDecision(RestOperationTypeEnum.READ, theRequestDetails, null, null, nextPart.getResource()); if (newVerdict == null) { continue; } else if (verdict == null) { @@ -165,8 +168,16 @@ class Rule extends BaseRule implements IAuthRule { case ALL_RESOURCES: break; case TYPES: - if (myAppliesToTypes.contains(appliesTo.getClass()) == false) { - return null; + if (appliesToResource != null) { + if (myAppliesToTypes.contains(appliesToResource.getClass()) == false) { + return null; + } + } + if (appliesToResourceId != null) { + Class type = theRequestDetails.getServer().getFhirContext().getResourceDefinition(appliesToResourceId.getResourceType()).getImplementingClass(); + if (myAppliesToTypes.contains(type) == false) { + return null; + } } break; default: @@ -180,9 +191,17 @@ class Rule extends BaseRule implements IAuthRule { FhirTerser t = ctx.newTerser(); boolean foundMatch = false; for (IIdType next : myClassifierCompartmentOwners) { - if (t.isSourceInCompartmentForTarget(myClassifierCompartmentName, appliesTo, next)) { - foundMatch = true; - break; + if (appliesToResource != null) { + if (t.isSourceInCompartmentForTarget(myClassifierCompartmentName, appliesToResource, next)) { + foundMatch = true; + break; + } + } + if (appliesToResourceId != null && appliesToResourceId.hasResourceType() && appliesToResourceId.hasIdPart()) { + if (appliesToResourceId.toUnqualifiedVersionless().getValue().equals(next.toUnqualifiedVersionless().getValue())) { + foundMatch = true; + break; + } } } if (!foundMatch) { @@ -196,7 +215,6 @@ class Rule extends BaseRule implements IAuthRule { return newVerdict(); } - private boolean requestAppliesToTransaction(FhirContext theContext, RuleOpEnum theOp, IBaseResource theInputResource) { if (!"Bundle".equals(theContext.getResourceDefinition(theInputResource).getName())) { return false; @@ -238,8 +256,7 @@ class Rule extends BaseRule implements IAuthRule { myClassifierType = theClassifierType; } - - public Rule setOp(RuleOpEnum theRuleOp) { + public RuleImplOp setOp(RuleOpEnum theRuleOp) { myOp = theRuleOp; return this; } diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java index b58d935daaa..efb8508273c 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java @@ -386,9 +386,9 @@ public class AbstractJaxRsResourceProviderDstu3Test { when(mock.update(idCaptor.capture(), patientCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome()); client.update().resource(createPatient(1)).conditional().where(Patient.IDENTIFIER.exactly().identifier("2")).execute(); - compareResultId(1, patientCaptor.getValue()); + assertEquals(null, patientCaptor.getValue().getIdElement().getIdPart()); + assertEquals(null, patientCaptor.getValue().getIdElement().getVersionIdPart()); assertEquals("Patient?identifier=2&_format=json", conditionalCaptor.getValue()); - compareResultId(1, patientCaptor.getValue()); } @SuppressWarnings("unchecked") diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java index b7d35635847..837f2509963 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java @@ -70,7 +70,6 @@ import ca.uhn.fhir.util.TestUtil; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class AbstractJaxRsResourceProviderTest { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(AbstractJaxRsResourceProviderTest.class); private static IGenericClient client; @@ -372,9 +371,8 @@ public class AbstractJaxRsResourceProviderTest { when(mock.update(idCaptor.capture(), patientCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome()); client.update().resource(createPatient(1)).conditional().where(Patient.IDENTIFIER.exactly().identifier("2")).execute(); - assertEquals("1", patientCaptor.getValue().getId().getIdPart()); + assertEquals(null, patientCaptor.getValue().getId().getIdPart()); assertEquals("Patient?identifier=2&_format=json", conditionalCaptor.getValue()); - compareResultId(1, patientCaptor.getValue()); } @SuppressWarnings("unchecked") diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 6467060e0ce..e6c529ae3e1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -166,9 +166,12 @@ public abstract class BaseHapiFhirResourceDao extends B String message = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "failedToCreateWithClientAssignedNumericId", theResource.getIdElement().getIdPart()); throw new InvalidRequestException(message, createErrorOperationOutcome(message, "processing")); } - } else { + } else if (getContext().getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { String message = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "failedToCreateWithClientAssignedId", theResource.getIdElement().getIdPart()); throw new InvalidRequestException(message, createErrorOperationOutcome(message, "processing")); + } else { + // As of DSTU3, ID and version in the body should be ignored for a create/update + theResource.setId(""); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java index 3184454e192..6fc1ddba100 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java @@ -58,7 +58,7 @@ public class DatabaseBackedPagingProvider extends FifoMemoryPagingProvider { if (!provider.ensureSearchEntityLoaded()) { return null; } - return provider; + retVal = provider; } return retVal; } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java index 0ed2703f7ae..c28c06470a8 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java @@ -14,46 +14,16 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import java.math.BigDecimal; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.hl7.fhir.dstu3.model.Appointment; -import org.hl7.fhir.dstu3.model.CodeType; -import org.hl7.fhir.dstu3.model.CodeableConcept; -import org.hl7.fhir.dstu3.model.Coding; +import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem; -import org.hl7.fhir.dstu3.model.DateTimeType; -import org.hl7.fhir.dstu3.model.DateType; -import org.hl7.fhir.dstu3.model.Device; -import org.hl7.fhir.dstu3.model.DiagnosticRequest; -import org.hl7.fhir.dstu3.model.DiagnosticReport; -import org.hl7.fhir.dstu3.model.Encounter; import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender; -import org.hl7.fhir.dstu3.model.IdType; -import org.hl7.fhir.dstu3.model.Immunization; -import org.hl7.fhir.dstu3.model.Location; -import org.hl7.fhir.dstu3.model.Medication; -import org.hl7.fhir.dstu3.model.MedicationOrder; -import org.hl7.fhir.dstu3.model.Observation; -import org.hl7.fhir.dstu3.model.Organization; -import org.hl7.fhir.dstu3.model.Patient; -import org.hl7.fhir.dstu3.model.Period; -import org.hl7.fhir.dstu3.model.Practitioner; -import org.hl7.fhir.dstu3.model.Quantity; -import org.hl7.fhir.dstu3.model.Reference; -import org.hl7.fhir.dstu3.model.StringType; -import org.hl7.fhir.dstu3.model.Subscription; import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType; import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus; -import org.hl7.fhir.dstu3.model.Substance; -import org.hl7.fhir.dstu3.model.TemporalPrecisionEnum; -import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -63,35 +33,13 @@ import org.junit.Test; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.SearchParameterMap; -import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate; -import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber; -import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity; -import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString; -import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken; -import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri; -import ca.uhn.fhir.jpa.entity.ResourceLink; +import ca.uhn.fhir.jpa.entity.*; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum; import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortSpec; -import ca.uhn.fhir.rest.param.CompositeParam; -import ca.uhn.fhir.rest.param.DateParam; -import ca.uhn.fhir.rest.param.DateRangeParam; -import ca.uhn.fhir.rest.param.HasParam; -import ca.uhn.fhir.rest.param.NumberParam; -import ca.uhn.fhir.rest.param.ParamPrefixEnum; -import ca.uhn.fhir.rest.param.QuantityParam; -import ca.uhn.fhir.rest.param.ReferenceParam; -import ca.uhn.fhir.rest.param.StringAndListParam; -import ca.uhn.fhir.rest.param.StringOrListParam; -import ca.uhn.fhir.rest.param.StringParam; -import ca.uhn.fhir.rest.param.TokenAndListParam; -import ca.uhn.fhir.rest.param.TokenOrListParam; -import ca.uhn.fhir.rest.param.TokenParam; -import ca.uhn.fhir.rest.param.TokenParamModifier; -import ca.uhn.fhir.rest.param.UriParam; -import ca.uhn.fhir.rest.param.UriParamQualifierEnum; +import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.IBundleProvider; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 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 105c3aa2ca5..bdd01237434 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 @@ -634,17 +634,13 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } @Test - public void testCreateTextIdFails() { + public void testCreateTextIdDoesntFail() { Patient p = new Patient(); p.addIdentifier().setSystem("urn:system").setValue("testCreateTextIdFails"); p.addName().addFamily("Hello"); p.setId("Patient/ABC"); - try { - myPatientDao.create(p, mySrd); - fail(); - } catch (InvalidRequestException e) { - assertThat(e.getMessage(), containsString("Can not create resource with ID[ABC], ID must not be supplied")); - } + String id = myPatientDao.create(p, mySrd).getId().getIdPart(); + assertNotEquals("ABC", id); } @Test @@ -678,20 +674,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { assertThat(toUnqualifiedVersionlessIdValues(myCarePlanDao.search(params)), empty()); } - @Test - public void testCreateWithIdFails() { - Patient p = new Patient(); - p.addIdentifier().setSystem("urn:system").setValue("testCreateNumericIdFails"); - p.addName().addFamily("Hello"); - p.setId("Patient/abc"); - try { - myPatientDao.create(p, mySrd); - fail(); - } catch (InvalidRequestException e) { - assertThat(e.getMessage(), containsString("Can not create resource with ID[abc], ID must not be supplied")); - } - } - @Test public void testCreateBundleAllowsDocumentAndCollection() { String methodName = "testCreateBundleAllowsDocumentAndCollection"; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/AuthorizationInterceptorResourceProviderDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/AuthorizationInterceptorResourceProviderDstu3Test.java index 6e64abe9e4a..1800a56defc 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/AuthorizationInterceptorResourceProviderDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/AuthorizationInterceptorResourceProviderDstu3Test.java @@ -70,6 +70,7 @@ public class AuthorizationInterceptorResourceProviderDstu3Test extends BaseResou //@formatter:off return new RuleBuilder() .allow("Rule 2").write().allResources().inCompartment("Patient", new IdDt("Patient/" + output1.getId().getIdPart())).andThen() + .allow().updateConditional().allResources() .build(); //@formatter:on } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java index add32791221..99986be7610 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.jpa.provider.dstu3; +import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInRelativeOrder; @@ -95,9 +96,11 @@ import org.hl7.fhir.instance.model.api.IIdType; import org.junit.AfterClass; import org.junit.Ignore; import org.junit.Test; +import org.springframework.core.NestedExceptionUtils; import com.google.common.collect.Lists; +import ca.uhn.fhir.jpa.dao.SearchParameterMap; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.parser.IParser; @@ -128,6 +131,47 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { } + @Test + public void testSearchPagingKeepsOldSearches() throws Exception { + String methodName = "testSearchPagingKeepsOldSearches"; + IIdType pid1; + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("0"); + patient.addName().addFamily(methodName).addGiven("Joe"); + pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + + for (int i = 1; i <= 20; i++) { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue(Integer.toString(i)); + patient.addName().addFamily(methodName).addGiven("Joe"); + myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + + List linkNext = Lists.newArrayList(); + for (int i = 0 ; i < 100; i++) { + Bundle bundle = ourClient + .search() + .forResource(Patient.class) + .where(Patient.NAME.matches().value("testSearchPagingKeepsOldSearches")) + .count(5) + .returnBundle(Bundle.class) + .execute(); + assertTrue(isNotBlank(bundle.getLink("next").getUrl())); + assertEquals(5, bundle.getEntry().size()); + linkNext.add(bundle.getLink("next").getUrl()); + } + + int index = 0; + for (String nextLink : linkNext) { + ourLog.info("Fetching index {}", index++); + Bundle b = ourClient.fetchResourceFromUrl(Bundle.class, nextLink); + assertEquals(5, b.getEntry().size()); + } + } + + @Test public void testHasParameter() throws Exception { IIdType pid0; @@ -570,6 +614,107 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { } + @Test + public void testIdAndVersionInBodyForCreate() throws IOException { + String methodName = "testIdAndVersionInBodyForCreate"; + + Patient pt = new Patient(); + pt.setId("Patient/AAA/_history/4"); + pt.addName().addFamily(methodName); + String resource = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(pt); + + ourLog.info("Input: {}", resource); + + HttpPost post = new HttpPost(ourServerBase + "/Patient"); + post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + CloseableHttpResponse response = ourHttpClient.execute(post); + IdType id; + try { + String respString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info("Response: {}", respString); + assertEquals(201, response.getStatusLine().getStatusCode()); + String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(); + assertThat(newIdString, startsWith(ourServerBase + "/Patient/")); + id = new IdType(newIdString); + } finally { + response.close(); + } + + assertEquals("1", id.getVersionIdPart()); + assertNotEquals("AAA", id.getIdPart()); + + HttpGet get = new HttpGet(ourServerBase + "/Patient/" + id.getIdPart()); + response = ourHttpClient.execute(get); + try { + assertEquals(200, response.getStatusLine().getStatusCode()); + String respString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info("Response: {}", respString); + assertThat(respString, containsString("")); + assertThat(respString, containsString("")); + } finally { + response.close(); + } + } + + @Test + public void testIdAndVersionInBodyForUpdate() throws IOException { + String methodName = "testIdAndVersionInBodyForUpdate"; + + Patient pt = new Patient(); + pt.setId("Patient/AAA/_history/4"); + pt.addName().addFamily(methodName); + String resource = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(pt); + + ourLog.info("Input: {}", resource); + + HttpPost post = new HttpPost(ourServerBase + "/Patient"); + post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + CloseableHttpResponse response = ourHttpClient.execute(post); + IdType id; + try { + String respString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info("Response: {}", respString); + assertEquals(201, response.getStatusLine().getStatusCode()); + String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(); + assertThat(newIdString, startsWith(ourServerBase + "/Patient/")); + id = new IdType(newIdString); + } finally { + response.close(); + } + + assertEquals("1", id.getVersionIdPart()); + assertNotEquals("AAA", id.getIdPart()); + + HttpPut put = new HttpPut(ourServerBase + "/Patient/" + id.getIdPart() + "/_history/1"); + put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + response = ourHttpClient.execute(put); + try { + String respString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info("Response: {}", respString); + assertEquals(200, response.getStatusLine().getStatusCode()); + String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue(); + assertThat(newIdString, startsWith(ourServerBase + "/Patient/")); + id = new IdType(newIdString); + } finally { + response.close(); + } + + assertEquals("2", id.getVersionIdPart()); + assertNotEquals("AAA", id.getIdPart()); + + HttpGet get = new HttpGet(ourServerBase + "/Patient/" + id.getIdPart()); + response = ourHttpClient.execute(get); + try { + assertEquals(200, response.getStatusLine().getStatusCode()); + String respString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info("Response: {}", respString); + assertThat(respString, containsString("")); + assertThat(respString, containsString("")); + } finally { + response.close(); + } + } + @Test public void testCreateResourceConditionalComplex() throws IOException { Patient pt = new Patient(); @@ -2493,9 +2638,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { put.addHeader("Accept", Constants.CT_FHIR_JSON); CloseableHttpResponse response = ourHttpClient.execute(put); try { - assertEquals(400, response.getStatusLine().getStatusCode()); - OperationOutcome oo = myFhirCtx.newJsonParser().parseResource(OperationOutcome.class, new InputStreamReader(response.getEntity().getContent())); - assertEquals("Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"FOO\" does not match URL ID of \""+p1id.getIdPart()+"\"", oo.getIssue().get(0).getDiagnostics()); + assertEquals(200, response.getStatusLine().getStatusCode()); } finally { response.close(); } @@ -2722,16 +2865,15 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { pt.addName().addFamily(methodName); String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt); - HttpPut post = new HttpPut(ourServerBase + "/Patient/2"); + HttpPut post = new HttpPut(ourServerBase + "/Patient/A2"); post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); CloseableHttpResponse response = ourHttpClient.execute(post); try { String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(responseString); - assertEquals(400, response.getStatusLine().getStatusCode()); - OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, responseString); - assertThat(oo.getIssue().get(0).getDiagnostics(), containsString( - "Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"333\" does not match URL ID of \"2\"")); + assertEquals(201, response.getStatusLine().getStatusCode()); + assertThat(responseString, containsString("/A2/")); + assertThat(responseString, not(containsString("333"))); } finally { response.close(); } diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java index c78f90f983a..8b076a2d19b 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java +++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java @@ -25,6 +25,7 @@ import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2; import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3; import ca.uhn.fhir.jpa.provider.dstu3.TerminologyUploaderProviderDstu3; +import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.rest.server.ETagSupportEnum; import ca.uhn.fhir.rest.server.EncodingEnum; @@ -200,11 +201,10 @@ public class TestRestfulServer extends RestfulServer { setServerAddressStrategy(new MyHardcodedServerAddressStrategy(baseUrl)); /* - * This is a simple paging strategy that keeps the last 10 - * searches in memory + * Spool results to the database */ - setPagingProvider(new FifoMemoryPagingProvider(10).setMaximumPageSize(500)); - + setPagingProvider(myAppCtx.getBean(DatabaseBackedPagingProvider.class)); + /* * Load interceptors for the server from Spring */ diff --git a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java index 9c257ddc131..0aaab012721 100644 --- a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java +++ b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java @@ -307,6 +307,8 @@ public abstract class BaseResource extends BaseElement implements IResource { myId = (IdDt) theId; } else if (theId != null) { myId = new IdDt(theId.getValue()); + } else { + myId = null; } return this; } diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptorDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptorDstu2Test.java index 36534b0623f..f5daeb3ff33 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptorDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/interceptor/auth/AuthorizationInterceptorDstu2Test.java @@ -70,6 +70,7 @@ import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; +import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.util.PortUtil; import ca.uhn.fhir.util.TestUtil; @@ -77,6 +78,7 @@ public class AuthorizationInterceptorDstu2Test { private static final String ERR403 = "{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"severity\":\"error\",\"code\":\"processing\",\"diagnostics\":\"Access denied by default policy (no applicable rules)\"}]}"; private static CloseableHttpClient ourClient; + private static String ourConditionalCreateId; private static FhirContext ourCtx = FhirContext.forDstu2(); private static boolean ourHitMethod; private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(AuthorizationInterceptorDstu2Test.class); @@ -85,6 +87,7 @@ public class AuthorizationInterceptorDstu2Test { private static Server ourServer; private static RestfulServer ourServlet; + @Before public void before() { ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.NEVER); @@ -93,9 +96,9 @@ public class AuthorizationInterceptorDstu2Test { } ourReturn = null; ourHitMethod = false; + ourConditionalCreateId = "1123"; } - private HttpEntity createFhirResourceEntity(IBaseResource theResource) { String out = ourCtx.newJsonParser().encodeResourceToString(theResource); return new StringEntity(out, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8")); @@ -175,286 +178,6 @@ public class AuthorizationInterceptorDstu2Test { } - @Test - public void testOperationServerLevel() throws Exception { - ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { - @Override - public List buildRuleList(RequestDetails theRequestDetails) { - //@formatter:off - return new RuleBuilder() - .allow("RULE 1").operation().named("opName").onServer().andThen() - .build(); - //@formatter:on - } - }); - - HttpGet httpGet; - HttpResponse status; - String response; - - // Server - ourHitMethod = false; - ourReturn = Arrays.asList(createObservation(10, "Patient/2")); - httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); - status = ourClient.execute(httpGet); - extractResponseAndClose(status); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); - - // Type - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - // Instance - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - } - - @Test - public void testOperationInstanceLevel() throws Exception { - ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { - @Override - public List buildRuleList(RequestDetails theRequestDetails) { - //@formatter:off - return new RuleBuilder() - .allow("RULE 1").operation().named("opName").onInstance(new IdDt("http://example.com/Patient/1/_history/2")).andThen() - .build(); - //@formatter:on - } - }); - - HttpGet httpGet; - HttpResponse status; - String response; - - // Server - ourHitMethod = false; - ourReturn = Arrays.asList(createObservation(10, "Patient/2")); - httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - // Type - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - // Instance - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); - - // Wrong instance - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - } - - @Test - public void testOperationAnyName() throws Exception { - ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { - @Override - public List buildRuleList(RequestDetails theRequestDetails) { - //@formatter:off - return new RuleBuilder() - .allow("RULE 1").operation().withAnyName().onServer().andThen() - .build(); - //@formatter:on - } - }); - - HttpGet httpGet; - HttpResponse status; - String response; - - // Server - ourHitMethod = false; - ourReturn = Arrays.asList(createObservation(10, "Patient/2")); - httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); - - } - - @Test - public void testOperationTypeLevel() throws Exception { - ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { - @Override - public List buildRuleList(RequestDetails theRequestDetails) { - //@formatter:off - return new RuleBuilder() - .allow("RULE 1").operation().named("opName").onType(Patient.class).andThen() - .build(); - //@formatter:on - } - }); - - HttpGet httpGet; - HttpResponse status; - String response; - - // Server - ourHitMethod = false; - ourReturn = Arrays.asList(createObservation(10, "Patient/2")); - httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - // Type - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); - - // Wrong type - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/1/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - // Wrong name - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName2"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - - // Instance - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by default policy")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - } - - @Test - public void testDenyAll() throws Exception { - ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { - @Override - public List buildRuleList(RequestDetails theRequestDetails) { - //@formatter:off - return new RuleBuilder() - .allow().read().resourcesOfType(Patient.class).withAnyId().andThen() - .denyAll("Default Rule") - .build(); - //@formatter:on - } - }); - - HttpGet httpGet; - HttpResponse status; - String response; - - ourHitMethod = false; - ourReturn = Arrays.asList(createPatient(2)); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1"); - status = ourClient.execute(httpGet); - extractResponseAndClose(status); - assertEquals(200, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); - - ourHitMethod = false; - ourReturn = Arrays.asList(createObservation(10, "Patient/2")); - httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/10"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by rule: Default Rule")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); - - ourHitMethod = false; - httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$validate"); - status = ourClient.execute(httpGet); - response = extractResponseAndClose(status); - ourLog.info(response); - assertThat(response, containsString("Access denied by rule: Default Rule")); - assertEquals(403, status.getStatusLine().getStatusCode()); - assertFalse(ourHitMethod); - } - - @Test - public void testMetadataAllow() throws Exception { - ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { - @Override - public List buildRuleList(RequestDetails theRequestDetails) { - //@formatter:off - return new RuleBuilder() - .allow("Rule 1").metadata() - .build(); - //@formatter:on - } - }); - - HttpGet httpGet; - HttpResponse status; - String response; - - ourReturn = Arrays.asList(createPatient(2)); - ourHitMethod = false; - httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata"); - status = ourClient.execute(httpGet); - extractResponseAndClose(status); - assertEquals(200, status.getStatusLine().getStatusCode()); - } - @Test public void testBatchWhenOnlyTransactionAllowed() throws Exception { ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { @@ -564,6 +287,77 @@ public class AuthorizationInterceptorDstu2Test { assertEquals(ERR403, response); } + @Test + public void testDenyAll() throws Exception { + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow().read().resourcesOfType(Patient.class).withAnyId().andThen() + .denyAll("Default Rule") + .build(); + //@formatter:on + } + }); + + HttpGet httpGet; + HttpResponse status; + String response; + + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1"); + status = ourClient.execute(httpGet); + extractResponseAndClose(status); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + ourHitMethod = false; + ourReturn = Arrays.asList(createObservation(10, "Patient/2")); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/10"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by rule: Default Rule")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + ourHitMethod = false; + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$validate"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by rule: Default Rule")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + } + + @Test + public void testMetadataAllow() throws Exception { + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("Rule 1").metadata() + .build(); + //@formatter:on + } + }); + + HttpGet httpGet; + HttpResponse status; + String response; + + ourReturn = Arrays.asList(createPatient(2)); + ourHitMethod = false; + httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata"); + status = ourClient.execute(httpGet); + extractResponseAndClose(status); + assertEquals(200, status.getStatusLine().getStatusCode()); + } + @Test public void testMetadataDeny() throws Exception { ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.ALLOW) { @@ -588,7 +382,216 @@ public class AuthorizationInterceptorDstu2Test { extractResponseAndClose(status); assertEquals(403, status.getStatusLine().getStatusCode()); } + + @Test + public void testOperationAnyName() throws Exception { + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("RULE 1").operation().withAnyName().onServer().andThen() + .build(); + //@formatter:on + } + }); + + HttpGet httpGet; + HttpResponse status; + String response; + + // Server + ourHitMethod = false; + ourReturn = Arrays.asList(createObservation(10, "Patient/2")); + httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + } + + @Test + public void testOperationInstanceLevel() throws Exception { + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("RULE 1").operation().named("opName").onInstance(new IdDt("http://example.com/Patient/1/_history/2")).andThen() + .build(); + //@formatter:on + } + }); + + HttpGet httpGet; + HttpResponse status; + String response; + + // Server + ourHitMethod = false; + ourReturn = Arrays.asList(createObservation(10, "Patient/2")); + httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + // Type + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + // Instance + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + // Wrong instance + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + } + + @Test + public void testOperationServerLevel() throws Exception { + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("RULE 1").operation().named("opName").onServer().andThen() + .build(); + //@formatter:on + } + }); + + HttpGet httpGet; + HttpResponse status; + String response; + + // Server + ourHitMethod = false; + ourReturn = Arrays.asList(createObservation(10, "Patient/2")); + httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); + status = ourClient.execute(httpGet); + extractResponseAndClose(status); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + // Type + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + // Instance + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + } + @Test + public void testOperationTypeLevel() throws Exception { + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("RULE 1").operation().named("opName").onType(Patient.class).andThen() + .build(); + //@formatter:on + } + }); + + HttpGet httpGet; + HttpResponse status; + String response; + + // Server + ourHitMethod = false; + ourReturn = Arrays.asList(createObservation(10, "Patient/2")); + httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + // Type + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + // Wrong type + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/1/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + // Wrong name + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName2"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + + // Instance + ourHitMethod = false; + ourReturn = Arrays.asList(createPatient(2)); + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName"); + status = ourClient.execute(httpGet); + response = extractResponseAndClose(status); + ourLog.info(response); + assertThat(response, containsString("Access denied by default policy")); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); + } + @Test public void testReadByAnyId() throws Exception { ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { @@ -689,6 +692,7 @@ public class AuthorizationInterceptorDstu2Test { } + @Test public void testReadByCompartmentWrong() throws Exception { ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { @@ -749,7 +753,6 @@ public class AuthorizationInterceptorDstu2Test { } - @Test public void testTransactionWriteGood() throws Exception { ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { @@ -803,14 +806,15 @@ public class AuthorizationInterceptorDstu2Test { HttpEntityEnclosingRequestBase httpPost; HttpResponse status; + String response; ourHitMethod = false; httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); httpPost.setEntity(createFhirResourceEntity(createPatient(null))); status = ourClient.execute(httpPost); - String response = extractResponseAndClose(status); - assertEquals(ERR403, response); + response = extractResponseAndClose(status); assertEquals(403, status.getStatusLine().getStatusCode()); + assertEquals(ERR403, response); assertFalse(ourHitMethod); // Conditional @@ -820,8 +824,8 @@ public class AuthorizationInterceptorDstu2Test { httpPost.setEntity(createFhirResourceEntity(createPatient(null))); status = ourClient.execute(httpPost); response = extractResponseAndClose(status); - assertEquals(ERR403, response); assertEquals(403, status.getStatusLine().getStatusCode()); + assertEquals(ERR403, response); assertFalse(ourHitMethod); ourHitMethod = false; @@ -829,8 +833,8 @@ public class AuthorizationInterceptorDstu2Test { httpPost.setEntity(createFhirResourceEntity(createObservation(null, "Patient/2"))); status = ourClient.execute(httpPost); response = extractResponseAndClose(status); - assertEquals(ERR403, response); assertEquals(403, status.getStatusLine().getStatusCode()); + assertEquals(ERR403, response); assertFalse(ourHitMethod); ourHitMethod = false; @@ -891,13 +895,14 @@ public class AuthorizationInterceptorDstu2Test { }); HttpEntityEnclosingRequestBase httpPost; + String response; HttpResponse status; ourHitMethod = false; httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient/2"); httpPost.setEntity(createFhirResourceEntity(createPatient(2))); status = ourClient.execute(httpPost); - String response = extractResponseAndClose(status); + response = extractResponseAndClose(status); assertEquals(ERR403, response); assertEquals(403, status.getStatusLine().getStatusCode()); assertFalse(ourHitMethod); @@ -907,7 +912,7 @@ public class AuthorizationInterceptorDstu2Test { httpPost.setEntity(createFhirResourceEntity(createPatient(1))); status = ourClient.execute(httpPost); extractResponseAndClose(status); - assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(200, status.getStatusLine().getStatusCode()); assertTrue(ourHitMethod); // Conditional @@ -918,7 +923,16 @@ public class AuthorizationInterceptorDstu2Test { response = extractResponseAndClose(status); assertEquals(ERR403, response); assertEquals(403, status.getStatusLine().getStatusCode()); - assertTrue(ourHitMethod); + assertFalse(ourHitMethod); + + ourHitMethod = false; + httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient?foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createPatient(99))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(ERR403, response); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertFalse(ourHitMethod); ourHitMethod = false; httpPost = new HttpPut("http://localhost:" + ourPort + "/Observation/10"); @@ -937,10 +951,184 @@ public class AuthorizationInterceptorDstu2Test { assertEquals(403, status.getStatusLine().getStatusCode()); assertFalse(ourHitMethod); } - + @Test + public void testWriteByCompartmentUpdateConditionalResolvesToInvalid() throws Exception { + ourConditionalCreateId = "1123"; + + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("Rule 1").write().resourcesOfType(Patient.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 2").write().resourcesOfType(Observation.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 3").updateConditional().resourcesOfType(Patient.class) + .build(); + //@formatter:on + } + }); + + HttpEntityEnclosingRequestBase httpPost; + HttpResponse status; + String response; + + ourHitMethod = false; + httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient?foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createPatient(null))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertEquals(ERR403, response); + assertTrue(ourHitMethod); + + } + + + @Test + public void testWriteByCompartmentUpdateConditionalResolvesToValid() throws Exception { + ourConditionalCreateId = "1"; + + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("Rule 1").write().resourcesOfType(Patient.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 2").write().resourcesOfType(Observation.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 3").updateConditional().resourcesOfType(Patient.class) + .build(); + //@formatter:on + } + }); + + HttpEntityEnclosingRequestBase httpPost; + HttpResponse status; + String response; + + ourHitMethod = false; + httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient?foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createPatient(null))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + ourHitMethod = false; + httpPost = new HttpPut("http://localhost:" + ourPort + "/Observation?foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createObservation(null, "Patient/12"))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertEquals(ERR403, response); + assertFalse(ourHitMethod); + + } + + @Test + public void testWriteByCompartmentCreateConditionalResolvesToValid() throws Exception { + ourConditionalCreateId = "1"; + + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("Rule 1").write().resourcesOfType(Patient.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 2").createConditional().resourcesOfType(Patient.class) + .build(); + //@formatter:on + } + }); + + HttpEntityEnclosingRequestBase httpPost; + HttpResponse status; + String response; + + ourHitMethod = false; + httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.addHeader(Constants.HEADER_IF_NONE_EXIST, "foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createPatient(null))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(201, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + } + + @Test + public void testWriteByCompartmentDeleteConditionalResolvesToValid() throws Exception { + ourConditionalCreateId = "1"; + + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("Rule 1").write().resourcesOfType(Patient.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 2").deleteConditional().resourcesOfType(Patient.class) + .build(); + //@formatter:on + } + }); + + HttpDelete httpDelete; + HttpResponse status; + String response; + + ourReturn = Arrays.asList(createPatient(1)); + + ourHitMethod = false; + httpDelete = new HttpDelete("http://localhost:" + ourPort + "/Patient?foo=bar"); + status = ourClient.execute(httpDelete); + response = extractResponseAndClose(status); + assertEquals(204, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + } + + @Test + public void testWriteByCompartmentUpdateConditionalResolvesToValidAllTypes() throws Exception { + ourConditionalCreateId = "1"; + + ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) { + @Override + public List buildRuleList(RequestDetails theRequestDetails) { + //@formatter:off + return new RuleBuilder() + .allow("Rule 1").write().resourcesOfType(Patient.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 2").write().resourcesOfType(Observation.class).inCompartment("Patient", new IdDt("Patient/1")).andThen() + .allow("Rule 3").updateConditional().allResources() + .build(); + //@formatter:on + } + }); + + HttpEntityEnclosingRequestBase httpPost; + HttpResponse status; + String response; + + ourHitMethod = false; + httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient?foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createPatient(null))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertTrue(ourHitMethod); + + ourHitMethod = false; + httpPost = new HttpPut("http://localhost:" + ourPort + "/Observation?foo=bar"); + httpPost.setEntity(createFhirResourceEntity(createObservation(null, "Patient/12"))); + status = ourClient.execute(httpPost); + response = extractResponseAndClose(status); + assertEquals(403, status.getStatusLine().getStatusCode()); + assertEquals(ERR403, response); + assertTrue(ourHitMethod); + + } + @AfterClass public static void afterClassClearContext() throws Exception { ourServer.stop(); @@ -977,7 +1165,7 @@ public class AuthorizationInterceptorDstu2Test { public static class DummyObservationResourceProvider implements IResourceProvider { @Create() - public MethodOutcome create(@ResourceParam Observation theResource) { + public MethodOutcome create(@ResourceParam Observation theResource, @ConditionalUrlParam String theConditionalUrl) { ourHitMethod = true; theResource.setId("Observation/1/_history/1"); MethodOutcome retVal = new MethodOutcome(); @@ -998,50 +1186,65 @@ public class AuthorizationInterceptorDstu2Test { return Observation.class; } - @Read(version = true) - public Observation read(@IdParam IdDt theId) { - ourHitMethod = true; - return (Observation) ourReturn.get(0); - } - - @Search() - public List search() { - ourHitMethod = true; - return ourReturn; - } - - @Update() - public MethodOutcome update(@IdParam IdDt theId, @ResourceParam Observation theResource) { - ourHitMethod = true; - theResource.setId(theId.withVersion("2")); - MethodOutcome retVal = new MethodOutcome(); - retVal.setCreated(true); - retVal.setResource(theResource); - return retVal; - } @Operation(name="opName", idempotent=true) public Parameters operation() { ourHitMethod = true; return (Parameters) new Parameters().setId("1"); } + @Operation(name="opName", idempotent=true) public Parameters operation(@IdParam IdDt theId) { ourHitMethod = true; return (Parameters) new Parameters().setId("1"); } + @Read(version = true) + public Observation read(@IdParam IdDt theId) { + ourHitMethod = true; + return (Observation) ourReturn.get(0); + } + @Search() + public List search() { + ourHitMethod = true; + return ourReturn; + } + @Update() + public MethodOutcome update(@IdParam IdDt theId, @ResourceParam Observation theResource, @ConditionalUrlParam String theConditionalUrl, RequestDetails theRequestDetails) { + ourHitMethod = true; + + if (isNotBlank(theConditionalUrl)) { + IdDt actual = new IdDt("Observation", ourConditionalCreateId); + ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, actual); + subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.UPDATE); + theResource.setId(actual); + } else { + ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, theResource); + subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.UPDATE); + theResource.setId(theId.withVersion("2")); + } + + MethodOutcome retVal = new MethodOutcome(); + retVal.setCreated(true); + retVal.setResource(theResource); + return retVal; + } + } - + public static class DummyPatientResourceProvider implements IResourceProvider { + @Create() public MethodOutcome create(@ResourceParam Patient theResource, @ConditionalUrlParam String theConditionalUrl, RequestDetails theRequestDetails) { if (isNotBlank(theConditionalUrl)) { - IdDt actual = new IdDt("Patient", "1123"); + IdDt actual = new IdDt("Patient", ourConditionalCreateId); ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, actual); subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.CREATE); + } else { + ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, theResource); + subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.CREATE); } ourHitMethod = true; @@ -1054,7 +1257,7 @@ public class AuthorizationInterceptorDstu2Test { @Delete() - public MethodOutcome delete(IRequestOperationCallback theRequestOperationCallback, @IdParam IdDt theId) { + public MethodOutcome delete(IRequestOperationCallback theRequestOperationCallback, @IdParam IdDt theId, @ConditionalUrlParam String theConditionalUrl, RequestDetails theRequestDetails) { ourHitMethod = true; for (IBaseResource next : ourReturn) { theRequestOperationCallback.resourceDeleted(next); @@ -1063,58 +1266,11 @@ public class AuthorizationInterceptorDstu2Test { return retVal; } - @Validate - public MethodOutcome validate(@ResourceParam Patient theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode, - @Validate.Profile String theProfile, RequestDetails theRequestDetails) { - ourHitMethod = true; - OperationOutcome oo = new OperationOutcome(); - oo.addIssue().setDiagnostics("OK"); - return new MethodOutcome(oo); - } - - @Validate - public MethodOutcome validate(@ResourceParam Patient theResource, @IdParam IdDt theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode, - @Validate.Profile String theProfile, RequestDetails theRequestDetails) { - ourHitMethod = true; - OperationOutcome oo = new OperationOutcome(); - oo.addIssue().setDiagnostics("OK"); - return new MethodOutcome(oo); - } - @Override public Class getResourceType() { return Patient.class; } - - @Read(version = true) - public Patient read(@IdParam IdDt theId) { - ourHitMethod = true; - return (Patient) ourReturn.get(0); - } - - @Search() - public List search() { - ourHitMethod = true; - return ourReturn; - } - - @Update() - public MethodOutcome update(@IdParam IdDt theId, @ResourceParam Patient theResource, @ConditionalUrlParam String theConditionalUrl, RequestDetails theRequestDetails) { - ourHitMethod = true; - - if (isNotBlank(theConditionalUrl)) { - IdDt actual = new IdDt("Patient", "1123"); - ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, actual); - subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.UPDATE); - } - theResource.setId(theId.withVersion("2")); - MethodOutcome retVal = new MethodOutcome(); - retVal.setCreated(true); - retVal.setResource(theResource); - return retVal; - } - @Operation(name="opName", idempotent=true) public Parameters operation() { ourHitMethod = true; @@ -1133,6 +1289,56 @@ public class AuthorizationInterceptorDstu2Test { return (Parameters) new Parameters().setId("1"); } + @Read(version = true) + public Patient read(@IdParam IdDt theId) { + ourHitMethod = true; + return (Patient) ourReturn.get(0); + } + + @Search() + public List search() { + ourHitMethod = true; + return ourReturn; + } + + @Update() + public MethodOutcome update(@IdParam IdDt theId, @ResourceParam Patient theResource, @ConditionalUrlParam String theConditionalUrl, RequestDetails theRequestDetails) { + ourHitMethod = true; + + if (isNotBlank(theConditionalUrl)) { + IdDt actual = new IdDt("Patient", ourConditionalCreateId); + ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, actual); + subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.UPDATE); + theResource.setId(actual); + } else { + ActionRequestDetails subRequest = new ActionRequestDetails(theRequestDetails, theResource); + subRequest.notifyIncomingRequestPreHandled(RestOperationTypeEnum.UPDATE); + theResource.setId(theId.withVersion("2")); + } + + MethodOutcome retVal = new MethodOutcome(); + retVal.setResource(theResource); + return retVal; + } + + @Validate + public MethodOutcome validate(@ResourceParam Patient theResource, @IdParam IdDt theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode, + @Validate.Profile String theProfile, RequestDetails theRequestDetails) { + ourHitMethod = true; + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setDiagnostics("OK"); + return new MethodOutcome(oo); + } + + @Validate + public MethodOutcome validate(@ResourceParam Patient theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode, + @Validate.Profile String theProfile, RequestDetails theRequestDetails) { + ourHitMethod = true; + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setDiagnostics("OK"); + return new MethodOutcome(oo); + } + } public static class PlainProvider diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/PatientWithCustomCompositeExtension.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/PatientWithCustomCompositeExtension.java new file mode 100644 index 00000000000..82ea6448407 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/PatientWithCustomCompositeExtension.java @@ -0,0 +1,82 @@ +package ca.uhn.fhir.parser; + +import org.hl7.fhir.dstu3.model.BackboneElement; +import org.hl7.fhir.dstu3.model.Patient; +import org.hl7.fhir.dstu3.model.StringType; + +import ca.uhn.fhir.model.api.annotation.Block; +import ca.uhn.fhir.model.api.annotation.Child; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.api.annotation.ResourceDef; +import ca.uhn.fhir.util.ElementUtil; + +@ResourceDef(name = "Patient") +public class PatientWithCustomCompositeExtension extends Patient { + + private static final long serialVersionUID = 1L; + + /** + * A custom extension + */ + @Child(name = "foo") + @Extension(url="http://acme.org/fooParent", definedLocally = false, isModifier = false) + protected FooParentExtension fooParentExtension; + + public FooParentExtension getFooParentExtension() { + return fooParentExtension; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(fooParentExtension); + } + + public void setFooParentExtension(FooParentExtension theFooParentExtension) { + fooParentExtension = theFooParentExtension; + } + + @Block + public static class FooParentExtension extends BackboneElement { + + private static final long serialVersionUID = 4522090347756045145L; + + @Child(name = "childA") + @Extension(url = "http://acme.org/fooChildA", definedLocally = false, isModifier = false) + private StringType myChildA; + + @Child(name = "childB") + @Extension(url = "http://acme.org/fooChildB", definedLocally = false, isModifier = false) + private StringType myChildB; + + @Override + public FooParentExtension copy() { + FooParentExtension copy = new FooParentExtension(); + copy.myChildA = myChildA; + copy.myChildB = myChildB; + return copy; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(myChildA, myChildB); + } + + public StringType getChildA() { + return myChildA; + } + + public StringType getChildB() { + return myChildB; + } + + public void setChildA(StringType theChildA) { + myChildA = theChildA; + } + + public void setChildB(StringType theChildB) { + myChildB = theChildB; + } + + } + +} \ No newline at end of file diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java index 3b186fa8719..b6535883644 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java @@ -4,6 +4,7 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.stringContainsInOrder; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -34,66 +35,21 @@ import org.custommonkey.xmlunit.XMLUnit; import org.hamcrest.collection.IsEmptyCollection; import org.hamcrest.core.StringContains; import org.hamcrest.text.StringContainsInOrder; +import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.Address.AddressUse; import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory; -import org.hl7.fhir.dstu3.model.AllergyIntolerance; -import org.hl7.fhir.dstu3.model.Annotation; -import org.hl7.fhir.dstu3.model.Appointment; -import org.hl7.fhir.dstu3.model.AuditEvent; -import org.hl7.fhir.dstu3.model.Binary; -import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleLinkComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleType; -import org.hl7.fhir.dstu3.model.CodeType; -import org.hl7.fhir.dstu3.model.CodeableConcept; -import org.hl7.fhir.dstu3.model.Coding; -import org.hl7.fhir.dstu3.model.Communication; -import org.hl7.fhir.dstu3.model.Composition; -import org.hl7.fhir.dstu3.model.ConceptMap; -import org.hl7.fhir.dstu3.model.Condition; import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem; -import org.hl7.fhir.dstu3.model.DataElement; -import org.hl7.fhir.dstu3.model.DateTimeType; -import org.hl7.fhir.dstu3.model.DateType; -import org.hl7.fhir.dstu3.model.DiagnosticReport; import org.hl7.fhir.dstu3.model.DiagnosticReport.DiagnosticReportStatus; -import org.hl7.fhir.dstu3.model.DocumentManifest; -import org.hl7.fhir.dstu3.model.Duration; -import org.hl7.fhir.dstu3.model.ElementDefinition; import org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionBindingComponent; -import org.hl7.fhir.dstu3.model.Encounter; -import org.hl7.fhir.dstu3.model.EnumFactory; -import org.hl7.fhir.dstu3.model.Enumeration; import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender; import org.hl7.fhir.dstu3.model.Enumerations.DocumentReferenceStatus; -import org.hl7.fhir.dstu3.model.Extension; -import org.hl7.fhir.dstu3.model.GuidanceResponse; -import org.hl7.fhir.dstu3.model.HumanName; import org.hl7.fhir.dstu3.model.HumanName.NameUse; -import org.hl7.fhir.dstu3.model.IdType; -import org.hl7.fhir.dstu3.model.Identifier; import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse; -import org.hl7.fhir.dstu3.model.InstantType; -import org.hl7.fhir.dstu3.model.Location; -import org.hl7.fhir.dstu3.model.Medication; -import org.hl7.fhir.dstu3.model.MedicationOrder; -import org.hl7.fhir.dstu3.model.MedicationStatement; -import org.hl7.fhir.dstu3.model.Observation; import org.hl7.fhir.dstu3.model.Observation.ObservationRelationshipType; import org.hl7.fhir.dstu3.model.Observation.ObservationStatus; -import org.hl7.fhir.dstu3.model.Organization; -import org.hl7.fhir.dstu3.model.Patient; -import org.hl7.fhir.dstu3.model.PrimitiveType; -import org.hl7.fhir.dstu3.model.ProcedureRequest; -import org.hl7.fhir.dstu3.model.Quantity; -import org.hl7.fhir.dstu3.model.Reference; -import org.hl7.fhir.dstu3.model.Resource; -import org.hl7.fhir.dstu3.model.SampledData; -import org.hl7.fhir.dstu3.model.SimpleQuantity; -import org.hl7.fhir.dstu3.model.StringType; -import org.hl7.fhir.dstu3.model.UriType; -import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.instance.model.api.IBaseResource; import org.junit.After; import org.junit.AfterClass; @@ -110,6 +66,7 @@ import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.parser.FooMessageHeaderWithExplicitField.FooMessageSourceComponent; import ca.uhn.fhir.parser.IParserErrorHandler.IParseLocation; +import ca.uhn.fhir.parser.PatientWithCustomCompositeExtension.FooParentExtension; import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.util.TestUtil; @@ -126,142 +83,6 @@ public class XmlParserDstu3Test { ourCtx.setNarrativeGenerator(null); } - @Test - public void testEncodeAndParseContainedCustomTypes() { - ourCtx = FhirContext.forDstu3(); - ourCtx.setDefaultTypeForProfile(CustomObservation.PROFILE, CustomObservation.class); - ourCtx.setDefaultTypeForProfile(CustomDiagnosticReport.PROFILE, CustomDiagnosticReport.class); - - CustomObservation obs = new CustomObservation(); - obs.setStatus(ObservationStatus.FINAL); - - CustomDiagnosticReport dr = new CustomDiagnosticReport(); - dr.setStatus(DiagnosticReportStatus.FINAL); - dr.addResult().setResource(obs); - - IParser parser = ourCtx.newXmlParser(); - parser.setPrettyPrint(true); - - String output = parser.encodeResourceToString(dr); - ourLog.info(output); - - //@formatter:off - assertThat(output,stringContainsInOrder( - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "")); - //@formatter:on - - /* - * Now PARSE! - */ - - dr = (CustomDiagnosticReport) parser.parseResource(output); - assertEquals(DiagnosticReportStatus.FINAL, dr.getStatus()); - - assertEquals("#1", dr.getResult().get(0).getReference()); - obs = (CustomObservation) dr.getResult().get(0).getResource(); - assertEquals(ObservationStatus.FINAL, obs.getStatus()); - - ourCtx = null; - } - - @Test - public void testEncodeAndParseContainedNonCustomTypes() { - ourCtx = FhirContext.forDstu3(); - - Observation obs = new Observation(); - obs.setStatus(ObservationStatus.FINAL); - - DiagnosticReport dr = new DiagnosticReport(); - dr.setStatus(DiagnosticReportStatus.FINAL); - dr.addResult().setResource(obs); - - IParser parser = ourCtx.newXmlParser(); - parser.setPrettyPrint(true); - - String output = parser.encodeResourceToString(dr); - ourLog.info(output); - - //@formatter:off - assertThat(output,stringContainsInOrder( - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "")); - //@formatter:on - - /* - * Now PARSE! - */ - - dr = (DiagnosticReport) parser.parseResource(output); - assertEquals(DiagnosticReportStatus.FINAL, dr.getStatus()); - - assertEquals("#1", dr.getResult().get(0).getReference()); - obs = (Observation) dr.getResult().get(0).getResource(); - assertEquals(ObservationStatus.FINAL, obs.getStatus()); - - ourCtx = null; - } - - @Test - public void testEncodeHistoryEncodeVersionsAtPath3() { - ourCtx = FhirContext.forDstu3(); - - assertNull(ourCtx.newXmlParser().getStripVersionsFromReferences()); - - AuditEvent auditEvent = new AuditEvent(); - auditEvent.addEntity().setReference(new Reference("http://foo.com/Organization/2/_history/1")); - - IParser parser = ourCtx.newXmlParser(); - - parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference"); - String enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); - ourLog.info(enc); - assertThat(enc, containsString("")); - - parser.setDontStripVersionsFromReferencesAtPaths(new ArrayList()); - enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); - ourLog.info(enc); - assertThat(enc, containsString("")); - - parser.setDontStripVersionsFromReferencesAtPaths((String[])null); - enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); - ourLog.info(enc); - assertThat(enc, containsString("")); - - parser.setDontStripVersionsFromReferencesAtPaths((List)null); - enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); - ourLog.info(enc); - assertThat(enc, containsString("")); - - } - - @Test public void testBundleWithBinary() { //@formatter:off @@ -292,7 +113,7 @@ public class XmlParserDstu3Test { assertArrayEquals(new byte[] { 1, 2, 3, 4 }, bin.getContent()); } - + @Test public void testContainedResourceInExtensionUndeclared() { Patient p = new Patient(); @@ -314,7 +135,7 @@ public class XmlParserDstu3Test { o = (Organization) rr.getResource(); assertEquals("ORG", o.getName()); } - + @Test public void testDuration() { Encounter enc = new Encounter(); @@ -328,7 +149,7 @@ public class XmlParserDstu3Test { assertThat(str, not(containsString("meta"))); assertThat(str, containsString("")); } - + @Test public void testEncodeAndParseBundleWithResourceRefs() { @@ -366,6 +187,24 @@ public class XmlParserDstu3Test { assertSame(org, pt.getManagingOrganization().getResource()); } + @Test + public void testEncodeAndParseCompositeExtension() { + PatientWithCustomCompositeExtension pat = new PatientWithCustomCompositeExtension(); + pat.setId("123"); + pat.setFooParentExtension(new FooParentExtension()); + pat.getFooParentExtension().setChildA(new StringType("ValueA")); + pat.getFooParentExtension().setChildB(new StringType("ValueB")); + + String enc = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(pat); + ourLog.info(enc); + + pat = ourCtx.newXmlParser().parseResource(PatientWithCustomCompositeExtension.class, enc); + + assertEquals("ValueA", pat.getFooParentExtension().getChildA().getValue()); + assertEquals("ValueB", pat.getFooParentExtension().getChildB().getValue()); + } + + @Test public void testEncodeAndParseContained() { IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true); @@ -435,6 +274,108 @@ public class XmlParserDstu3Test { } + @Test + public void testEncodeAndParseContainedCustomTypes() { + ourCtx = FhirContext.forDstu3(); + ourCtx.setDefaultTypeForProfile(CustomObservation.PROFILE, CustomObservation.class); + ourCtx.setDefaultTypeForProfile(CustomDiagnosticReport.PROFILE, CustomDiagnosticReport.class); + + CustomObservation obs = new CustomObservation(); + obs.setStatus(ObservationStatus.FINAL); + + CustomDiagnosticReport dr = new CustomDiagnosticReport(); + dr.setStatus(DiagnosticReportStatus.FINAL); + dr.addResult().setResource(obs); + + IParser parser = ourCtx.newXmlParser(); + parser.setPrettyPrint(true); + + String output = parser.encodeResourceToString(dr); + ourLog.info(output); + + //@formatter:off + assertThat(output,stringContainsInOrder( + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "")); + //@formatter:on + + /* + * Now PARSE! + */ + + dr = (CustomDiagnosticReport) parser.parseResource(output); + assertEquals(DiagnosticReportStatus.FINAL, dr.getStatus()); + + assertEquals("#1", dr.getResult().get(0).getReference()); + obs = (CustomObservation) dr.getResult().get(0).getResource(); + assertEquals(ObservationStatus.FINAL, obs.getStatus()); + + ourCtx = null; + } + + @Test + public void testEncodeAndParseContainedNonCustomTypes() { + ourCtx = FhirContext.forDstu3(); + + Observation obs = new Observation(); + obs.setStatus(ObservationStatus.FINAL); + + DiagnosticReport dr = new DiagnosticReport(); + dr.setStatus(DiagnosticReportStatus.FINAL); + dr.addResult().setResource(obs); + + IParser parser = ourCtx.newXmlParser(); + parser.setPrettyPrint(true); + + String output = parser.encodeResourceToString(dr); + ourLog.info(output); + + //@formatter:off + assertThat(output,stringContainsInOrder( + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "")); + //@formatter:on + + /* + * Now PARSE! + */ + + dr = (DiagnosticReport) parser.parseResource(output); + assertEquals(DiagnosticReportStatus.FINAL, dr.getStatus()); + + assertEquals("#1", dr.getResult().get(0).getReference()); + obs = (Observation) dr.getResult().get(0).getResource(); + assertEquals(ObservationStatus.FINAL, obs.getStatus()); + + ourCtx = null; + } + @Test public void testEncodeAndParseExtensionOnCode() { Organization o = new Organization(); @@ -1140,6 +1081,30 @@ public class XmlParserDstu3Test { ourLog.info(parser.encodeResourceToString(gr)); } + @Test + public void testEncodeDeclaredBlock() throws Exception { + FooMessageSourceComponent source = new FooMessageHeaderWithExplicitField.FooMessageSourceComponent(); + source.getMessageHeaderApplicationId().setValue("APPID"); + source.setName("NAME"); + + FooMessageHeaderWithExplicitField header = new FooMessageHeaderWithExplicitField(); + header.setSourceNew(source); + + header.addDestination().setName("DEST"); + + Bundle bundle = new Bundle(); + bundle.addEntry().setResource(header); + + IParser p = ourCtx.newXmlParser(); + p.setPrettyPrint(true); + + String encode = p.encodeResourceToString(bundle); + ourLog.info(encode); + + assertThat(encode, containsString("")); + assertThat(encode, stringContainsInOrder("")); + + parser.setDontStripVersionsFromReferencesAtPaths(new ArrayList()); + enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); + ourLog.info(enc); + assertThat(enc, containsString("")); + + parser.setDontStripVersionsFromReferencesAtPaths((String[])null); + enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); + ourLog.info(enc); + assertThat(enc, containsString("")); + + parser.setDontStripVersionsFromReferencesAtPaths((List)null); + enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent); + ourLog.info(enc); + assertThat(enc, containsString("")); + + } + @Test public void testEncodeNarrativeSuppressed() { Patient patient = new Patient(); @@ -1498,6 +1496,23 @@ public class XmlParserDstu3Test { assertThat(str, containsString("")); } + @Test + public void testEncodeReferenceWithUuid() { + + Practitioner pract = new Practitioner(); + pract.setId(IdType.newRandomUuid()); + pract.addName().addFamily("PRACT FAMILY"); + + Patient patient = new Patient(); + patient.addGeneralPractitioner().setResource(pract); + + String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient); + ourLog.info(encoded); + + assertThat(pract.getId(), startsWith("urn:uuid:")); + assertThat(encoded, containsString("")); + } + @Test public void testEncodeSummary() { Patient patient = new Patient(); @@ -1561,30 +1576,6 @@ public class XmlParserDstu3Test { assertThat(encode, stringContainsInOrder("")); - assertThat(encode, stringContainsInOrder(" + + Servers in STU3 mode will now ignore any ID or VersionID found in the + resource body provided by the client when processing FHIR + update]]> operations. This change has been made + because the FHIR specification now requires servers to ignore + these values. Note that as a result of this change, resources passed + to @Update]]> methods will always have + null]]> ID + + + Add new methods to + AuthorizationInterceptor]]> + which allow user code to declare support for conditional + create, update, and delete. + + + When encoding a resource with a reference to another resource + that has a placeholder ID (e.g. urn:uuid:foo), the urn prefix + was incorrectly stripped from the reference. + diff --git a/src/changes/changes_BACKUP_31097.xml b/src/changes/changes_BACKUP_31097.xml new file mode 100644 index 00000000000..86d406bf5b9 --- /dev/null +++ b/src/changes/changes_BACKUP_31097.xml @@ -0,0 +1,2804 @@ + + + + James Agnew + HAPI FHIR Changelog + + + + + JSON parsing in HAPI FHIR has been switched from using JSR353 (javax.json) to + using Google Gson. For this reason we are bumping the major release number to + 2.0. Theoretically this should not affect projects in any major way, but Gson + does have subtle differences. Two differences which popped up a fair bit in + our own testing: + +
    + A space is placed after the : in keys, e.g. what was previously + encoded as "resourceType":"Patient" is now encoded + as "resourceType": "Patient" (this broke a number of + our unit tests with hardcoded resource definitions) +
+
    + Trailing content after a valid json resource is rejected by + Gson (it was ignored by the Glassfish parser we were previously + using even though it was invalid) +
+ + ]]> +
+ + STU3 structure definitions have been updated to the + STU3 ballot candidate versions (1.5.0 - SVN 9395) + + + Both client and server now support the new Content Types decided in + FHIR #10199]]>. +
]]> + This means that the server now supports + application/fhir+xml and application/fhir+json]]> + in addition to the older style + application/xml+fhir and application/json+fhir]]>. + In order to facilitate migration by implementors, the old style remains the default + for now, but the server will respond using the new style if the request contains it. The + client now uses an Accept]]> header value which requests both + styles with a preference given to the new style when running in DSTU3 mode. +
]]> + As a part of this change, the server has also been enhanced so that if a request + contains a Content-Type header but no Accept header, the response will prefer the + encoding specified by the Content-Type header. +
+ + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Logback (used in sample projects): 1.1.5 -> 1.1.7
  • +
  • Phloc Commons (used by schematron validator): 4.4.4 -> 4.4.5
  • +
  • Commons-IO: 2.4 -> 2.5
  • +
  • Apache HTTPClient: 4.5.1 -> 4.5.2
  • +
  • Apache HTTPCore: 4.4.4 -> 4.4.5
  • +
  • Jersey (JAX-RS tests): 2.22.2 -> 2.23.1
  • +
  • Spring (JPA, Web Tester): 4.3.0 -> 4.3.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.4
  • + + ]]> +
    + + + Fix issue in DSTU1 Bundle parsing where unexpected elements in the bundle resulted in a failure + to parse. + + + DSTU2 QuestionnaireResponse validator failed with an exception if the + QuestionnaireResponse contained certain groups with no content + + + Fluent client should ignore parameter values which are null instead of including + them as ?foo=null]]> + + + When using _elements]]> parameter on server, the server was not + automatically adding the SUBSETTED]]> tag as it should + + + JPA server should now automatically detect + if Hibernate Search (Lucene) is configured to be + disabled and will not attempt to use it. This + prevents a crash for some operations. + + + A new server interceptor "BanUnsupprtedHttpMethodsInterceptor" has been added + which causes the server to return an HTTP 405 if an unsupported HTTP + verb is received from the client + + + Fix an issue where resource IDs were not correctly set when using + DSTU2 HL7org structures with the JAX-RS module. Thanks to Carlo Mion + for the pull request! + + + hapi-fhir-testpage-overlay project contained an unneccesary + dependency on hapi-fhir-jpaserver-base module, which resulted in + projects using the overlay having a large number of unnneded + JARs included + + + It is not possible to configure both the parser and the context to + preserve versions in resource references (default behaviour is to + strip versions from references). Thanks to GitHub user @cknaap + for the suggestion! + + + Tag#setCode(String)]]> did not actually set the code it was supposed to + set. Thanks to Tim Tschampel for reporting! + + + JPA server's /Bundle]]> endpoint cleared + the Bundle.entry.fullUrl]]> field on stored + bundles, resulting in invalid content being saved. Thanks to Mirjam + Baltus for reporting! + + + JPA server now returns HTTP 200 instead of HTTP 404 for + conditional deletes which did not find any matches, + per FHIR-I decision. + + + Client that declares explicitly that it is searching/reading/etc for + a custom type did not automatically parse into that type. + + + Allow servers to specify the authentication realm of their choosing when + throwing an AuthenticationException. Thanks to GitHub user @allanbrohansen + for the suggestion! + + + Add a new client implementation which uses the + OkHttp]]> + library as the HTTP client implementation (instead of Apache HttpClient). + This is particularly useful for Android (where HttpClient is a pain) but + could also be useful in other places too. + Thanks to Matt Clarke of Orion Health for the contribution! + + + Fix a regression when parsing resources that have contained + resources, where the reference in the outer resource which + links to the contained resource sometimes did does not get + populated with the actual target resource instance. Thanks to + Neal Acharya for reporting! + + + hapi-fhir-cli upload-terminology command now has an argument + "-b FOO" that lets you add an authorization header in the form + Authorization: Bearer FOO]]> + + + Parser failed to successfully encode a custom resource + if it contained custom fields that also used custom + types. Thanks to GitHub user @sjanic for reporting! + + +<<<<<<< HEAD + Inprove handling of _text and _content searches in JPA server to do better + matching on partial strings +======= + Servers in STU3 mode will now ignore any ID or VersionID found in the + resource body provided by the client when processing FHIR + update]]> operations. This change has been made + because the FHIR specification now requires servers to ignore + these values. Note that as a result of this change, resources passed + to @Update]]> methods will always have + null]]> ID + + + Add new methods to + AuthorizationInterceptor]]> + which allow user code to declare support for conditional + create, update, and delete. + + + When encoding a resource with a reference to another resource + that has a placeholder ID (e.g. urn:uuid:foo), the urn prefix + was incorrectly stripped from the reference. +>>>>>>> da8abca1ffdaa4dcae3d931b2e4732e437951cac + +
    + + + Performance has been improved for the initial FhirContext + object creation by avoiding a lot of unnecessary reflection. HAPI FHIR + 1.5 had a regression compared to previous releases + and this has been corrected, but other improvements have been + made so that this release is faster than previous releases too. +
    ]]> + In addition, a new "deferred scan" mode has been implemented for + even faster initialization on slower environments (e.g. Android). + See the performance documentation]]> + for more information. +
    ]]> + The following shows our benchmarks for context initialization across several + versions of HAPI: + +
  • Version 1.4: 560ms
  • +
  • Version 1.5: 800ms
  • +
  • Version 1.6: 340ms
  • +
  • Version 1.6 (deferred mode): 240ms
  • + + ]]> +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Spring (JPA, Web Tester): 4.2.5 -> 4.3.0
  • +
  • Spring-Data (JPA): 1.9.2 -> 1.10.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.3
  • +
  • Jetty (CLI): 9.3.9 -> 9.3.10
  • + + ]]> +
    + + Remove some clases that were deprecated over a year ago and have + suitable replacements: + +
  • QualifiedDateParam has been removed, but DateParam may be used instead
  • +
  • PathSpecification has been removedm but Include may be used instead
  • + + ]]> +
    + + ResponseValidatingInterceptor threw an InternalErrorException (HTTP 500) for operations + that do not return any content (e.g. delete). Thanks to Mohammad Jafari for reporting! + + + REST server now throws an HTTP 400 instead of an HTTP 500 if an operation which takes + a FHIR resource in the request body (e.g. create, update) contains invalid content that + the parser is unable to parse. Thanks to Jim Steel for the suggestion! + + + Deprecate fluent client search operations without an explicit declaration of the + bundle type being used. This also means that in a client + .search()]]> + operation, the + .returnBundle(Bundle.class)]]> + needs to be the last statement before + .execute()]]> + + + Server now respects the parameter _format=application/xml+fhir"]]> + which is technically invalid since the + should be escaped, but is likely to be used. Also, + a parameter of _format=html]]> can now be used, which + forces SyntaxHighlightingInterceptor to use HTML even + if the headers wouldn't otherwise trigger it. + Thanks to Jim Steel for reporting! + + + Improve performance when parsing large bundles by fixing a loop over all of the + entries inthe bundle to stitch together cross-references, which was happening once + per entry instead of once overall. Thanks to Erick on the HAPI FHIR Google Group for + noticing that this was an issue! + + + JSON parser no longer allows the resource ID to be specified in an element called "_id" + (the correct one is "id"). Previously _id was allowed because some early FHIR examples + used that form, but this was never actually valid so it is now being removed. + + + JPA server now allows "forced IDs" (ids containing non-numeric, client assigned IDs) + to use the same logical ID part on different resource types. E.g. A server may now have + both Patient/foo and Obervation/foo on the same server.
    ]]> + Note that existing databases will need to modify index "IDX_FORCEDID" as + it is no longer unique, and perform a reindexing pass. +
    + + When serializing/encoding custom types which replace exsting choice fields by + fixing the choice to a single type, the parser would forget that the + field was a choice and would use the wrong name (e.g. "abatement" instead of + "abatementDateType"). Thanks to Yaroslav Kovbas for reporting and + providing a unit test! + + + JPA server transactions sometimes created an incorrect resource reference + if a resource being saved contained references that had a display value but + not an actual reference. Thanks to David Hay for reporting! + + + When performing a REST Client create or update with + Prefer: return=representation]]> set, + if the server does not honour the Prefer header, the client + will automatically fetch the resource before returning. Thanks + to Ewout Kramer for the idea! + + + DSTU3 structures now have + setFoo(List)]]> + and + setGetFooFirstRep()]]> + methods, bringing them back to parity with the HAPI + DSTU2 structures. Thanks to Rahul Somasunderam and + Claude Nanjo for the suggestions! + + + JPA server has now been refactored to use the + new FluentPath search parameter definitions + for DSTU3 resources. + + + RequestValidatingInterceptor and ResponseValidatingInterceptor + both have new method setIgnoreValidatorExceptions]]> + which causes validator exceptions to be ignored, rather than causing + processing to be aborted. + + + LoggingInterceptor on server has a new parameter + ${requestBodyFhir}]]> which logs the entire request body. + + + JAX-RS server module now supports DSTU3 resources (previously it only supported DSTU2). Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Generated conformance statements for DSTU3 servers did not properly reference their + OperationDefinitions. Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Properly handle null arrays when parsing JSON resources. Thanks to Subhro for + fixing this and providing a pull request! + + + STU3 validator failed to validate codes where the + code was a child code within the code system that contained it + (i.e. not a top level code). Thanks to Jon + Zammit for reporting! + + + Restore the setType method in the DSTU1 Bundle + class, as it was accidentally commented out. Thanks + to GitHub user @Virdulys for the pull request! + + + JPA server now supports composite search parameters + where the type of the composite parameter is + a quantity (e.g. Observation:component-code-component-value-quantity) + + + Remove the Remittance resource from DSTU2 + structures, as it is not a real resource and + was causing issues with interoperability + with the .NET client. + + + CLI tool cache feature (-c) for upload-example task sometimes failed + to write cache file and exited with an exception. + + + Fix error message in web testing UI when loading pages in a search + result for STU3 endpoints. + + + When encoding JSON resource, the parser will now always + ensure that XHTML narrative content has an + XHTML namespace declaration on the first + DIV tag. This was preventing validation for + some resources using the official validator + rules. + + + Server failed to invoke operations when the name + was escaped (%24execute instead of $execute). + Thanks to Michael Lawley for reporting! + + + JPA server transactions containing a bundle that has multiple entries + trying to delete the same resource caused a 500 internal error + + + JPA module failed to index search parameters that mapped to a Timing datatype, + e.g. CarePlan:activitydate + + + Add a new option to the CLI run-server command called --lowmem]]>. + This option disables some features (e.g. fulltext search) in order to allow the + server to start in memory-constrained environments (e.g Raspberry Pi) + + + When updating a resource via an update operation on the server, if the ID of the + resource is not present in the resource body but is present on the URL, this will + now be treated as a warning instead of as a failure in order to be a bit more + tolerant of errors. If the ID is present in the body but does not agree with the + ID in the URL this remains an error. + + + Server / JPA server date range search params (e.g. Encounter:date) now treat + a single date with no comparator (or the eq comparator) as requiring that the + value be completely contained by the range specified. Thanks to Chris Moesel + for the suggestion. + + + In server, if a parameter was annotated with the annotation, the + count would not appear in the self/prev/next links and would not actually be applied + to the search results by the server. Thanks to Jim Steele for letting us know! + + + Conditional update on server failed to process if the conditional URL did not have any + search parameters that did not start with an underscore. E.g. "Patient?_id=1" failed + even though this is a valid conditional reference. + + + JPA server can now be configured to allow external references (i.e. references that + point to resources on other servers). See + JPA Documentation]]> for information on + how to use this. Thanks to Naminder Soorma for the suggestion! + + + When posting a resource to a server that contains an invalid value in a boolean field + (e.g. Patient with an active value of "1") the server should return an HTTP 400, not + an HTTP 500. Thanks to Jim Steel for reporting! + + + Enable parsers to parse and serialize custom resources that contain custom datatypes. + An example has been added which shows how to do this + here]]> + + + JSON parser was incorrectly encoding resource language attribute in JSON as an + array instead of a string. Thanks to David Hay for reporting! + + + Sébastien Rivière contributed an excellent pull request which adds a + number of enhancements to JAX-RS module: + +
  • Enable the conditional update and delete
  • +
  • Creation of a bundle provider, and support of the @Transaction
  • +
  • Bug fix on the exceptions handling as some exceptions throw outside bean context were not intercept.
  • +
  • Add the possibility to have the stacktrace in the jaxrsException
  • + + ]]> +
    + + FhirTerser.cloneInto method failed to clone correctly if the source + had any extensions. Thanks to GitHub user @Virdulys for submitting and + providing a test case! + + + Update DSTU2 InstanceValidator to latest version from upstream + + + Web Testing UI was not able to correctly post an STU3 transaction + + + DateTime parser incorrectly parsed times where more than 3 digits of + precision were provided on the seconds after the decimal point + + + Improve error messages when the $validate operation is called but no resource + is actually supplied to validate + + + DSTU2+ servers no longer return the Category header, as this has been + removed from the FHIR specification (and tags are now available in the + resource body so the header was duplication/wasted bandwidth) + + + Create and Update operations in server did not + include ETag or Last-Modified headers even though + the spec says they should. Thanks to Jim Steel for + reporting! + + + Update STU3 client and server to use the new sort parameter style (param1,-param2,param). Thanks to GitHub user @euz1e4r for + reporting! + + + QuantityClientParam#withUnit(String) put the unit into the system part of the + parameter value + + + Fluent client searches with date parameters were not correctly using + new prefix style (e.g. gt) instead of old one (e.g. >) + + + Some built-in v3 code systems for STU3 resources were missing + certain codes, which caused false failures when validating + resources. Thanks to GitHub user @Xoude for reporting! + + + Some methods on DSTU2 model structures have JavaDocs that + incorrectly claim that the method will not return null when + in fact it can. Thanks to Rick Riemer for reporting! + + + ResponseHighlightingInterceptor has been modified based on consensus + on Zulip with Grahame that requests that have a parameter of + _format=json]]> or + _format=xml]]> will output raw FHIR content + instead of HTML highlighting the content as they previously did. + HTML content can now be forced via the (previously existing) + _format=html]]> or via the two newly added + values + _format=html/json]]> and + _format=html/xml]]>. Because of this + change, the custom + _raw=true]]> mode has been deprecated and + will be removed at some point. + + + Operation definitions (e.g. for $everything operation) in the generated + server conformance statement should not include the $ prefix in the operation + name or code. Thanks to Dion McMurtrie for reporting! + + + Server generated OperationDefinition resources did not validate + due to some missing elements (kind, status, etc.). + Thanks to + Michael Lawley for reporting! + + + Operations that are defined on multiple resource provider types with + the same name (e.g. "$everything") are now automatically exposed by the server + as separate OperationDefinition resources per resource type. Thanks to + Michael Lawley for reporting! + + + OperationDefinition resources generated automatically by the server for operations + that are defined within resource/plain providers incorrectly stated that + the maximum cardinality was "*" for non-collection types with no explicit + maximum stated, which is not the behaviour that the JavaDoc on the + annotation describes. Thanks to Michael Lawley + for reporting! + + + Server parameters annotated with + @Since]]> + or + @Count]]> + which are of a FHIR type such as IntegerDt or DateTimeType will + now be set to null if the client's URL does not + contain this parameter. Previously they would be populated + with an empty instance of the FHIR type, which was inconsistent with + the way other server parameters worked. + + + Server now supports the _at parameter (including multiple repetitions) + for history operation + + + + AuthorizationInterceptor can now allow or deny requests to extended + operations (e.g. $everything) + + + DecimalType used BigDecimal constructor instead of valueOf method to + create a BigDecimal from a double, resulting in weird floating point + conversions. Thanks to Craig McClendon for reporting! + + + Remove the depdendency on a method from commons-lang3 3.3 which was + causing issues on some Android phones which come with an older version + of this library bundled. Thanks to Paolo Perliti for reporting! + + + Parser is now better able to handle encoding fields which have been + populated with a class that extends the expected class + + + When declaring a child with + order=Child.REPLACE_PARENT]]> + the serialized form still put the element at the + end of the resource instead of in the correct + order + + + Fix STU3 JPA resource providers to allow validate operation + at instance level + +
    + + + Security Fix: XML parser was vulnerable to XXE (XML External Entity) + processing, which could result in local files on disk being disclosed. + See this page]]> + for more information. + Thanks to Jim Steel for reporting! + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.7 -> 5.1.0
  • +
  • Spring (JPA, Web Tester): 4.2.4 -> 4.2.5
  • +
  • SLF4j (All): 1.7.14 -> 1.7.21
  • + + ]]> +
    + + Support comments when parsing and encoding both JSON and XML. Comments are retrieved + and added to the newly created methods + IBase#getFormatCommentsPre() and + IBase#getFormatCommentsPost() + + + Added options to the CLI upload-examples command which allow it to cache + the downloaded content file, or use an arbitrary one. Thanks to Adam Carbone + for the pull request! + + + REST search parameters with a prefix/comparator had not been updated to use + the DSTU2 style prefixes (gt2011-01-10) instead of the DSTU1 style prefixes + (>2011-01-01). The client has been updated so that it uses the new prefixes + if the client has a DSTU2+ context. The server has been updated so that it now + supports both styles. +
    ]]> + As a part of this change, a new enum called + ParamPrefixEnum]]> + has been introduced. This enum replaces the old + QuantityCompararatorEnum]]> + which has a typo in its name and can not represent several new prefixes added since + DSTU1. +
    + + JPA server number and quantity search params now follow the rules for the + use of precision in search terms outlined in the + search page]]> of the + FHIR specification. For example, previously a 1% tolerance was applied for + all searches (10% for approximate search). Now, a tolerance which respects the + precision of the search term is used (but still 10% for approximate search). + + + Fix a failure starting the REST server if a method returns an untyped List, which + among other things prevented resource provider added to the server + as CDI beans in a JBoss enviroment. Thanks to GitHub user fw060 (Fei) for + reporting and figuring out exactly why this wasn't working! + + + JPA server now supports :above and :below qualifiers on URI search params + + + Add optional support (disabled by default for now) to JPA server to support + inline references containing search URLs. These URLs will be resolved when + a resource is being created/updated and replaced with the single matching + resource. This is being used as a part of the May 2016 Connectathon for + a testing scenario. + + + The server no longer adds a + WWW-Authenticate]]> + header to the response if any resource provider code throws an + AuthenticationException]]>. This header is + used for interactive authentication, which isn't generally + appropriate for FHIR. We added code to add this header a long time + ago for testing purposes and it never got removed. Please let us + know if you need the ability to add this header automatically. Thanks + to Lars Kristian Roland for pointing this out. + + + In the client, the create/update operations on a Binary resource + (which use the raw binary's content type as opposed to the FHIR + content type) were not including any request headers (Content-Type, + User-Agent, etc.) Thanks to Peter Van Houte of Agfa Healthcare for + reporting! + + + Handling of Binary resources containing embedded FHIR resources for + create/update/etc operations has been corrected per the FHIR rules + outlined at + Binary Resource]]> + in both the client and server. +
    ]]> + Essentially, if the Binary contains something + that isn't FHIR (e.g. an image with an image content-type) the + client will send the raw data with the image content type to the server. The + server will place the content type and raw data into a Binary resource instance + and pass those to the resource provider. This part was already correct previous + to 1.5. +
    ]]> + On the other hand, if the Binary contains a FHIR content type, the Binary + is now sent by the client to the server as a Binary resource with a FHIR content-type, + and the embedded FHIR content is contained in the appropriate fields. The server + will pass this "outer" Binary resource to the resource provider code. +
    + + The RequestDetails and ActionRequestDetails objects which are passed to + server interceptor methods and may also be used as server provider method + arguments now has a new method + Map<String, String> getUserData() + ]]> + which can be used to pass data and objects between interceptor methods to + to providers. This can be useful, for instance, if an authorization + interceptor wants to pass the logged in user's details to other parts + of the server. + + + IServerInterceptor#incomingRequestPreHandled() is called + for a @Validate method, the resource was not populated in the + ActionRequestDetails argument. Thanks to Ravi Kuchi for reporting! + ]]> + + + [baseUrl]/metadata with an HTTP method + other than GET (e.g. POST, PUT) should result in an HTTP 405. Thanks to + Michael Lawley for reporting! + ]]> + + + Fix a server exception when trying to automatically add the profile tag + to a resource which already has one or more profiles set. Thanks to + Magnus Vinther for reporting! + + + QuantityParam parameters being used in the RESTful server were ignoring + the + :missing]]> + qualifier. Thanks to Alexander Takacs for reporting! + + + Annotation client failed with an exception if the response contained + extensions on fields in the resonse Bundle (e.g. Bundle.entry.search). + Thanks to GitHub user am202 for reporting! + + + Primitive elements with no value but an extension were sometimes not + encoded correctly in XML, and sometimes not parsed correctly in JSON. + Thanks to Bill de Beaubien for reporting! + + + The Web Testing UI has long had an issue where if you click on a button which + navigates to a new page (e.g. search, read, etc) and then click the back button + to return to the original page, the button you clicked remains disabled and can't + be clicked again (on Firefox and Safari). This is now fixed. Unfortunately the fix means that the + buttom will no longer show a "loading" spinner, but there doesn't seem to + be another way of fixing this. Thanks to Mark Scrimshire for reporting! + + + Extensions found while parsing an object that doesn't support extensions are now + reported using the IParserErrorHandler framework in the same way that + other similar errors are handled. This allows the parser to be more lenient + when needed. + + + Improve error message if incorrect type is placed in a list field in the data model. Java + uses generics to prevent this at compile time, but if someone is in an environment without + generics this helps improve the error message at runtime. Thanks to Hugo Soares for + suggesting. + + + Prevent an unneeded warning when parsing a resource containing + a declared extension. Thanks to Matt Blanchette for reporting! + + + Web Tester UI did not invoke VRead even if a version ID was specified. Thanks + to Poseidon for reporting! + + + Per discussion on the FHIR implementer chat, the JPA server no + longer includes _revinclude matches in the Bundle.total count, or the + page size limit. + + + JPA server now persists search results to the database in a new table where they + can be temporaily preserved. This makes the JPA server much more scalable, since it + no longer needs to store large lists of pages in memory between search invocations. +
    ]]> + Old searches are deleted after an hour by default, but this can be changed + via a setting in the DaoConfig. +
    + + JPA servers' resource version history mechanism + has been adjusted so that the history table + keeps a record of all versions including the + current version. This has the very helpful + side effect that history no longer needs to be + paged into memory as a complete set. Previously + history had a hard limit of only being able to + page the most recent 20000 entries. Now it has + no limit. + + + JPA server returned the wrong Bundle.type value (COLLECTION, should be SEARCHSET) + for $everything operation responses. Thanks to Sonali Somase for reporting! + + + REST and JPA server should reject update requests where the resource body does not + contain an ID, or contains an ID which does not match the URL. Previously these + were accepted (the URL ID was trusted) which is incorrect according to the + FHIR specification. Thanks to GitHub user ametke for reporting! +
    ]]> + As a part of this change, server error messages were also improved for + requests where the URL does not contain an ID but needs to (e.g. for + an update) or contains an ID but shouldn't (e.g. for a create) +
    + + When fields of type BoundCodeDt (e.g. Patient.gender) + are serialized and deserialized using Java's native + object serialization, the enum binder was not + serialized too. This meant that values for the + field in the deserialized object could not be + modified. Thanks to Thomas Andersen for reporting! + + + REST Server responded to HTTP OPTIONS requests with + any URI as being a request for the server's + Conformance statement. This is incorrect, as only + a request for OPTIONS [base url]]]> should be treated as such. Thanks to Michael Lawley for reporting! + + + REST annotation style client was not able to handle extended operations + ($foo) where the response from the server was a raw resource instead + of a Parameters resource. Thanks to Andrew Michael Martin for reporting! + + + JPA server applies _lastUpdated filter inline with other searches wherever possible + instead of applying this filter as a second query against the results of the + first query. This should improve performance when searching against large + datasets. + + + Parsers have new method + setDontEncodeElements]]> + which can be used to force the parser to not encode certain elements + in a resource when serializing. For example this can be used to omit + sensitive data or skip the resource metadata. + + + JPA server database design has been adjusted + so that different tables use different sequences + to generate their indexes, resulting in more sequential + resource IDs being assigned by the server + + + Server now correctly serves up Binary resources + using their native content type (instead of as a + FHIR resource) if the request contains an accept + header containing "application/xml" as some browsers + do. + + + DSTU2 resources now have a + getMeta()]]> method which returns a + modifiable view of the resource metadata for convenience. This + matches the equivalent method in the DSTU3 structures. + + + Add a new method to FhirContext called + setDefaultTypeForProfile + ]]> + which can be used to specify that when recources are received which declare + support for specific profiles, a specific custom structures should be used + instead of the default. For example, if you have created a custom Observation + class for a specific profile, you could use this method to cause your custom + type to be used by the parser for resources in a search bundle you receive. +
    + See the documentation page on + Profiles and Extensions + for more information. + ]]> +
    + + Parsing/Encoding a custom resource type which extends a + base type sometimes caused the FhirContext to treat all future + parses of the same resource as using the custom type even when + this was not wanted. +
    ]]> + Custom structures may now be explicitly declared by profile + using the + setDefaultTypeForProfile + ]]> + method. +
    ]]> + This issue was discovered and fixed as a part of the implementation of issue #315. +
    + + Set up the tinder plugin to work as an ant task + as well as a Maven plugin, and to use external + sources. Thanks to Bill Denton for the pull + request! + + + JPA server now allows searching by token + parameter using a system only and no code, + giving a search for any tokens which match + the given token with any code. Previously the + expected behaviour for this search + was not clear in the spec and HAPI had different + behaviour from the other reference servers. + + + Introduce a JAX-RS client provider which can be used instead of the + default Apache HTTP Client provider to provide low level HTTP + services to HAPI's REST client. See + JAX-RS & Alternate HTTP Client Providers]]> + for more information. +
    ]]> + This is useful in cases where you have other non-FHIR REST clients + using a JAX-RS provider and want to take advantage of the + rest of the framework. +
    ]]> + Thanks to Peter Van Houte from Agfa for the amazing work! +
    + + Parser failed with a NPE while encoding resources if the + resource contained a null extension. Thanks to + steve1medix for reporting! + + + In generated model classes (DSTU1/2) don't + use BoundCodeDt and BoundCodeableConceptDt for + coded fields which use example bindings. Thanks + to GitHub user Ricq for reporting! + + + @Operation will now infer the maximum number of repetitions + of their parameters by the type of the parameter. Previously if + a default max() value was not specified in the + @OperationParam annotation on a parameter, the maximum + was assumed to be 1. Now, if a max value is not explicitly specified + and the type of the parameter is a basic type (e.g. StringDt) the + max will be 1. If the parameter is a collection type (e.g. List<StringDt>) + the max will be * + ]]> + + + @Operation + may now use search parameter types, such as + TokenParam and + TokenAndListParam as values. Thanks to + Christian Ohr for reporting! + ]]> + + + Add databases indexes to JPA module search index tables + for the RES_ID column on each. This should help + performance when searching over large datasets. + Thanks to Emmanuel Duviviers for the suggestion! + + + DateTimeType should fail to parse 1974-12-25+10:00 as this is not + a valid time in FHIR. Thanks to Grahame Grieve for reporting! + + + When parsing a Bundle resource, if the Bundle.entry.request.url contains a UUID + but the resource body has no ID, the Resource.id will be populated with the ID from the + Bundle.entry.request.url. This is helpful when round tripping Bundles containing + UUIDs. + + + When parsing a DSTU3 bundle, references between resources did not have + the actual resource instance populated into the reference if the + IDs matched as they did in DSTU1/2. + + + Contained resource references on DSTU3 + resources were not serialized correctly when + using the Json Parser. Thanks to GitHub user + @fw060 for reporting and supplying a patch + which corrects the issue! + + + DSTU3 model classes equalsShallow and equalsDeep both did not work + correctly if a field was null in one object, but contained an empty + object in the other (e.g. a StringType with no actual value in it). These + two should be considered equal, since they would produce the exact same + wire format.
    ]]> + Thanks to GitHub user @ipropper for reporting and providing + a test case! +
    + + JPA server now supports searching for _tag:not=[tag]]]> + which enables finding resources that to not have a given tag/profile/security tag. + Thanks to Lars Kristian Roland for the suggestion! + + + Extensions containing resource references did not get encoded correctly + some of the time. Thanks to Poseidon for reporting! + + + Parsers (both XML and JSON) encoded the first few elements of DSTU3 structures in the wrong order: + Extensions were placed before any other content, which is incorrect (several + elements come first: meta, text, etc.) + + + In server implementations, the Bundle.entry.fullUrl was not getting correctly + populated on Hl7OrgDstu2 servers. Thanks to Christian Ohr for reporting! + + + Ensure that element IDs within resources (i.e. IDs on elements other than the + resource itself) get serialized and parsed correctly. Previously, these didn't get + serialized in a bunch of circumstances. Thanks to Vadim Peretokin for reporting + and providing test cases! + + + Improve CLI error message if the tool can't bind to the requested port. Thanks + to Claude Nanjo for the suggestion! + + + Server param of _summary=text]]> did not + include mandatory elements in return as well as + the text element, even though the FHIR specification + required it. + + + Remove invalid resource type "Documentation" from DSTU2 + structures. + + + JPA server did not respect target types for search parameters. E.g. Appointment:patient has + a path of "Appointment.participant.actor" and a target type of "Patient". The search path + was being correctly handled, but the target type was being ignored. + + + RestfulServer now manually parses URL parameters instead of relying on the container's + parsed parameters. This is useful because many Java servlet containers (e.g. Tomcat, Glassfish) + default to ISO-8859-1 encoding for URLs insetad of the UTF-8 encoding specified by + FHIR. + + + ResponseHighlightingInterceptor now doesn't highlight if the request + has an Origin header, since this probably denotes an AJAX request. + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.3 -> 5.0.7
  • +
  • Springframework (JPA, Web Tester): 4.2.2 -> 4.2.4
  • +
  • Phloc-Commons (Schematron Validator): 4.3.6 -> 4.4.4
  • +
  • Apache httpclient (Client): 4.4 -> 4.5.1
  • +
  • Apache httpcore (Client): 4.4 -> 4.4.4
  • +
  • SLF4j (All): 1.7.13 -> 1.7.14
  • + + ]]> +
    + + Remove a dependency on a Java 1.7 class + (ReflectiveOperationException) in several spots in the + codebase. This dependency was accidentally introduced in + 1.3, and animal-sniffer-plugin failed to detect it (sigh). + + + Add two new server interceptors: + RequestValidatingInterceptor + and + ResponseValidatingInterceptor + ]]> + which can be used to validate incoming requests or outgoing responses using the standard FHIR validation + tools. See the + Server Validation Page + ]]> + for examples of how to use these interceptors. These intereptors have both + been enabled on the + public test page. + ]]> + + + Make IBoundCodeableConcept and IValueSetEnumBinder serializable, + fixing an issue when trying to serialize model classes containing + bound codes. Thanks to Nick Peterson for the Pull Request! + + + Introduce a JAX-RS version of the REST server, which can be used + to deploy the same resource provider implementations which work + on the existing REST server into a JAX-RS (e.g. Jersey) environment. + Thanks to Peter Van Houte from Agfa for the amazing work! + + + CLI now supports writing to file:// URL for 'upload-examples' command + + + GZipped content is now supported for client-to-server uploads (create, update, transaction, etc.). + The server will not automatically detect compressed incoming content and decompress it (this can be + disabled using a RestfulServer configuration setting). A new client interceptor has been added + which compresses outgoing content from the client. + + + JPA server transaction attempted to validate resources twice each, + with one of these times being before anything had been committed to the + database. This meant that if a transaction contained both a Questionnaire + and a QuestionnaireResponse, it would fail because the QuestionnaireResponse + validator wouldn't be able to find the questionnaire. This is now corrected. + + + Add a new method to the generic/fluent client for searching: + .count(int)
    ]]> + This replaces the existing ".limitTo(int)" method which has + now been deprocated because it was badly named and undocumented. +
    + + Profile validator has been configured to allow extensions even if they + aren't explicitly declared in the profile. + + + Add a constraint that the Maven build will only run in JDK 8+. HAPI + remains committed to supporting JDK 6+ in the compiled library, but these + days it can only be built using JDK 8. Thanks to joelsch for the PR! + + + When serializing a value[x] field, if the value type was a profiled type (e.g. markdown is a + profile of string) HAPI 1.3 would use the base type in the element name, e.g. + valueString instead of valueMarkdown. After discussion with Grahame, this appears to + be incorrect behaviour so it has been fixed. + + + Support target parameter type in _include / _revinclude values, e.g. + _include=Patient:careProvider:Organization. Thanks to Joe Portner + for reporting! + + + Use ResponseHighlighterInterceptor in the hapi-fhir-jpaserver-example + project to provide nice syntax highlighting. Thanks to Rob Hausam for + noting that this wasn't there. + + + Introduce custom @CoverageIgnore annotation to hapi-fhir-base in order to + remove dependency on cobertura during build and in runtime. + + + Server-generated conformance statements incorrectly used /Profile/ instead + of /StructureDefinition/ in URL links to structures. + + + JsonParser has been changed so that when serializing numbers it will use + plain format (0.001) instead of scientific format (1e-3). The latter is + valid JSON, and the parser will still correctly parse either format (all + clients should be prepared to) but this change makes serialized + resources appear more consistent between XML and JSON. As a result of this + change, trailing zeros will now be preserved when serializing as well. + + + Add DSTU3 example to hapi-fhir-jpaserver-example. Thanks to Karl + Davis for the Pull Request! + + + RestfulServer#setUseBrowserFriendlyContentTypes has been deprecated and its + functionality removed. The intention of this feature was that if it + detected a request coming in from a browser, it would serve up JSON/XML + using content types that caused the browsers to pretty print. But + each browser has different rules for when to pretty print, and + after we wrote that feature both Chrome and FF changed their rules to break it anyhow. + ResponseHighlightingInterceptor provides a better implementation of + this functionality and should be used instead. + + + Narrative generator framework has removed the + ability to generate resource titles. This + functionality was only useful for DSTU1 + implementations and wasn't compatible + with coming changes to that API. + + + Remove dependency on Servlet-API 3.0+ by using methods available in 2.5 where possible. + Note that we continue to use Servlet-API 3.0+ features in some parts of the JPA API, so + running in an old serlvet container should be tested well before use. Thanks to Bill Denton + for reporting! + + + Add new methods to RestfulClientFactory allowing you to configure the size of the + client pool used by Apache HttpClient. Thanks to Matt Blanchette for the pull + request! + + + Add support for new modifier types on Token search params in Server and + annotation client. + + + Server conformance statement should include search parameter chains if the + chains are explicitly defined via @Search(whitelist={....}). Thanks to lcamilo15 + for reporting! + + + Remove afterPropertiesSet() call in Java config for JPA + server's EntityManagerFactory. This doesn't need to be called + manually, the the manual call led to a warning about + the EntityManager being created twice. + + + Allow server to correctly figure out it's own address even if the container provides + a Servlet Context Path which does not include the root. Thanks to Petro Mykhaylyshyn + for the pull request! + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Commons-lang3 (Core): 3.3.2 -> 3.4
  • +
  • Logback (Core): 1.1.2 -> 1.1.3
  • +
  • SLF4j (Core): 1.7.102 -> 1.7.12
  • +
  • Springframework (JPA, Web Tester): 4.1.5 -> 4.2.2
  • +
  • Hibernate (JPA, Web Tester): 4.2.17 -> 5."
  • +
  • Hibernate Validator (JPA, Web Tester): 5.2.1 -> 5.2.2
  • +
  • Derby (JPA, CLI, Public Server): 10.11.1.1 -> 10.12.1.1
  • +
  • Jetty (JPA, CLI, Public Server): 9.2.6.v20141205 -> 9.3.4.v20151007
  • + + ]]> +
    + + JPA and Tester Overlay now use Spring Java config files instead + of the older XML config files. All example projects have been updated. + + + JPA server removes duplicate resource index entries before storing them + (e.g. if a patient has the same name twice, only one index entry is created + for that name) + + + JPA server did not correctly index search parameters of type "reference" where the + path had multiple entries (i.e. "Resource.path1 | Resource.path2") + + + JPA server _history operations (server, type, instance) not correctly set the + Bundle.entry.request.method to POST or PUT for create and updates of the resource. + + + Support AND/OR on _id search parameter in JPA + + + Constructor for DateRanfeParam which dates in two DateParam instances was ignoring + comparators on the DateParam. + + + In JSON parsing, finding an object where an array was expected led to an unhelpful + error message. Thanks to Avinash Shanbhag for reporting! + + + JPA server gave an unhelpful error message if $meta-add or $meta-delete were called + with no meta elements in the input Parameters + + + Narrative generator did not include OperationOutcome.issue.diagnostics in the + generated narrative. + + + Clients (generic and annotation) did not populate the Accept header on outgoing + requests. This is now populated to indicate that the client supports both XML and + JSON unless the user has explicitly requested one or the other (in which case the + appropriate type only will be send in the accept header). Thanks to + Avinash Shanbhag for reporting! + + + QuestionnaireResponse validator now allows responses to questions of + type OPENCHOICE to be of type 'string' + + + JPA server should reject resources with a reference that points to an incorrectly typed + resource (e.g. points to Patient/123 but resource 123 is actually an Observation) or points + to a resource that is not valid in the location it is found in (e.g. points to Patient/123 but + the field supposed to reference an Organization). Thanks to Bill de Beaubien for reporting! + + + In server, if a client request is received and it has an Accept header indicating + that it supports both XML and JSON with equal weight, the server's default is used instead of the first entry in the list. + + + JPA server now supports searching with sort by token, quantity, + number, Uri, and _lastUpdated (previously only string, date, and _id + were supported) + + + Fix issue in JPA where a search with a _lastUpdated filter which matches no results + would crash if the search also had a _sort + + + Fix several cases where invalid requests would cause an HTTP 500 instead of + a more appropriate 400/404 in the JPA server (vread on invalid version, + delete with no ID, etc.) + + + Fix narrative generation for DSTU2 Medication resource + + + Profile validator now works for valuesets which use + v2 tables + + + JPA server Patient/[id]/$everything operation now supports + _lastUpdated filtering and _sort'ing of results. + + + Fix parser issue where profiled choice element datatypes (e.g. value[x] where one allowable + type is Duration, which is a profile of Quantity) get incorrectly encoded using the + profiled datatype name instead of the base datatype name as required by the FHIR + spec. Thanks to Nehashri Puttu Lokesh for reporting! + + + Some generated Enum types in DSTU2 HAPI structures + did not have latest valueset definitions applied. Thanks + to Bill de Beaubien for reporting! + + + JPA server can now successfully search for tokens pointing at code values + (values with no explicit system but an implied one, such as Patient.gender) + even if the system is supplied in the query. + + + Correct issues with Android library. Thanks to + Thomas Andersen for the submission! + + + JPA server incorrectly rejected match URLs + if they did not contain a question mark. Thanks + to Bill de Beaubien for reporting! + + + Remove invalid entries in OSGi Manifest. Thanks + to Alexander Kley for the fix! + + + JPA server now supports $everything on Patient and Encounter types (patient and encounter instance was already supported) + + + Generic client operation invocations now + have an additional inline method for generating the input + Parameters using chained method calls instead + of by passing a Parameters resource in + + + Parsing an XML resource where the XHTML + namespace was declared before the beginning + of the narrative section caused an invalid + re-encoding when encoding to JSON. + + + Conditional deletes in JPA did not correctly + process if the condition had a chain or a + qualifier, e.g. "Patient?organization.name" or + "Patient.identifier:missing" + + + Generic/fluent client search can now be + performed using a complete URL supplied + by user code. Thanks to Simone Heckmann + pointing out that this was needed! + + + Refactor JPA $everything operations so that + they perform better + + + Server operation methods can now declare the + ID optional, via + @IdParam(optional=true) + meaning that the same operation can also be invoked + at the type level. + + + Make JPA search queries with _lastUpdated parameter a bit more efficient + + + Clean up Android project to make it more lightweight and remove a + number of unneeded dependencies. Thanks to Thomas Andersen + for the pull request! + + + Fix a crash when encoding a Binary resource in JSON encoding + if the resource has no content-type + + + JPA server now supports read/history/search in transaction entries + by calling the actual implementing method in the server (previously + the call was simulated, which meant that many features did not work) + + + ResourceReferenceDt#loadResource(IRestfulClient) did not + use the client's read functionality, so it did not + handle JSON responses or use interceptors. Thanks to + JT for reporting! + + + JPA server maximumn length for a URI search parameter has been reduced from + 256 to 255 in order to accomodate MySQL's indexing requirements + + + Server failed to respond correctly to compartment search operations + if the same provider also contained a read operation. Thanks to GitHub user + @am202 for reporting! + + + Fix issue in testpage-overlay's new Java configuration where only the first + configured server actually gets used. + + + Introduce + IJpaServerInterceptor]]> + interceptors for JPA server which can be used for more fine grained operations. + + + Parser (XML and JSON) shouldn't encode an ID tag in resources + which are part of a bundle when the resource has a UUID/OID + ID. + + + Add ability for a server REST resource provider @Search method + to declare that it should allow even parameters it doesn't + understand. + + + Correctly set the Bundle.type value on all pages of a search result in + the server, and correcltly set the same value in JPA server $everything + results. + + + JPA $everything operations now support new parameters _content + and _text, which work the same way as the same parameters on a + search. This is experimental, since it is not a part of the core + FHIR specification. + + + Process "Accept: text/xml" and "Accept: text/json" headers was + wanting the equivalent FHIR encoding styles. These are not + correct, but the intention is clear so we will honour them + just to be helpful. + + + Generated Enum types for some ValueSets did not include all + codes (specifically, ValueSets which defined concepts containing + child concepts did not result in Enum values for the child concepts) + + + In the JPA server, order of transaction processing should be + DELETE, POST, PUT, GET, and the order should not matter + within entries with the same verb. Thanks to Bill de Beaubien + for reporting! + + + Add the ability to wire JPA conformance providers + using Spring (basically, add default constructors + and setters to the conformance providers). Thanks + to C. Mike Bylund for the pull request! + +
    + + + JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire + if one is declared. + + + SyntaxHighlightingInterceptor now also highlights OperationOutcome responses for errors/exceptions. + + + Model classes do not use BoundCodeableConcept for example bindings that do not + actually point to any codes (e.g. Observation.interpretation). Thanks + to GitHub user @steve1medix for reporting! + + + Server now exports operations as separate resources instead of as contained resources + within Conformance + + + Add new operation $get-resource-counts which will replace the resource + count extensions exported in the Conformance statement by the JPA + server. + + + JPA server sorting often returned unexpected orders when multiple + indexes of the same type were found on the same resource (e.g. multiple string indexed fields). Thanks to Travis Cummings for reporting! + + + Add another method to IServerInterceptor which converts an exception generated on the server + into a BaseServerResponseException. This is useful so that servers using ResponseHighlighterInterceptor + will highlight exceptions even if they aren't created with an OperationOutcome. + + + XmlParser and JsonParser in DSTU2 mode should not encode empty + tags in resource. Thanks to Bill De Beaubien for reporting! + + + OperationDefinitions generated by server did not properly document + their return parameters or the type of their input parameters. + + + Operations in server generated conformance statement should only + appear once per name, since the name needs to be unique. + + + Resources and datatypes are now serializable. This is an + experimental feature which hasn't yet been extensively tested. Please test and give us your feedback! + + + Switch REST server to using HttpServletRequest#getContextPath() to get + the servlet's context path. This means that the server should behave more + predictably, and should work in servlet 2.4 environments. Thanks to + Ken Zeisset for the suggestion! + + + Vagrant environment now has an apt recipt to ensure that + package lists are up to date. Thanks to GitHub user + Brian S. Corbin (@corbinbs) for thr contribution! + + + JPA server and generic client now both support the _tag search parameter + + + Add support for BATCH mode to JPA server transaction operation + + + Server was not correctly unescaping URL parameter values with + a trailing comma or an escaped backslash. Thanks to GitHub user + @SherryH for all of her help in diagnosing this issue! + + + Avoid crash when parsing if an invalid child element is found in + a resource reference. + + + Create new android specialty libraries for DSTU1 and DSTU2 + + + Throwing a server exception (e.g. AuthenticationException) in a server interceptor's + incomingRequestPreProcessed method resulted in the server returning an HTTP 500 instead + of the appropriate error code for the exception being thrown. Thanks to Nagesh Bashyam + for reporting! + + + Fix issue in JSON parser where invalid contained resources (missing + a resourceType element) fail to parse with a confusing NullPointerException. + Thanks to GitHub user @hugosoares for reporting! + + + JPA server now implements the $validate-code operation + + + HAPI-FHIR now has support for _summary and _elements parameters, in server, client, + and JPA server. + + + _revinclude results from JPA server should have a Bundle.entry.search.mode of + "include" and not "match". Thanks to Josh Mandel for reporting! + + + Resource references using resource instance objects instead of resource IDs + will correctly qualify the IDs with the resource type if they aren't already qualified + + + Testpage Overlay project now properly allows a custom client + factory to be used (e.g. for custom authentication, etc.) Thanks + to Chin Huang (@pukkaone) for the pull request! + + + JPA server should reject IDs containing invalid characters (e.g. "abc:123") + but should allow client assigned IDs that contain text but do not start with + text. Thanks to Josh Mandel for reporting! + + + :text modifier on server and JPA server did not work correctly. Thanks to + Josh Mandel for reporting! + + + Fix issue in client where parameter values containing a comma were + sometimes double escaped. + + + _include parameters now support the new _include:recurse=FOO]]> + syntax that has been introduced in DSTU2 in the Client, Server, and JPA Server modules. + Non-recursive behaviour is now the default (previously it was recursive) and :recurse + needs to be explicitly stated in order to support recursion. + + + New operations added to JPA server to force re-indexing of all + resources (really only useful after indexes change or bugs are + fixed) + + + JPA server did not correctly index search parameters + of type "URI". Thanks to David Hay for reporting! Note that if you are using the JPA server, this change means that + there are two new tables added to the database schema. Updating existing resources in the database may fail unless you + set default values for the resource + table by issuing a SQL command similar to the following (false may be 0 or something else, depending on the database platform in use) + update hfj_resource set sp_coords_present = false;
    + update hfj_resource set sp_uri_present = false;
    ]]> +
    + + FIx issue in JPA server where profile declarations, tags, and + security labels were not always properly removed by an update that + was trying to remove them. Also don't store duplicates. + + + Instance $meta operations on JPA server did not previously return the + resource version and lastUpdated time + + + Server responses populate Bundle.entry.fullUrl if possible. Thanks + to Bill de Beaubien for reporting! + + + XML parser failed to initialize in environments where a very old Woodstox + library is in use (earlier than 4.0). Thanks to Bill de Beaubien for + reporting! + + + Invalid/unexpected attributes found when parsing composite elements + should be logged or reported to the parser error handler + + + JPA server can now store Conformance resources, per a request + from David Hay + + + ResponseHighlightingInterceptor now skips handling responses if it + finds a URL parameter of _raw=true]]> (in other + words, if this parameter is found, the response won't be returned as + HTML even if the request is detected as coming from a browser. + + + RestfulServer now supports dynamically adding and removing resource providers + at runtime. Thanks to Bill Denton for adding this. + + + JPA server now correctly suppresses contents of deleted resources + in history + + + JPA server returned deleted resources in search results when using the _tag, _id, _profile, or _security search parameters + + + Fix issue with build on Windows. Thanks to Bryce van Dyk for the pull request! + + + JPA server now supports $validate operation completely, including delete mode + and profile validation using the RI InstanceValidator + +
    + + + Add support for reference implementation structures. + + + Parsers did not encode the resource meta element if the resource + had tags but no other meta elements. Thanks to Bill de Beaubien and + Claude Nanjo for finding this. + + + Correct performance issue with :missing=true search requests where the parameter is a resource link. Thanks to wanghaisheng for all his help in testing this. + + + The self link in the Bundle returned by searches on the server does not respect the + server's address strategy (which resulted in an internal IP being shown on fhirtest.uhn.ca) + + + Introduce ResponseHighlighterInterceptor, which provides syntax highlighting on RESTful server responses + if the server detects that the request is coming from a browser. This interceptor has been added + to fhirtest.uhn.ca responses. + + + Performing a create operation in a client used an incorrect URL if the + resource had an ID set. ID should be ignored for creates. Thanks to + Peter Girard for reporting! + + + Add better addXXX() methods to structures, which take the datatype being added as a parameter. Thanks to Claude Nanjo for the + suggestion! + + + Add a new parser validation mechanism (see the + validation page]]> for info) which can be + used to validate resources as they are being parsed, and optionally fail if invalid/unexpected + elements are found in resource bodies during parsing. + + + IParser#parseResource(Class, String) method, which is used to parse a resource into the given + structure will now throw a DataFormatException if the structure is for the wrong type of + resource for the one actually found in the input String (or Reader). For example, if a Patient + resource is being parsed into Organization.class this will now cause an error. Previously, + the XML parser would ignore the type and the JSON parser would fail. This also caused + operations to not parse correctly if they returned a resource type other than + parameters with JSON encoding (e.g. the $everything operation on UHN's test server). + Thanks to Avinash Shanbhag for reporting! + + + Web tester UI now supports _revinclude + + + Support link elements in Bundle.entry when parsing in DSTU2 mode + using the old (non-resource) Bundle class. Thanks to GitHub user + @joedai for reporting! + + + LoggingInterceptor for server now supports logging DSTU2 extended operations by name + + + Woodstox XML parser has a default setting to limit the maximum + length of an attribute to 512kb. This caused issues handling + large attachments, so this setting has been increased to 100Mb. + Thanks to Nikos Kyriakoulakos for reporting! + + + Some HTML entities were not correctly converted during parsing. Thanks to + Nick Kitto for reporting! + + + In the JPA Server: + Transactions creating resources with temporary/placeholder resource IDs + and other resources with references to those placeholder IDs previously + did not work if the reference did not contain the resource type + (e.g. Patient/urn:oid:0.1.2.3 instead of urn:oid:0.1.2.3). The + latter is actually the correct way of specifying a reference to a + placeholder, but the former was the only way that worked. Both forms + now work, in order to be lenient. Thanks to Bill De Beaubien for + reporting! + + + When parsing Bundles, if Bundle.entry.base is set to "cid:" (for DSTU1) + or "urn:uuid:" / "urn:oid:" (for DSTU2) this is now correctly passed as + the base in resource.getId(). Conversely, when + encoding bundles, if a resource ID has a base defined, + and Bundle.entry.base is empty, it will now be + automatically set by the parser. + + + Add fluent client method for validate operation, and support the + new DSTU2 style extended operation for $validate if the client is + in DSTU2 mode. Thanks to Eric from the FHIR Skype Implementers chat for + reporting. + + + Server now supports complete Accept header content negotiation, including + q values specifying order of preference. Previously the q value was ignored. + + + Server in DSTU2 mode now indicates that whether it has support for Transaction operation or not. Thanks to Kevin Paschke for pointing out that this wasn't working! + + + Questionnaire.title now gets correctly indexed in JPA server (it has no path, so it is a special case) + + + JPA server now supports ifNoneMatch in GET within a transaction request. + + + DateRangeParam now supports null values in the constructor for lower or upper bounds (but + still not both) + + + Generic/fluent client and JPA server now both support _lastUpdated search parameter + which was added in DSTU2 + + + JPA server now supports sorting on reference parameters. Thanks to + Vishal Kachroo for reporting that this wasn't working! + + + Prevent Last-Updated header in responses coming back to the client from + overwriting the 'lastUpdated' value in the meta element in DSTU2 + resources. This is important because 'lastUpdated' can have more + precision than the equivalent header, but the client previously + gave the header priority. + + + JPA server supports _count parameter in transaction containing search URL (nested search) + + + DSTU2 servers now indicate support for conditional create/update/delete in their + conformance statement. + + + Support for the Prefer header has been added to the server, client, and + JPA modules. + + + JPA server failed to search for deep chained parameters across multiple references, + e.g. "Location.partof.partof.organization". Thanks to Ismael Sarmento Jr for + reporting! + + + Prevent crash when encoding resources with contained resources + if the contained resources contained a circular reference to each other + + + Add $meta, $meta-add, and $meta-delete operations to generic client + + + + + Bump the version of a few dependencies to the + latest versions: + +
  • Phloc-commons (for schematron validation) 4.3.5 -> 4.3.6
  • +
  • Apache HttpClient 4.3.6 -> 4.4
  • +
  • Woodstox 4.4.0 -> 4.4.1
  • +
  • SLF4j 1.7.9 -> 1.7.10
  • +
  • Spring (used in hapi-fhir-jpaserver-base module) 4.1.3.RELEASE -> 4.1.5.RELEASE
  • + + ]]> +
    + + Add support for "profile" and "tag" elements in the resource Meta block + when parsing DSTU2 structures. + + + When a user manually creates the list of contained resources in a resource, + the encoder fails to encode any resources that don't have a '#' at the + start of their ID. This is unintuitive, so we now assume that '123' means '#123'. + Thanks to myungchoi for reporting and providing a test case! + + + Add methods for setting the default encoding (XML/JSON) and + oretty print behaviour in the Fluent Client. Thanks to Stackoverflow + user ewall for the idea. + + + JPA Server did not mark a resource as "no longer deleted" if it + was updated after being deleted. Thanks to Elliott Lavy and Lloyd + McKenzie for reporting! + + + Fix regression in 0.9 - Server responds with an HTTP 500 and a NullPointerException instead of an HTTP 400 and a useful error message if the client requests an unknown resource type + + + Add support for + _revinclude]]> + parameter in client, server, and JPA. + + + Include constants on resources (such as + Observation.INCLUDE_VALUE_STRING]]>) + have been switched in the DSTU2 structures to use + the new syntax required in DSTU2: [resource name]:[search param NAME] + insead of the DSTU1 style [resource name].[search param PATH] + + + When encoding resources, the parser will now convert any resource + references to versionless references automatically (i.e. it will + omit the version part automatically if one is present in the reference) + since references between resources must be versionless. Additionally, + references in server responses will omit the server base URL part of the + reference if the base matches the base for the server giving + the response. + + + Narrative generator incorrectly sets the Resource.text.status to 'generated' even if the + given resource type does not have a template (and therefore no narrative is actually generated). + Thanks to Bill de Beaubien for reporting! + + + Searching in JPA server with no search parameter returns deleted resources when it should exclude them. + + + Remove Eclipse and IntelliJ artifacts (.project, *.iml, etc) from version control. Thanks + to Doug Martin for the suggestion! + + + REST server methods may now have a parameter of + type NarrativeModeEnum which will be populated with + the value of the _narrative URL parameter + if one was supplied. Annotation client methods + may also include a parameter of this type, and it + will be used to populate this parameter on the request + URL if it is not null. Thanks to Neal Acharya for the + idea! + + + Android JAR now includes servlet-API classes, as the project will not + work without them. Thanks + + + Requested _include values are preserved across paging links when the + server returns multiple pages. Thanks to Bill de Beaubien for + reporting! + + + Add new server address strategy "ApacheProxyAddressStrategy" which uses + headers "x-forwarded-host" and "x-forwarded-proto" to determine the + server's address. This is useful if you are deploying a HAPI FHIR + server behind an Apache proxy (e.g. for load balancing or other reasons). + Thanks to Bill de Beaubien for contributing! + + + Resource references between separate resources found in a single + bundle did not get populated with the actual resource when parsing a + DSTU2 style bundle. Thanks to Nick Peterson for reporting and figuring + out why none of our unit tests were actually catching the problem! + + + JSON encoder did not encode contained resources when encoding + a DSTU2 style bundle. Thanks to Mohammad Jafari and baopingle + for all of their help in tracking this issue down and developing + useful unit tests to demonstrate it. + + + Client now supports invoking transcation using a DSTU2-style + Bundle resource as the input. + + + JPA Server $everything operation could sometimes include a duplicate copy of + the main focus resource if it was referred to in a deep chain. Thanks + to David Hay for reporting! + + + JPA Server $everything operation now allows a _count parameter + + + JPA server failed to index resources containing ContactPointDt elements with + populated values (e.g. Patient.telecom). Thanks to Mohammad Jafari for reporting! + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Terser's IModelVisitor now supplies to the path to the element. This is + an API change, but I don't think there are many users of the IModelVisitor yet. + Please let us know if this is a big hardship and we can find an alternate way + of making this change. + + + Prevent server from returning a Content-Location header for search + response when using the DSTU2 bundle format + + + JPA server (uhnfhirtest.uhn.ca) sometimes included an empty + "text" element in Bundles being returned. + + + Add a framework for the Web Tester UI to allow its internal FHIR client to + be configured (e.g. to add an authorization interceptor so that it adds + credentials to client requests it makes). Thanks to Harsha Kumara for + the suggestion! + + + Fix regression in early 1.0 builds where resource type sometimes does not get + populated in a resource ID when the resource is parsed. Thanks to + Nick Peterson for reporting, and for providing a test case! + + + Allow fluent/generic client users to execute a transaction using a raw string (containing a bundle resource) + as input instead of a Bundle resource class instance. + + + Disable date validation in the web tester UI, so that it is possible to + enter partial dates, or dates without times, or even test out invalid date + options. + + + Make BaseElement#getUndeclaredExtensions() and BaseElement#getUndeclaredExtensions() return + a mutable list so that it is possible to delete extensions from a resource instance. + + + Server conformance statement check in clients (this is the check + where the first time a given FhirContext is used to access a given server + base URL, it will first check the server's Conformance statement to ensure + that it supports the correct version of FHIR) now uses any + registered client interceptors. In addition, IGenericClient now has a method + "forceConformanceCheck()" which manually triggers this check. Thanks to + Doug Martin for reporting and suggesting! + + + Rename the Spring Bean definition for the JPA server EntityManager from + "myEntityManagerFactory" to just "entityManagerFactory" as this is the + default bean name expected in other parts of the Spring framework. + Thanks to Mohammad Jafari for the suggestion! + + + Improve error message when a user tries to perform a create/update with an invalid + or missing Content-Type header. Thanks to wanghaisheng for reporting! (This was + actually a three part bug, so the following two fixes also reference this + bug number) + + + Add support for :missing qualifier in generic/fluent client. + + + Add support for :missing qualifier in JPA server. + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Add an exception for RESTful clients/servers to represent the + HTTP 403 Forbidden status code. Thanks to Joel Costigliola for + the patch! + + + Transaction server operations incorrectly used the "Accept" header instead of the "Content-Type" header to determine the + POST request encoding. Thanks to Rene Spronk for providing a test case! + +
    + + + Support for DSTU2 features introduced: New resource definitions, Bundle resource, + encoding changes (ID in resource bodt, meta tag) + + + Fix an issue encoding extensions on primitive types in JSON. Previously the "_value" object + would be an array even if the field it was extending was not repeatable. This is not correct + according to the specification, nor can HAPI's parser parse this correctly. The encoder + has been corrected, and the parser has been adjusted to be able to handle resources with + extensions encoded in this way. Thanks to Mohammad Jafari for reporting! + + + Library now checks if custom resource types can be instantiated on startup + (e.g. because they don't have a no-argument constructor) in order to + avoid failing later + + + Bump a few dependency JARs to the latest versions in Maven POM: + +
  • SLF4j (in base module) - Bumped to 1.7.9
  • +
  • Apache HTTPClient (in base module) - Bumped to 4.3.6
  • +
  • Hibernate (in JPA module) - Bumped to 4.3.7
  • + + ]]> +
    + + IdDt failed to recognize local identifiers containing fragments that look like + real identifiers as being local identifiers even though they started with '#'. + For example, a local resource reference of "#aa/_history/aa" would be incorrectly + parsed as a non-local reference. + Thanks to Mohammad Jafari for reporting! + + + Last-Modified]]> + header in server was incorrectly using FHIR date format instead + of RFC-1123 format. + + + Server create and update methods failed with an IllegalArgumentException if + the method type was a custom resource definition type (instead of a built-in + HAPI type). Thanks to Neal Acharya for the analysis. + + + JPA server module now supports + _include]]> + value of + *]]>. Thanks to Bill de Beaubien for reporting! + + + IdDt method + + returned String (unlike all of the other "withFoo" methods on that class), + and did not work correctly if the IdDt already had a server base. This + has been corrected. Note that the return type for this method has been + changed, so code may need to be updated. + + + In previous versions of HAPI, the XML parser encoded multiple contained + resources in a single + <contained></contained>]]> + tag, even though the FHIR specification rerquires a separate + <contained></contained>]]> + tag for each resource. This has been corrected. Note that the parser will + correctly parse either form (this has always been the case) so this + change should not cause any breakage in HAPI based trading partners, but + may cause issues if other applications have been coded to depend on the + incorrect behaviour. Thanks to Mochaholic for reporting! + + + Custom/user defined resource definitions which contained more than one + child with no order defined failed to initialize properly. Thanks to + Andy Huang for reporting and figuring out where the + problem was! + + + RESTful Client now queries the server (only once per server base URL) to ensure that + the given server corresponds to the correct version of the FHIR specification, as + defined by the FhirContext. This behaviour can be disabled by setting the + appropriate configuration on the + RestfulClientConfig. Thanks to Grahame Grieve for the suggestion! + + + JPA module now supports deleting resource via transaction + + + DateClientParam#second() incorrectly used DAY precision instead + of SECOND precision. Thanks to Tom Wilson for the pull request! + + + Fix issue where HAPI failed to initialize correctly if Woodstox library was not on the classpath, even + if StAX API was configured to use a different provider. Thanks to + James Butler for reporting and figuring out where the issue was! + + + Calling BaseDateTimeDt#setValue(Date, TemporalPrecisionEnum) did not always actually respect + the given precision when the value was encoded. Thanks to jacksonjesse for + reporting! + + + Encoders (both XML and JSON) will no longer encode contained resources if they are + not referenced anywhere in the resource via a local reference. This is just a convenience + for users who have parsed a resource with contained resources and want to remove some + before re-encoding. Thanks to Alexander Kley for reporting! + + + Add support for DSTU2 style security labels in the parser and encoder. Thanks to + Mohammad Jafari for the contribution! + + + Server requests for Binary resources where the client has explicitly requested XML or JSON responses + (either with a _format]]> URL parameter, or an Accept]]> request header) + will be responded to using the Binary FHIR resource type instead of as Binary blobs. This is + in accordance with the recommended behaviour in the FHIR specification. + + + Add new properties to RestfulServer: "DefaultResponseEncoding", which allows + users to configure a default encoding (XML/JSON) to use if none is specified in the + client request. Currently defaults to XML. Also "DefaultPrettyPrint", which specifies + whether to pretty print responses by default. Both properties can be overridden + on individual requets using the appropriate Accept header or request URL parameters. + + + Add support for quantity search params in FHIR tester UI + + + Add support for FHIR "extended operations" as defined in the FHIR DSTU2 + specification, for the Generic Client, Annotation Client, and + Server. + + + Observation.applies[x] and other similar search fields with multiple allowable + value types were not being correctly indexed in the JPA server. + + + DateClientParam.before() incorrectly placed "<=" instead of + "<" in the request URL. Thanks to Ryan for reporting! + + + Server now only automatically adds _include resources which are provided + as references if the client request actually requested that specific include. + See RestfulServer + + + User defined resource types which contain extensions that use a bound code type + (e.g. an BoundCodeDt with a custom Enum) failed to parse correctly. Thanks + to baopingle for reporting and providing a test case! + + + Sorting is now supported in the Web Testing UI (previously a button existed for sorting, but it didn't do anything) + + + Server will no longer include stack traces in the OperationOutcome returned to the client + when an exception is thrown. A new interceptor called ExceptionHandlingInterceptor has been + created which adds this functionality back if it is needed (e.g. for DEV setups). See the + server interceptor documentation for more information. Thanks to Andy Huang for the suggestion! + +
    + + + API CHANGE:]]> The "FHIR structures" for DSTU1 (the classes which model the + resources and composite datatypes) have been moved out of the core JAR into their + own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast + version is finalized. See the + DSTU2 page]]> + for more information. + + + Deprocated API Removal: The following classes (which were deprocated previously) + have now been removed: +
      +
    • ISecurityManager: If you are using this class, the same functionality + is available through the more general purpose + server interceptor + capabilities. +
    • CodingListParam: This class was made redundant by the + TokenOrListParam + class, which can be used in its place. +
    + ]]> +
    + + API Change: The IResource#getResourceMetadata() method has been changed + from returning + Map<ResourceMetadataKeyEnum<?>, Object> + to returning a new type called + ResourceMetadataMap. This new type implements + Map<ResourceMetadataKeyEnum<?>, Object> + itself, so this change should not break existing code, but may + require a clean build in order to run correctly. + ]]> + + + Profile generation on the server was not working due to IdDt being + incorrectly used. Thanks to Bill de Beaubien for the pull request! + + + Profiles did not generate correctly if a resource definition class had a + defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request! + + + Remove unnecessary IOException from narrative generator API. Thanks to + Petro Mykhailysyn for the pull request! + + + Introduced a new + @ProvidesResources]]> annotation which can be added to + resource provider and servers to allow them to declare additional resource + classes they are able to serve. This is useful if you have a server which can + serve up multiple classes for the same resource type (e.g. a server that sometimes + returns a default Patient, but sometimes uses a custom subclass). + Thanks to Bill de Beaubien for the pull request! + + + Introduced a new + @Destroy]]> annotation which can be added to + a resource provider method. This method will be called by the server when it + is being closed/destroyed (e.g. when the application is being undeployed, the + container is being shut down, etc.) + Thanks to Bill de Beaubien for the pull request! + + + Add a new method to the server interceptor + framework which allows interceptors to be notified of any exceptions and + runtime errors within server methods. Interceptors may optionally also + override the default error handling behaviour of the RestfulServer. + + + Add constants to BaseResource for the "_id" search parameter which all resources + should support. + + + DateRangeParam parameters on the server now return correct + getLowerBoundAsInstant()]]> + and + getUpperBoundAsInstant()]]> + values if a single unqualified value is passed in. For example, if + a query containing + &birthdate=2012-10-01]]> + is received, previously these two methods would both return the same + value, but with this fix + getUpperBoundAsInstant()]]> + now returns the instant at 23:59:59.9999. + + + Resource fields with a type of "*" (or Any) sometimes failed to parse if a + value type of "code" was used. Thanks to Bill de Beaubien for reporting! + + + Remove dependency on JAXB libraries, which were used to parse and encode + dates and times (even in the JSON parser). JAXB is built in to most JDKs + but the version bundled with IBM's JDK is flaky and resulted in a number + of problems when deploying to Websphere. + + + Primitive datatypes now preserve their original string value when parsing resources, + as well as containing the "parsed value". For instance, a DecimalDt field value of + 1.0000]]> will be parsed into the corresponding + decimal value, but will also retain the original value with the corresponding + level of precision. This allows vadliator rules to be applied to + original values as received "over the wire", such as well formatted but + invalid dates, e.g. "2001-15-01". Thanks to Joe Athman for reporting and + helping to come up with a fix! + + + When using Generic Client, if performing a + or operation using a String as the resource body, + the client will auto-detect the FHIR encoding style and send an appropriate + header. + + + JPA module (and public HAPI-FHIR test server) were unable to process resource types + where at least one search parameter has no path specified. These now correctly save + (although the server does not yet process these params, and it should). Thanks to + GitHub user shvoidlee for reporting and help with analysis! + + + Generic/Fluent Client "create" and "update" method requests were not setting a content type header + + + DateDt left precision value as in the constructor + . + + + RESTful server now doesn't overwrite resource IDs if they are absolute. In other words, if + a server's Resource Provider returns a resource with ID "Patient/123" it will be translated to + "[base url]/Patient/123" but if the RP returns ID "http://foo/Patient/123" the ID will be + returned exactly as is. Thanks to Bill de Beaubien for the suggestion! + + + JPA module Transaction operation was not correctly replacing logical IDs + beginning with "cid:" with server assigned IDs, as required by the + specification. + + + did not visit or find children in contained resources when + searching a resource. This caused server implementations to not always return contained + resources when they are included with a resource being returned. + + + Add a method which returns the name of the + resource in question (e.g. "Patient", or "Observation"). This is intended as a + convenience to users. + + + Do not strip version from resource references in resources returned + from server search methods. Thanks to Bill de Beaubien for reporting! + + + Correct an issue with the validator where changes to the underlying + OperationOutcome produced by a validation cycle cause the validation + results to be incorrect. + + + Client interceptors registered to an interface based client instance + were applied to other client instances for the same client interface as well. (Issue + did not affect generic/fluent clients) + + + DateDt, DateTimeDt and types InstantDt types now do not throw an exception + if they are used to parse a value with the wrong level of precision for + the given type but do throw an exception if the wrong level of precision + is passed into their constructors.
    ]]> + This means that HAPI FHIR can now successfully parse resources from external + sources that have the wrong level of precision, but will generate a validation + error if the resource is validated. Thanks to Alexander Kley for the suggestion! +
    + + Encoding a Binary resource without a content type set should not result in a NullPointerException. Thanks + to Alexander Kley for reporting! + + + Server gives a more helpful error message if multiple IResourceProvider implementations + are provided for the same resource type. Thanks to wanghaisheng for the idea! + + + Bring DSTU1 resource definitions up to version 0.0.82-2929]]> + Bring DEV resource definitions up to 0.4.0-3775]]> + Thanks to crinacimpian for reporting! + + + JPA server did not correctly process _include requests if included + resources were present with a non-numeric identifier. Thanks to + Bill de Beaubien for reporting! + + + Client requests which include a resource/bundle body (e.g. create, + update, transaction) were not including a charset in the content type + header, leading to servers incorrectly assuming ISO-8859/1. Thanks to + shvoidlee for reporting! + + + Clean up the way that Profile resources are automatically exported + by the server for custom resource profile classes. See the + @ResourceDef]]> + JavaDoc for information on how this works. + + + Add convenience methods to TokenOrListParam to test whether any of a set of tokens match + the given requested list. + + + Add a protected method to RestfulServer which allows developers to + implement their own method for determining which part of the request + URL is the FHIR request path (useful if you are embedding the RestulServer inside + of another web framework). Thanks to Harsha Kumara for the pull request! + +
    + + + API CHANGE:]]> The TagList class previously implemented ArrayList semantics, + but this has been replaced with LinkedHashMap semantics. This means that the list of + tags will no longer accept duplicate tags, but that tag order will still be + preserved. Thanks to Bill de Beaubien for reporting! + + + Server was incorrectly including contained resources being returned as both contained resources, and as + top-level resources in the returned bundle for search operations. + Thanks to Bill de Beaubien for reporting! This also fixes Issue #20, thanks to + lephty for reporting! + + + Documentation fixes + + + Add a collection of new methods on the generic client which support the + read, + read, + and search + ]]> + operations using an absolute URL. This allows developers to perform these operations using + URLs they obtained from other sources (or external resource references within resources). In + addition, the existing read/vread operations will now access absolute URL references if + they are passed in. Thanks to Doug Martin of the Regenstrief Center for Biomedical Informatics + for contributing this implementation! + + + Server implementation was not correctly figuring out its own FHIR Base URL when deployed + on Amazon Web Service server. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + XML Parser failed to encode fields with both a resource reference child and + a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + HAPI now runs successfully on Servlet 2.5 containers (such as Tomcat 6). Thanks to + Bernard Gitaadji for reporting and diagnosing the issue! + + + Summary (in the bundle entry) is now encoded by the XML and JSON parsers if supplied. Thanks to David Hay of + Orion Health for reporting this! + + + Conformance profiles which are automatically generated by the server were missing a few mandatory elements, + which meant that the profile did not correctly validate. Thanks to Bill de Beaubien of Systems Made Simple + for reporting this! + + + XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters + escaped properly in encoded messages. + + + Resources containing entities which are not valid in basic XML (e.g. &sect;) will have those + entities converted to their equivalent unicode characters when resources are encoded, since FHIR does + not allow extended entities in resource instances. + + + Add a new client interceptor which adds HTTP Authorization Bearer Tokens (for use with OAUTH2 servers) + to client requests. + + + Add phloc-commons dependency explicitly, which resolves an issue building HAPI from source on + some platforms. Thanks to Odysseas Pentakalos for the patch! + + + HAPI now logs a single line indicating the StAX implementation being used upon the + first time an XML parser is created. + + + Update methods on the server did not return a "content-location" header, but + only a "location" header. Both are required according to the FHIR specification. + Thanks to Bill de Beaubien of Systems Made Simple for reporting this! + + + Parser failed to correctly read contained Binary resources. Thanks to Alexander Kley for + the patch! + + + Calling encode multiple times on a resource with contained resources caused the contained + resources to be re-added (and the actual message to grow) with each encode pass. Thanks to + Alexander Kley for the test case! + + + JSON-encoded contained resources with the incorrect "_id" element (which should be "id", but some + incorrect examples exist on the FHIR specification) now parse correctly. In other words, HAPI + previously only accepted the correct "id" element, but now it also accepts the incorrect + "_id" element just to be more lenient. + + + Several unit tests failed on Windows (or any platform with non UTF-8 default encoding). This may + have also caused resource validation to fail occasionally on these platforms as well. + Thanks to Bill de Beaubien for reporting! + + + toString() method on TokenParam was incorrectly showing the system as the value. + Thanks to Bill de Beaubien for reporting! + + + Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks + to David Hay of Orion Health for reporting! + + + Add a + Vagrant]]> + based environment (basically a fully built, self contained development environment) for + trying out the HAPI server modules. Thanks to Preston Lee for the pull request, and for + offering to maintain this! + + + Change validation API so that it uses a return type instead of exceptions to communicate + validation failures. Thanks to Joe Athman for the pull request! + + + Add a client interceptor which adds an HTTP cookie to each client request. Thanks to + Petro Mykhailysyn for the pull request! + + + + + + Add server interceptor framework, and new interceptor for logging incoming + requests. + + + Add server validation framework for validating resources against the FHIR schemas and schematrons + + + Tester UI created double _format and _pretty param entries in searches. Thanks to Gered King of University + Health Network for reporting! + + + Create method was incorrectly returning an HTTP 204 on sucessful completion, but + should be returning an HTTP 200 per the FHIR specification. Thanks to wanghaisheng + for reporting! + + + FHIR Tester UI now correctly sends UTF-8 charset in responses so that message payloads containing + non US-ASCII characters will correctly display in the browser + + + JSON parser was incorrectly encoding extensions on composite elements outside the element itself + (as is done correctly for non-composite elements) instead of inside of them. Thanks to David Hay of + Orion for reporting this! + + + Contained/included resource instances received by a client are now automatically + added to any ResourceReferenceDt instancea in other resources which reference them. + + + Add documentation on how to use eBay CORS Filter to support Cross Origin Resource + Sharing (CORS) to server. CORS support that was built in to the server itself has + been removed, as it did not work correctly (and was reinventing a wheel that others + have done a great job inventing). Thanks to Peter Bernhardt of Relay Health for all the assistance + in testing this! + + + IResource interface did not expose the getLanguage/setLanguage methods from BaseResource, + so the resource language was difficult to access. + + + JSON Parser now gives a more friendly error message if it tries to parse JSON with invalid use + of single quotes + + + Transaction server method is now allowed to return an OperationOutcome in addition to the + incoming resources. The public test server now does this in order to return status information + about the transaction processing. + + + Update method in the server can now flag (via a field on the MethodOutcome object being returned) + that the result was actually a creation, and Create method can indicate that it was actually an + update. This has no effect other than to switch between the HTTP 200 and HTTP 201 status codes on the + response, but this may be useful in some circumstances. + + + Annotation client search methods with a specific resource type (e.g. List<Patient> search()) + won't return any resources that aren't of the correct type that are received in a response + bundle (generally these are referenced resources, so they are populated in the reference fields instead). + Thanks to Tahura Chaudhry of University Health Network for the unit test! + + + Added narrative generator template for OperationOutcome resource + + + Date/time types did not correctly parse values in the format "yyyymmdd" (although the FHIR-defined format + is "yyyy-mm-dd" anyhow, and this is correctly handled). Thanks to Jeffrey Ting of Systems Made Simple + for reporting! + + + Server search method for an unnamed query gets called if the client requests a named query + with the same parameter list. Thanks to Neal Acharya of University Health Network for reporting! + + + Category header (for tags) is correctly read in client for "read" operation + + + Transaction method in server can now have parameter type Bundle instead of + List<IResource> + + + HAPI parsers now use field access to get/set values instead of method accessors and mutators. + This should give a small performance boost. + + + JSON parser encodes resource references incorrectly, using the name "resource" instead + of the name "reference" for the actual reference. Thanks to + Ricky Nguyen for reporting and tracking down the issue! + + + Rename NotImpementedException to NotImplementedException (to correct typo) + + + Server setUseBrowserFriendlyContentType setting also respected for errors (e.g. OperationOutcome with 4xx/5xx status) + + + Fix performance issue in date/time datatypes where pattern matchers were not static + + + Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but + previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting! + + + Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health + for reporting! + + + QuantityParam correctly encodes approximate (~) prefix to values + + + If a server defines a method with parameter "_id", incoming search requests for that method may + get delegated to the wrong method. Thanks to Neal Acharya for reporting! + + + SecurityEvent.Object structural element has been renamed to + SecurityEvent.ObjectElement to avoid conflicting names with the + java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for + reporting! + + + Text/narrative blocks that were created with a non-empty + namespace prefix (e.g. <xhtml:div xmlns:xhtml="...">...</xhtml:div>) + failed to encode correctly (prefix was missing in encoded resource) + + + Resource references previously encoded their children (display and reference) + in the wrong order so references with both would fail schema validation. + + + SecurityEvent resource's enums now use friendly enum names instead of the unfriendly + numeric code values. Thanks to Laurie MacDougall-Sookraj of UHN for the + suggestion! + + + + + HAPI has a number of RESTful method parameter types that have similar but not identical + purposes and confusing names. A cleanup has been undertaken to clean this up. + This means that a number of existing classes + have been deprocated in favour of new naming schemes. +
    ]]> + All annotation-based clients and all server search method parameters are now named + (type)Param, for example: StringParam, TokenParam, etc. +
    ]]> + All generic/fluent client method parameters are now named + (type)ClientParam, for example: StringClientParam, TokenClientParam, etc. +
    ]]> + All renamed classes have been retained and deprocated, so this change should not cause any issues + for existing applications but those applications should be refactored to use the + new parameters when possible. +
    + + Allow server methods to return wildcard generic types (e.g. List<? extends IResource>) + + + Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as + "&identifier=system|codepart1\|codepart2" + + + Add support for OPTIONS verb (which returns the server conformance statement) + + + Add support for CORS headers in server + + + Bump SLF4j dependency to latest version (1.7.7) + + + Add interceptor framework for clients (annotation based and generic), and add interceptors + for configurable logging, capturing requests and responses, and HTTP basic auth. + + + Transaction client invocations with XML encoding were using the wrong content type ("application/xml+fhir" instead + of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one! + + + Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion! + + + If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or + an OperationOutcome resource, include the message in the exception message so that it will be + more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion! + + + Read invocations in the client now process the "Content-Location" header and use it to + populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion! + + + Fix issue where vread invocations on server incorrectly get routed to instance history method if one is + defined. Thanks to Neal Acharya from UHN for surfacing this one! + + + Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary + blobs from being used for nefarious purposes. See + FHIR Tracker Bug 3298]]> + for more information. + + + Support has been added for using an HTTP proxy for outgoing requests. + + + Fix: Primitive extensions declared against custom resource types + are encoded even if they have no value. Thanks to David Hay of Orion for + reporting this! + + + Fix: RESTful server deployed to a location where the URL to access it contained a + space (e.g. a WAR file with a space in the name) failed to work correctly. + Thanks to David Hay of Orion for reporting this! + +
    + + + BREAKING CHANGE:]]>: IdDt has been modified so that it + contains a partial or complete resource identity. Previously it contained + only the simple alphanumeric id of the resource (the part at the end of the "read" URL for + that resource) but it can now contain a complete URL or even a partial URL (e.g. "Patient/123") + and can optionally contain a version (e.g. "Patient/123/_history/456"). New methods have + been added to this datatype which provide just the numeric portion. See the JavaDoc + for more information. + + + API CHANGE:]]>: Most elements in the HAPI FHIR model contain + a getId() and setId() method. This method is confusing because it is only actually used + for IDREF elements (which are rare) but its name makes it easy to confuse with more + important identifiers. For this reason, these methods have been deprocated and replaced with + get/setElementSpecificId() methods. The old methods will be removed at some point. Resource + types are unchanged and retain their get/setId methods. + + + Allow use of QuantityDt as a service parameter to support the "quantity" type. Previously + QuantityDt did not implement IQueryParameterType so it was not valid, and there was no way to + support quantity search parameters on the server (e.g. Observation.value-quantity) + + + Introduce StringParameter type which can be used as a RESTful operation search parameter + type. StringParameter allows ":exact" matches to be specified in clients, and handled in servers. + + + Parsers (XML/JSON) now support deleted entries in bundles + + + Transaction method now supported in servers + + + Support for Binary resources added (in servers, clients, parsers, etc.) + + + Support for Query resources fixed (in parser) + + + Nested contained resources (e.g. encoding a resource with a contained resource that itself contains a resource) + now parse and encode correctly, meaning that all contained resources are placed in the "contained" element + of the root resource, and the parser looks in the root resource for all container levels when stitching + contained resources back together. + + + Server methods with @Include parameter would sometimes fail when no _include was actually + specified in query strings. + + + Client requests for IdentifierDt types (such as Patient.identifier) did not create the correct + query string if the system is null. + + + Add support for paging responses from RESTful servers. + + + Don't fail on narrative blocks in JSON resources with only an XML declaration but no content (these are + produced by the Health Intersections server) + + + Server now automatically compresses responses if the client indicates support + + + Server failed to support optional parameters when type is String and :exact qualifier is used + + + Read method in client correctly populated resource ID in returned object + + + Support added for deleted-entry by/name, by/email, and comment from Tombstones spec + + + + + + + + + +
    diff --git a/src/changes/changes_BASE_31097.xml b/src/changes/changes_BASE_31097.xml new file mode 100644 index 00000000000..eb1aeb24464 --- /dev/null +++ b/src/changes/changes_BASE_31097.xml @@ -0,0 +1,2779 @@ + + + + James Agnew + HAPI FHIR Changelog + + + + + JSON parsing in HAPI FHIR has been switched from using JSR353 (javax.json) to + using Google Gson. For this reason we are bumping the major release number to + 2.0. Theoretically this should not affect projects in any major way, but Gson + does have subtle differences. Two differences which popped up a fair bit in + our own testing: + +
      + A space is placed after the : in keys, e.g. what was previously + encoded as "resourceType":"Patient" is now encoded + as "resourceType": "Patient" (this broke a number of + our unit tests with hardcoded resource definitions) +
    +
      + Trailing content after a valid json resource is rejected by + Gson (it was ignored by the Glassfish parser we were previously + using even though it was invalid) +
    + + ]]> +
    + + STU3 structure definitions have been updated to the + STU3 ballot candidate versions (1.5.0 - SVN 9395) + + + Both client and server now support the new Content Types decided in + FHIR #10199]]>. +
    ]]> + This means that the server now supports + application/fhir+xml and application/fhir+json]]> + in addition to the older style + application/xml+fhir and application/json+fhir]]>. + In order to facilitate migration by implementors, the old style remains the default + for now, but the server will respond using the new style if the request contains it. The + client now uses an Accept]]> header value which requests both + styles with a preference given to the new style when running in DSTU3 mode. +
    ]]> + As a part of this change, the server has also been enhanced so that if a request + contains a Content-Type header but no Accept header, the response will prefer the + encoding specified by the Content-Type header. +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Logback (used in sample projects): 1.1.5 -> 1.1.7
  • +
  • Phloc Commons (used by schematron validator): 4.4.4 -> 4.4.5
  • +
  • Commons-IO: 2.4 -> 2.5
  • +
  • Apache HTTPClient: 4.5.1 -> 4.5.2
  • +
  • Apache HTTPCore: 4.4.4 -> 4.4.5
  • +
  • Jersey (JAX-RS tests): 2.22.2 -> 2.23.1
  • +
  • Spring (JPA, Web Tester): 4.3.0 -> 4.3.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.4
  • + + ]]> +
    + + + Fix issue in DSTU1 Bundle parsing where unexpected elements in the bundle resulted in a failure + to parse. + + + DSTU2 QuestionnaireResponse validator failed with an exception if the + QuestionnaireResponse contained certain groups with no content + + + Fluent client should ignore parameter values which are null instead of including + them as ?foo=null]]> + + + When using _elements]]> parameter on server, the server was not + automatically adding the SUBSETTED]]> tag as it should + + + JPA server should now automatically detect + if Hibernate Search (Lucene) is configured to be + disabled and will not attempt to use it. This + prevents a crash for some operations. + + + A new server interceptor "BanUnsupprtedHttpMethodsInterceptor" has been added + which causes the server to return an HTTP 405 if an unsupported HTTP + verb is received from the client + + + Fix an issue where resource IDs were not correctly set when using + DSTU2 HL7org structures with the JAX-RS module. Thanks to Carlo Mion + for the pull request! + + + hapi-fhir-testpage-overlay project contained an unneccesary + dependency on hapi-fhir-jpaserver-base module, which resulted in + projects using the overlay having a large number of unnneded + JARs included + + + It is not possible to configure both the parser and the context to + preserve versions in resource references (default behaviour is to + strip versions from references). Thanks to GitHub user @cknaap + for the suggestion! + + + Tag#setCode(String)]]> did not actually set the code it was supposed to + set. Thanks to Tim Tschampel for reporting! + + + JPA server's /Bundle]]> endpoint cleared + the Bundle.entry.fullUrl]]> field on stored + bundles, resulting in invalid content being saved. Thanks to Mirjam + Baltus for reporting! + + + JPA server now returns HTTP 200 instead of HTTP 404 for + conditional deletes which did not find any matches, + per FHIR-I decision. + + + Client that declares explicitly that it is searching/reading/etc for + a custom type did not automatically parse into that type. + + + Allow servers to specify the authentication realm of their choosing when + throwing an AuthenticationException. Thanks to GitHub user @allanbrohansen + for the suggestion! + + + Add a new client implementation which uses the + OkHttp]]> + library as the HTTP client implementation (instead of Apache HttpClient). + This is particularly useful for Android (where HttpClient is a pain) but + could also be useful in other places too. + Thanks to Matt Clarke of Orion Health for the contribution! + + + Fix a regression when parsing resources that have contained + resources, where the reference in the outer resource which + links to the contained resource sometimes did does not get + populated with the actual target resource instance. Thanks to + Neal Acharya for reporting! + + + hapi-fhir-cli upload-terminology command now has an argument + "-b FOO" that lets you add an authorization header in the form + Authorization: Bearer FOO]]> + + + Parser failed to successfully encode a custom resource + if it contained custom fields that also used custom + types. Thanks to GitHub user @sjanic for reporting! + +
    + + + Performance has been improved for the initial FhirContext + object creation by avoiding a lot of unnecessary reflection. HAPI FHIR + 1.5 had a regression compared to previous releases + and this has been corrected, but other improvements have been + made so that this release is faster than previous releases too. +
    ]]> + In addition, a new "deferred scan" mode has been implemented for + even faster initialization on slower environments (e.g. Android). + See the performance documentation]]> + for more information. +
    ]]> + The following shows our benchmarks for context initialization across several + versions of HAPI: + +
  • Version 1.4: 560ms
  • +
  • Version 1.5: 800ms
  • +
  • Version 1.6: 340ms
  • +
  • Version 1.6 (deferred mode): 240ms
  • + + ]]> +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Spring (JPA, Web Tester): 4.2.5 -> 4.3.0
  • +
  • Spring-Data (JPA): 1.9.2 -> 1.10.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.3
  • +
  • Jetty (CLI): 9.3.9 -> 9.3.10
  • + + ]]> +
    + + Remove some clases that were deprecated over a year ago and have + suitable replacements: + +
  • QualifiedDateParam has been removed, but DateParam may be used instead
  • +
  • PathSpecification has been removedm but Include may be used instead
  • + + ]]> +
    + + ResponseValidatingInterceptor threw an InternalErrorException (HTTP 500) for operations + that do not return any content (e.g. delete). Thanks to Mohammad Jafari for reporting! + + + REST server now throws an HTTP 400 instead of an HTTP 500 if an operation which takes + a FHIR resource in the request body (e.g. create, update) contains invalid content that + the parser is unable to parse. Thanks to Jim Steel for the suggestion! + + + Deprecate fluent client search operations without an explicit declaration of the + bundle type being used. This also means that in a client + .search()]]> + operation, the + .returnBundle(Bundle.class)]]> + needs to be the last statement before + .execute()]]> + + + Server now respects the parameter _format=application/xml+fhir"]]> + which is technically invalid since the + should be escaped, but is likely to be used. Also, + a parameter of _format=html]]> can now be used, which + forces SyntaxHighlightingInterceptor to use HTML even + if the headers wouldn't otherwise trigger it. + Thanks to Jim Steel for reporting! + + + Improve performance when parsing large bundles by fixing a loop over all of the + entries inthe bundle to stitch together cross-references, which was happening once + per entry instead of once overall. Thanks to Erick on the HAPI FHIR Google Group for + noticing that this was an issue! + + + JSON parser no longer allows the resource ID to be specified in an element called "_id" + (the correct one is "id"). Previously _id was allowed because some early FHIR examples + used that form, but this was never actually valid so it is now being removed. + + + JPA server now allows "forced IDs" (ids containing non-numeric, client assigned IDs) + to use the same logical ID part on different resource types. E.g. A server may now have + both Patient/foo and Obervation/foo on the same server.
    ]]> + Note that existing databases will need to modify index "IDX_FORCEDID" as + it is no longer unique, and perform a reindexing pass. +
    + + When serializing/encoding custom types which replace exsting choice fields by + fixing the choice to a single type, the parser would forget that the + field was a choice and would use the wrong name (e.g. "abatement" instead of + "abatementDateType"). Thanks to Yaroslav Kovbas for reporting and + providing a unit test! + + + JPA server transactions sometimes created an incorrect resource reference + if a resource being saved contained references that had a display value but + not an actual reference. Thanks to David Hay for reporting! + + + When performing a REST Client create or update with + Prefer: return=representation]]> set, + if the server does not honour the Prefer header, the client + will automatically fetch the resource before returning. Thanks + to Ewout Kramer for the idea! + + + DSTU3 structures now have + setFoo(List)]]> + and + setGetFooFirstRep()]]> + methods, bringing them back to parity with the HAPI + DSTU2 structures. Thanks to Rahul Somasunderam and + Claude Nanjo for the suggestions! + + + JPA server has now been refactored to use the + new FluentPath search parameter definitions + for DSTU3 resources. + + + RequestValidatingInterceptor and ResponseValidatingInterceptor + both have new method setIgnoreValidatorExceptions]]> + which causes validator exceptions to be ignored, rather than causing + processing to be aborted. + + + LoggingInterceptor on server has a new parameter + ${requestBodyFhir}]]> which logs the entire request body. + + + JAX-RS server module now supports DSTU3 resources (previously it only supported DSTU2). Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Generated conformance statements for DSTU3 servers did not properly reference their + OperationDefinitions. Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Properly handle null arrays when parsing JSON resources. Thanks to Subhro for + fixing this and providing a pull request! + + + STU3 validator failed to validate codes where the + code was a child code within the code system that contained it + (i.e. not a top level code). Thanks to Jon + Zammit for reporting! + + + Restore the setType method in the DSTU1 Bundle + class, as it was accidentally commented out. Thanks + to GitHub user @Virdulys for the pull request! + + + JPA server now supports composite search parameters + where the type of the composite parameter is + a quantity (e.g. Observation:component-code-component-value-quantity) + + + Remove the Remittance resource from DSTU2 + structures, as it is not a real resource and + was causing issues with interoperability + with the .NET client. + + + CLI tool cache feature (-c) for upload-example task sometimes failed + to write cache file and exited with an exception. + + + Fix error message in web testing UI when loading pages in a search + result for STU3 endpoints. + + + When encoding JSON resource, the parser will now always + ensure that XHTML narrative content has an + XHTML namespace declaration on the first + DIV tag. This was preventing validation for + some resources using the official validator + rules. + + + Server failed to invoke operations when the name + was escaped (%24execute instead of $execute). + Thanks to Michael Lawley for reporting! + + + JPA server transactions containing a bundle that has multiple entries + trying to delete the same resource caused a 500 internal error + + + JPA module failed to index search parameters that mapped to a Timing datatype, + e.g. CarePlan:activitydate + + + Add a new option to the CLI run-server command called --lowmem]]>. + This option disables some features (e.g. fulltext search) in order to allow the + server to start in memory-constrained environments (e.g Raspberry Pi) + + + When updating a resource via an update operation on the server, if the ID of the + resource is not present in the resource body but is present on the URL, this will + now be treated as a warning instead of as a failure in order to be a bit more + tolerant of errors. If the ID is present in the body but does not agree with the + ID in the URL this remains an error. + + + Server / JPA server date range search params (e.g. Encounter:date) now treat + a single date with no comparator (or the eq comparator) as requiring that the + value be completely contained by the range specified. Thanks to Chris Moesel + for the suggestion. + + + In server, if a parameter was annotated with the annotation, the + count would not appear in the self/prev/next links and would not actually be applied + to the search results by the server. Thanks to Jim Steele for letting us know! + + + Conditional update on server failed to process if the conditional URL did not have any + search parameters that did not start with an underscore. E.g. "Patient?_id=1" failed + even though this is a valid conditional reference. + + + JPA server can now be configured to allow external references (i.e. references that + point to resources on other servers). See + JPA Documentation]]> for information on + how to use this. Thanks to Naminder Soorma for the suggestion! + + + When posting a resource to a server that contains an invalid value in a boolean field + (e.g. Patient with an active value of "1") the server should return an HTTP 400, not + an HTTP 500. Thanks to Jim Steel for reporting! + + + Enable parsers to parse and serialize custom resources that contain custom datatypes. + An example has been added which shows how to do this + here]]> + + + JSON parser was incorrectly encoding resource language attribute in JSON as an + array instead of a string. Thanks to David Hay for reporting! + + + Sébastien Rivière contributed an excellent pull request which adds a + number of enhancements to JAX-RS module: + +
  • Enable the conditional update and delete
  • +
  • Creation of a bundle provider, and support of the @Transaction
  • +
  • Bug fix on the exceptions handling as some exceptions throw outside bean context were not intercept.
  • +
  • Add the possibility to have the stacktrace in the jaxrsException
  • + + ]]> +
    + + FhirTerser.cloneInto method failed to clone correctly if the source + had any extensions. Thanks to GitHub user @Virdulys for submitting and + providing a test case! + + + Update DSTU2 InstanceValidator to latest version from upstream + + + Web Testing UI was not able to correctly post an STU3 transaction + + + DateTime parser incorrectly parsed times where more than 3 digits of + precision were provided on the seconds after the decimal point + + + Improve error messages when the $validate operation is called but no resource + is actually supplied to validate + + + DSTU2+ servers no longer return the Category header, as this has been + removed from the FHIR specification (and tags are now available in the + resource body so the header was duplication/wasted bandwidth) + + + Create and Update operations in server did not + include ETag or Last-Modified headers even though + the spec says they should. Thanks to Jim Steel for + reporting! + + + Update STU3 client and server to use the new sort parameter style (param1,-param2,param). Thanks to GitHub user @euz1e4r for + reporting! + + + QuantityClientParam#withUnit(String) put the unit into the system part of the + parameter value + + + Fluent client searches with date parameters were not correctly using + new prefix style (e.g. gt) instead of old one (e.g. >) + + + Some built-in v3 code systems for STU3 resources were missing + certain codes, which caused false failures when validating + resources. Thanks to GitHub user @Xoude for reporting! + + + Some methods on DSTU2 model structures have JavaDocs that + incorrectly claim that the method will not return null when + in fact it can. Thanks to Rick Riemer for reporting! + + + ResponseHighlightingInterceptor has been modified based on consensus + on Zulip with Grahame that requests that have a parameter of + _format=json]]> or + _format=xml]]> will output raw FHIR content + instead of HTML highlighting the content as they previously did. + HTML content can now be forced via the (previously existing) + _format=html]]> or via the two newly added + values + _format=html/json]]> and + _format=html/xml]]>. Because of this + change, the custom + _raw=true]]> mode has been deprecated and + will be removed at some point. + + + Operation definitions (e.g. for $everything operation) in the generated + server conformance statement should not include the $ prefix in the operation + name or code. Thanks to Dion McMurtrie for reporting! + + + Server generated OperationDefinition resources did not validate + due to some missing elements (kind, status, etc.). + Thanks to + Michael Lawley for reporting! + + + Operations that are defined on multiple resource provider types with + the same name (e.g. "$everything") are now automatically exposed by the server + as separate OperationDefinition resources per resource type. Thanks to + Michael Lawley for reporting! + + + OperationDefinition resources generated automatically by the server for operations + that are defined within resource/plain providers incorrectly stated that + the maximum cardinality was "*" for non-collection types with no explicit + maximum stated, which is not the behaviour that the JavaDoc on the + annotation describes. Thanks to Michael Lawley + for reporting! + + + Server parameters annotated with + @Since]]> + or + @Count]]> + which are of a FHIR type such as IntegerDt or DateTimeType will + now be set to null if the client's URL does not + contain this parameter. Previously they would be populated + with an empty instance of the FHIR type, which was inconsistent with + the way other server parameters worked. + + + Server now supports the _at parameter (including multiple repetitions) + for history operation + + + + AuthorizationInterceptor can now allow or deny requests to extended + operations (e.g. $everything) + + + DecimalType used BigDecimal constructor instead of valueOf method to + create a BigDecimal from a double, resulting in weird floating point + conversions. Thanks to Craig McClendon for reporting! + + + Remove the depdendency on a method from commons-lang3 3.3 which was + causing issues on some Android phones which come with an older version + of this library bundled. Thanks to Paolo Perliti for reporting! + + + Parser is now better able to handle encoding fields which have been + populated with a class that extends the expected class + + + When declaring a child with + order=Child.REPLACE_PARENT]]> + the serialized form still put the element at the + end of the resource instead of in the correct + order + + + Fix STU3 JPA resource providers to allow validate operation + at instance level + +
    + + + Security Fix: XML parser was vulnerable to XXE (XML External Entity) + processing, which could result in local files on disk being disclosed. + See this page]]> + for more information. + Thanks to Jim Steel for reporting! + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.7 -> 5.1.0
  • +
  • Spring (JPA, Web Tester): 4.2.4 -> 4.2.5
  • +
  • SLF4j (All): 1.7.14 -> 1.7.21
  • + + ]]> +
    + + Support comments when parsing and encoding both JSON and XML. Comments are retrieved + and added to the newly created methods + IBase#getFormatCommentsPre() and + IBase#getFormatCommentsPost() + + + Added options to the CLI upload-examples command which allow it to cache + the downloaded content file, or use an arbitrary one. Thanks to Adam Carbone + for the pull request! + + + REST search parameters with a prefix/comparator had not been updated to use + the DSTU2 style prefixes (gt2011-01-10) instead of the DSTU1 style prefixes + (>2011-01-01). The client has been updated so that it uses the new prefixes + if the client has a DSTU2+ context. The server has been updated so that it now + supports both styles. +
    ]]> + As a part of this change, a new enum called + ParamPrefixEnum]]> + has been introduced. This enum replaces the old + QuantityCompararatorEnum]]> + which has a typo in its name and can not represent several new prefixes added since + DSTU1. +
    + + JPA server number and quantity search params now follow the rules for the + use of precision in search terms outlined in the + search page]]> of the + FHIR specification. For example, previously a 1% tolerance was applied for + all searches (10% for approximate search). Now, a tolerance which respects the + precision of the search term is used (but still 10% for approximate search). + + + Fix a failure starting the REST server if a method returns an untyped List, which + among other things prevented resource provider added to the server + as CDI beans in a JBoss enviroment. Thanks to GitHub user fw060 (Fei) for + reporting and figuring out exactly why this wasn't working! + + + JPA server now supports :above and :below qualifiers on URI search params + + + Add optional support (disabled by default for now) to JPA server to support + inline references containing search URLs. These URLs will be resolved when + a resource is being created/updated and replaced with the single matching + resource. This is being used as a part of the May 2016 Connectathon for + a testing scenario. + + + The server no longer adds a + WWW-Authenticate]]> + header to the response if any resource provider code throws an + AuthenticationException]]>. This header is + used for interactive authentication, which isn't generally + appropriate for FHIR. We added code to add this header a long time + ago for testing purposes and it never got removed. Please let us + know if you need the ability to add this header automatically. Thanks + to Lars Kristian Roland for pointing this out. + + + In the client, the create/update operations on a Binary resource + (which use the raw binary's content type as opposed to the FHIR + content type) were not including any request headers (Content-Type, + User-Agent, etc.) Thanks to Peter Van Houte of Agfa Healthcare for + reporting! + + + Handling of Binary resources containing embedded FHIR resources for + create/update/etc operations has been corrected per the FHIR rules + outlined at + Binary Resource]]> + in both the client and server. +
    ]]> + Essentially, if the Binary contains something + that isn't FHIR (e.g. an image with an image content-type) the + client will send the raw data with the image content type to the server. The + server will place the content type and raw data into a Binary resource instance + and pass those to the resource provider. This part was already correct previous + to 1.5. +
    ]]> + On the other hand, if the Binary contains a FHIR content type, the Binary + is now sent by the client to the server as a Binary resource with a FHIR content-type, + and the embedded FHIR content is contained in the appropriate fields. The server + will pass this "outer" Binary resource to the resource provider code. +
    + + The RequestDetails and ActionRequestDetails objects which are passed to + server interceptor methods and may also be used as server provider method + arguments now has a new method + Map<String, String> getUserData() + ]]> + which can be used to pass data and objects between interceptor methods to + to providers. This can be useful, for instance, if an authorization + interceptor wants to pass the logged in user's details to other parts + of the server. + + + IServerInterceptor#incomingRequestPreHandled() is called + for a @Validate method, the resource was not populated in the + ActionRequestDetails argument. Thanks to Ravi Kuchi for reporting! + ]]> + + + [baseUrl]/metadata with an HTTP method + other than GET (e.g. POST, PUT) should result in an HTTP 405. Thanks to + Michael Lawley for reporting! + ]]> + + + Fix a server exception when trying to automatically add the profile tag + to a resource which already has one or more profiles set. Thanks to + Magnus Vinther for reporting! + + + QuantityParam parameters being used in the RESTful server were ignoring + the + :missing]]> + qualifier. Thanks to Alexander Takacs for reporting! + + + Annotation client failed with an exception if the response contained + extensions on fields in the resonse Bundle (e.g. Bundle.entry.search). + Thanks to GitHub user am202 for reporting! + + + Primitive elements with no value but an extension were sometimes not + encoded correctly in XML, and sometimes not parsed correctly in JSON. + Thanks to Bill de Beaubien for reporting! + + + The Web Testing UI has long had an issue where if you click on a button which + navigates to a new page (e.g. search, read, etc) and then click the back button + to return to the original page, the button you clicked remains disabled and can't + be clicked again (on Firefox and Safari). This is now fixed. Unfortunately the fix means that the + buttom will no longer show a "loading" spinner, but there doesn't seem to + be another way of fixing this. Thanks to Mark Scrimshire for reporting! + + + Extensions found while parsing an object that doesn't support extensions are now + reported using the IParserErrorHandler framework in the same way that + other similar errors are handled. This allows the parser to be more lenient + when needed. + + + Improve error message if incorrect type is placed in a list field in the data model. Java + uses generics to prevent this at compile time, but if someone is in an environment without + generics this helps improve the error message at runtime. Thanks to Hugo Soares for + suggesting. + + + Prevent an unneeded warning when parsing a resource containing + a declared extension. Thanks to Matt Blanchette for reporting! + + + Web Tester UI did not invoke VRead even if a version ID was specified. Thanks + to Poseidon for reporting! + + + Per discussion on the FHIR implementer chat, the JPA server no + longer includes _revinclude matches in the Bundle.total count, or the + page size limit. + + + JPA server now persists search results to the database in a new table where they + can be temporaily preserved. This makes the JPA server much more scalable, since it + no longer needs to store large lists of pages in memory between search invocations. +
    ]]> + Old searches are deleted after an hour by default, but this can be changed + via a setting in the DaoConfig. +
    + + JPA servers' resource version history mechanism + has been adjusted so that the history table + keeps a record of all versions including the + current version. This has the very helpful + side effect that history no longer needs to be + paged into memory as a complete set. Previously + history had a hard limit of only being able to + page the most recent 20000 entries. Now it has + no limit. + + + JPA server returned the wrong Bundle.type value (COLLECTION, should be SEARCHSET) + for $everything operation responses. Thanks to Sonali Somase for reporting! + + + REST and JPA server should reject update requests where the resource body does not + contain an ID, or contains an ID which does not match the URL. Previously these + were accepted (the URL ID was trusted) which is incorrect according to the + FHIR specification. Thanks to GitHub user ametke for reporting! +
    ]]> + As a part of this change, server error messages were also improved for + requests where the URL does not contain an ID but needs to (e.g. for + an update) or contains an ID but shouldn't (e.g. for a create) +
    + + When fields of type BoundCodeDt (e.g. Patient.gender) + are serialized and deserialized using Java's native + object serialization, the enum binder was not + serialized too. This meant that values for the + field in the deserialized object could not be + modified. Thanks to Thomas Andersen for reporting! + + + REST Server responded to HTTP OPTIONS requests with + any URI as being a request for the server's + Conformance statement. This is incorrect, as only + a request for OPTIONS [base url]]]> should be treated as such. Thanks to Michael Lawley for reporting! + + + REST annotation style client was not able to handle extended operations + ($foo) where the response from the server was a raw resource instead + of a Parameters resource. Thanks to Andrew Michael Martin for reporting! + + + JPA server applies _lastUpdated filter inline with other searches wherever possible + instead of applying this filter as a second query against the results of the + first query. This should improve performance when searching against large + datasets. + + + Parsers have new method + setDontEncodeElements]]> + which can be used to force the parser to not encode certain elements + in a resource when serializing. For example this can be used to omit + sensitive data or skip the resource metadata. + + + JPA server database design has been adjusted + so that different tables use different sequences + to generate their indexes, resulting in more sequential + resource IDs being assigned by the server + + + Server now correctly serves up Binary resources + using their native content type (instead of as a + FHIR resource) if the request contains an accept + header containing "application/xml" as some browsers + do. + + + DSTU2 resources now have a + getMeta()]]> method which returns a + modifiable view of the resource metadata for convenience. This + matches the equivalent method in the DSTU3 structures. + + + Add a new method to FhirContext called + setDefaultTypeForProfile + ]]> + which can be used to specify that when recources are received which declare + support for specific profiles, a specific custom structures should be used + instead of the default. For example, if you have created a custom Observation + class for a specific profile, you could use this method to cause your custom + type to be used by the parser for resources in a search bundle you receive. +
    + See the documentation page on + Profiles and Extensions + for more information. + ]]> +
    + + Parsing/Encoding a custom resource type which extends a + base type sometimes caused the FhirContext to treat all future + parses of the same resource as using the custom type even when + this was not wanted. +
    ]]> + Custom structures may now be explicitly declared by profile + using the + setDefaultTypeForProfile + ]]> + method. +
    ]]> + This issue was discovered and fixed as a part of the implementation of issue #315. +
    + + Set up the tinder plugin to work as an ant task + as well as a Maven plugin, and to use external + sources. Thanks to Bill Denton for the pull + request! + + + JPA server now allows searching by token + parameter using a system only and no code, + giving a search for any tokens which match + the given token with any code. Previously the + expected behaviour for this search + was not clear in the spec and HAPI had different + behaviour from the other reference servers. + + + Introduce a JAX-RS client provider which can be used instead of the + default Apache HTTP Client provider to provide low level HTTP + services to HAPI's REST client. See + JAX-RS & Alternate HTTP Client Providers]]> + for more information. +
    ]]> + This is useful in cases where you have other non-FHIR REST clients + using a JAX-RS provider and want to take advantage of the + rest of the framework. +
    ]]> + Thanks to Peter Van Houte from Agfa for the amazing work! +
    + + Parser failed with a NPE while encoding resources if the + resource contained a null extension. Thanks to + steve1medix for reporting! + + + In generated model classes (DSTU1/2) don't + use BoundCodeDt and BoundCodeableConceptDt for + coded fields which use example bindings. Thanks + to GitHub user Ricq for reporting! + + + @Operation will now infer the maximum number of repetitions + of their parameters by the type of the parameter. Previously if + a default max() value was not specified in the + @OperationParam annotation on a parameter, the maximum + was assumed to be 1. Now, if a max value is not explicitly specified + and the type of the parameter is a basic type (e.g. StringDt) the + max will be 1. If the parameter is a collection type (e.g. List<StringDt>) + the max will be * + ]]> + + + @Operation + may now use search parameter types, such as + TokenParam and + TokenAndListParam as values. Thanks to + Christian Ohr for reporting! + ]]> + + + Add databases indexes to JPA module search index tables + for the RES_ID column on each. This should help + performance when searching over large datasets. + Thanks to Emmanuel Duviviers for the suggestion! + + + DateTimeType should fail to parse 1974-12-25+10:00 as this is not + a valid time in FHIR. Thanks to Grahame Grieve for reporting! + + + When parsing a Bundle resource, if the Bundle.entry.request.url contains a UUID + but the resource body has no ID, the Resource.id will be populated with the ID from the + Bundle.entry.request.url. This is helpful when round tripping Bundles containing + UUIDs. + + + When parsing a DSTU3 bundle, references between resources did not have + the actual resource instance populated into the reference if the + IDs matched as they did in DSTU1/2. + + + Contained resource references on DSTU3 + resources were not serialized correctly when + using the Json Parser. Thanks to GitHub user + @fw060 for reporting and supplying a patch + which corrects the issue! + + + DSTU3 model classes equalsShallow and equalsDeep both did not work + correctly if a field was null in one object, but contained an empty + object in the other (e.g. a StringType with no actual value in it). These + two should be considered equal, since they would produce the exact same + wire format.
    ]]> + Thanks to GitHub user @ipropper for reporting and providing + a test case! +
    + + JPA server now supports searching for _tag:not=[tag]]]> + which enables finding resources that to not have a given tag/profile/security tag. + Thanks to Lars Kristian Roland for the suggestion! + + + Extensions containing resource references did not get encoded correctly + some of the time. Thanks to Poseidon for reporting! + + + Parsers (both XML and JSON) encoded the first few elements of DSTU3 structures in the wrong order: + Extensions were placed before any other content, which is incorrect (several + elements come first: meta, text, etc.) + + + In server implementations, the Bundle.entry.fullUrl was not getting correctly + populated on Hl7OrgDstu2 servers. Thanks to Christian Ohr for reporting! + + + Ensure that element IDs within resources (i.e. IDs on elements other than the + resource itself) get serialized and parsed correctly. Previously, these didn't get + serialized in a bunch of circumstances. Thanks to Vadim Peretokin for reporting + and providing test cases! + + + Improve CLI error message if the tool can't bind to the requested port. Thanks + to Claude Nanjo for the suggestion! + + + Server param of _summary=text]]> did not + include mandatory elements in return as well as + the text element, even though the FHIR specification + required it. + + + Remove invalid resource type "Documentation" from DSTU2 + structures. + + + JPA server did not respect target types for search parameters. E.g. Appointment:patient has + a path of "Appointment.participant.actor" and a target type of "Patient". The search path + was being correctly handled, but the target type was being ignored. + + + RestfulServer now manually parses URL parameters instead of relying on the container's + parsed parameters. This is useful because many Java servlet containers (e.g. Tomcat, Glassfish) + default to ISO-8859-1 encoding for URLs insetad of the UTF-8 encoding specified by + FHIR. + + + ResponseHighlightingInterceptor now doesn't highlight if the request + has an Origin header, since this probably denotes an AJAX request. + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.3 -> 5.0.7
  • +
  • Springframework (JPA, Web Tester): 4.2.2 -> 4.2.4
  • +
  • Phloc-Commons (Schematron Validator): 4.3.6 -> 4.4.4
  • +
  • Apache httpclient (Client): 4.4 -> 4.5.1
  • +
  • Apache httpcore (Client): 4.4 -> 4.4.4
  • +
  • SLF4j (All): 1.7.13 -> 1.7.14
  • + + ]]> +
    + + Remove a dependency on a Java 1.7 class + (ReflectiveOperationException) in several spots in the + codebase. This dependency was accidentally introduced in + 1.3, and animal-sniffer-plugin failed to detect it (sigh). + + + Add two new server interceptors: + RequestValidatingInterceptor + and + ResponseValidatingInterceptor + ]]> + which can be used to validate incoming requests or outgoing responses using the standard FHIR validation + tools. See the + Server Validation Page + ]]> + for examples of how to use these interceptors. These intereptors have both + been enabled on the + public test page. + ]]> + + + Make IBoundCodeableConcept and IValueSetEnumBinder serializable, + fixing an issue when trying to serialize model classes containing + bound codes. Thanks to Nick Peterson for the Pull Request! + + + Introduce a JAX-RS version of the REST server, which can be used + to deploy the same resource provider implementations which work + on the existing REST server into a JAX-RS (e.g. Jersey) environment. + Thanks to Peter Van Houte from Agfa for the amazing work! + + + CLI now supports writing to file:// URL for 'upload-examples' command + + + GZipped content is now supported for client-to-server uploads (create, update, transaction, etc.). + The server will not automatically detect compressed incoming content and decompress it (this can be + disabled using a RestfulServer configuration setting). A new client interceptor has been added + which compresses outgoing content from the client. + + + JPA server transaction attempted to validate resources twice each, + with one of these times being before anything had been committed to the + database. This meant that if a transaction contained both a Questionnaire + and a QuestionnaireResponse, it would fail because the QuestionnaireResponse + validator wouldn't be able to find the questionnaire. This is now corrected. + + + Add a new method to the generic/fluent client for searching: + .count(int)
    ]]> + This replaces the existing ".limitTo(int)" method which has + now been deprocated because it was badly named and undocumented. +
    + + Profile validator has been configured to allow extensions even if they + aren't explicitly declared in the profile. + + + Add a constraint that the Maven build will only run in JDK 8+. HAPI + remains committed to supporting JDK 6+ in the compiled library, but these + days it can only be built using JDK 8. Thanks to joelsch for the PR! + + + When serializing a value[x] field, if the value type was a profiled type (e.g. markdown is a + profile of string) HAPI 1.3 would use the base type in the element name, e.g. + valueString instead of valueMarkdown. After discussion with Grahame, this appears to + be incorrect behaviour so it has been fixed. + + + Support target parameter type in _include / _revinclude values, e.g. + _include=Patient:careProvider:Organization. Thanks to Joe Portner + for reporting! + + + Use ResponseHighlighterInterceptor in the hapi-fhir-jpaserver-example + project to provide nice syntax highlighting. Thanks to Rob Hausam for + noting that this wasn't there. + + + Introduce custom @CoverageIgnore annotation to hapi-fhir-base in order to + remove dependency on cobertura during build and in runtime. + + + Server-generated conformance statements incorrectly used /Profile/ instead + of /StructureDefinition/ in URL links to structures. + + + JsonParser has been changed so that when serializing numbers it will use + plain format (0.001) instead of scientific format (1e-3). The latter is + valid JSON, and the parser will still correctly parse either format (all + clients should be prepared to) but this change makes serialized + resources appear more consistent between XML and JSON. As a result of this + change, trailing zeros will now be preserved when serializing as well. + + + Add DSTU3 example to hapi-fhir-jpaserver-example. Thanks to Karl + Davis for the Pull Request! + + + RestfulServer#setUseBrowserFriendlyContentTypes has been deprecated and its + functionality removed. The intention of this feature was that if it + detected a request coming in from a browser, it would serve up JSON/XML + using content types that caused the browsers to pretty print. But + each browser has different rules for when to pretty print, and + after we wrote that feature both Chrome and FF changed their rules to break it anyhow. + ResponseHighlightingInterceptor provides a better implementation of + this functionality and should be used instead. + + + Narrative generator framework has removed the + ability to generate resource titles. This + functionality was only useful for DSTU1 + implementations and wasn't compatible + with coming changes to that API. + + + Remove dependency on Servlet-API 3.0+ by using methods available in 2.5 where possible. + Note that we continue to use Servlet-API 3.0+ features in some parts of the JPA API, so + running in an old serlvet container should be tested well before use. Thanks to Bill Denton + for reporting! + + + Add new methods to RestfulClientFactory allowing you to configure the size of the + client pool used by Apache HttpClient. Thanks to Matt Blanchette for the pull + request! + + + Add support for new modifier types on Token search params in Server and + annotation client. + + + Server conformance statement should include search parameter chains if the + chains are explicitly defined via @Search(whitelist={....}). Thanks to lcamilo15 + for reporting! + + + Remove afterPropertiesSet() call in Java config for JPA + server's EntityManagerFactory. This doesn't need to be called + manually, the the manual call led to a warning about + the EntityManager being created twice. + + + Allow server to correctly figure out it's own address even if the container provides + a Servlet Context Path which does not include the root. Thanks to Petro Mykhaylyshyn + for the pull request! + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Commons-lang3 (Core): 3.3.2 -> 3.4
  • +
  • Logback (Core): 1.1.2 -> 1.1.3
  • +
  • SLF4j (Core): 1.7.102 -> 1.7.12
  • +
  • Springframework (JPA, Web Tester): 4.1.5 -> 4.2.2
  • +
  • Hibernate (JPA, Web Tester): 4.2.17 -> 5."
  • +
  • Hibernate Validator (JPA, Web Tester): 5.2.1 -> 5.2.2
  • +
  • Derby (JPA, CLI, Public Server): 10.11.1.1 -> 10.12.1.1
  • +
  • Jetty (JPA, CLI, Public Server): 9.2.6.v20141205 -> 9.3.4.v20151007
  • + + ]]> +
    + + JPA and Tester Overlay now use Spring Java config files instead + of the older XML config files. All example projects have been updated. + + + JPA server removes duplicate resource index entries before storing them + (e.g. if a patient has the same name twice, only one index entry is created + for that name) + + + JPA server did not correctly index search parameters of type "reference" where the + path had multiple entries (i.e. "Resource.path1 | Resource.path2") + + + JPA server _history operations (server, type, instance) not correctly set the + Bundle.entry.request.method to POST or PUT for create and updates of the resource. + + + Support AND/OR on _id search parameter in JPA + + + Constructor for DateRanfeParam which dates in two DateParam instances was ignoring + comparators on the DateParam. + + + In JSON parsing, finding an object where an array was expected led to an unhelpful + error message. Thanks to Avinash Shanbhag for reporting! + + + JPA server gave an unhelpful error message if $meta-add or $meta-delete were called + with no meta elements in the input Parameters + + + Narrative generator did not include OperationOutcome.issue.diagnostics in the + generated narrative. + + + Clients (generic and annotation) did not populate the Accept header on outgoing + requests. This is now populated to indicate that the client supports both XML and + JSON unless the user has explicitly requested one or the other (in which case the + appropriate type only will be send in the accept header). Thanks to + Avinash Shanbhag for reporting! + + + QuestionnaireResponse validator now allows responses to questions of + type OPENCHOICE to be of type 'string' + + + JPA server should reject resources with a reference that points to an incorrectly typed + resource (e.g. points to Patient/123 but resource 123 is actually an Observation) or points + to a resource that is not valid in the location it is found in (e.g. points to Patient/123 but + the field supposed to reference an Organization). Thanks to Bill de Beaubien for reporting! + + + In server, if a client request is received and it has an Accept header indicating + that it supports both XML and JSON with equal weight, the server's default is used instead of the first entry in the list. + + + JPA server now supports searching with sort by token, quantity, + number, Uri, and _lastUpdated (previously only string, date, and _id + were supported) + + + Fix issue in JPA where a search with a _lastUpdated filter which matches no results + would crash if the search also had a _sort + + + Fix several cases where invalid requests would cause an HTTP 500 instead of + a more appropriate 400/404 in the JPA server (vread on invalid version, + delete with no ID, etc.) + + + Fix narrative generation for DSTU2 Medication resource + + + Profile validator now works for valuesets which use + v2 tables + + + JPA server Patient/[id]/$everything operation now supports + _lastUpdated filtering and _sort'ing of results. + + + Fix parser issue where profiled choice element datatypes (e.g. value[x] where one allowable + type is Duration, which is a profile of Quantity) get incorrectly encoded using the + profiled datatype name instead of the base datatype name as required by the FHIR + spec. Thanks to Nehashri Puttu Lokesh for reporting! + + + Some generated Enum types in DSTU2 HAPI structures + did not have latest valueset definitions applied. Thanks + to Bill de Beaubien for reporting! + + + JPA server can now successfully search for tokens pointing at code values + (values with no explicit system but an implied one, such as Patient.gender) + even if the system is supplied in the query. + + + Correct issues with Android library. Thanks to + Thomas Andersen for the submission! + + + JPA server incorrectly rejected match URLs + if they did not contain a question mark. Thanks + to Bill de Beaubien for reporting! + + + Remove invalid entries in OSGi Manifest. Thanks + to Alexander Kley for the fix! + + + JPA server now supports $everything on Patient and Encounter types (patient and encounter instance was already supported) + + + Generic client operation invocations now + have an additional inline method for generating the input + Parameters using chained method calls instead + of by passing a Parameters resource in + + + Parsing an XML resource where the XHTML + namespace was declared before the beginning + of the narrative section caused an invalid + re-encoding when encoding to JSON. + + + Conditional deletes in JPA did not correctly + process if the condition had a chain or a + qualifier, e.g. "Patient?organization.name" or + "Patient.identifier:missing" + + + Generic/fluent client search can now be + performed using a complete URL supplied + by user code. Thanks to Simone Heckmann + pointing out that this was needed! + + + Refactor JPA $everything operations so that + they perform better + + + Server operation methods can now declare the + ID optional, via + @IdParam(optional=true) + meaning that the same operation can also be invoked + at the type level. + + + Make JPA search queries with _lastUpdated parameter a bit more efficient + + + Clean up Android project to make it more lightweight and remove a + number of unneeded dependencies. Thanks to Thomas Andersen + for the pull request! + + + Fix a crash when encoding a Binary resource in JSON encoding + if the resource has no content-type + + + JPA server now supports read/history/search in transaction entries + by calling the actual implementing method in the server (previously + the call was simulated, which meant that many features did not work) + + + ResourceReferenceDt#loadResource(IRestfulClient) did not + use the client's read functionality, so it did not + handle JSON responses or use interceptors. Thanks to + JT for reporting! + + + JPA server maximumn length for a URI search parameter has been reduced from + 256 to 255 in order to accomodate MySQL's indexing requirements + + + Server failed to respond correctly to compartment search operations + if the same provider also contained a read operation. Thanks to GitHub user + @am202 for reporting! + + + Fix issue in testpage-overlay's new Java configuration where only the first + configured server actually gets used. + + + Introduce + IJpaServerInterceptor]]> + interceptors for JPA server which can be used for more fine grained operations. + + + Parser (XML and JSON) shouldn't encode an ID tag in resources + which are part of a bundle when the resource has a UUID/OID + ID. + + + Add ability for a server REST resource provider @Search method + to declare that it should allow even parameters it doesn't + understand. + + + Correctly set the Bundle.type value on all pages of a search result in + the server, and correcltly set the same value in JPA server $everything + results. + + + JPA $everything operations now support new parameters _content + and _text, which work the same way as the same parameters on a + search. This is experimental, since it is not a part of the core + FHIR specification. + + + Process "Accept: text/xml" and "Accept: text/json" headers was + wanting the equivalent FHIR encoding styles. These are not + correct, but the intention is clear so we will honour them + just to be helpful. + + + Generated Enum types for some ValueSets did not include all + codes (specifically, ValueSets which defined concepts containing + child concepts did not result in Enum values for the child concepts) + + + In the JPA server, order of transaction processing should be + DELETE, POST, PUT, GET, and the order should not matter + within entries with the same verb. Thanks to Bill de Beaubien + for reporting! + + + Add the ability to wire JPA conformance providers + using Spring (basically, add default constructors + and setters to the conformance providers). Thanks + to C. Mike Bylund for the pull request! + +
    + + + JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire + if one is declared. + + + SyntaxHighlightingInterceptor now also highlights OperationOutcome responses for errors/exceptions. + + + Model classes do not use BoundCodeableConcept for example bindings that do not + actually point to any codes (e.g. Observation.interpretation). Thanks + to GitHub user @steve1medix for reporting! + + + Server now exports operations as separate resources instead of as contained resources + within Conformance + + + Add new operation $get-resource-counts which will replace the resource + count extensions exported in the Conformance statement by the JPA + server. + + + JPA server sorting often returned unexpected orders when multiple + indexes of the same type were found on the same resource (e.g. multiple string indexed fields). Thanks to Travis Cummings for reporting! + + + Add another method to IServerInterceptor which converts an exception generated on the server + into a BaseServerResponseException. This is useful so that servers using ResponseHighlighterInterceptor + will highlight exceptions even if they aren't created with an OperationOutcome. + + + XmlParser and JsonParser in DSTU2 mode should not encode empty + tags in resource. Thanks to Bill De Beaubien for reporting! + + + OperationDefinitions generated by server did not properly document + their return parameters or the type of their input parameters. + + + Operations in server generated conformance statement should only + appear once per name, since the name needs to be unique. + + + Resources and datatypes are now serializable. This is an + experimental feature which hasn't yet been extensively tested. Please test and give us your feedback! + + + Switch REST server to using HttpServletRequest#getContextPath() to get + the servlet's context path. This means that the server should behave more + predictably, and should work in servlet 2.4 environments. Thanks to + Ken Zeisset for the suggestion! + + + Vagrant environment now has an apt recipt to ensure that + package lists are up to date. Thanks to GitHub user + Brian S. Corbin (@corbinbs) for thr contribution! + + + JPA server and generic client now both support the _tag search parameter + + + Add support for BATCH mode to JPA server transaction operation + + + Server was not correctly unescaping URL parameter values with + a trailing comma or an escaped backslash. Thanks to GitHub user + @SherryH for all of her help in diagnosing this issue! + + + Avoid crash when parsing if an invalid child element is found in + a resource reference. + + + Create new android specialty libraries for DSTU1 and DSTU2 + + + Throwing a server exception (e.g. AuthenticationException) in a server interceptor's + incomingRequestPreProcessed method resulted in the server returning an HTTP 500 instead + of the appropriate error code for the exception being thrown. Thanks to Nagesh Bashyam + for reporting! + + + Fix issue in JSON parser where invalid contained resources (missing + a resourceType element) fail to parse with a confusing NullPointerException. + Thanks to GitHub user @hugosoares for reporting! + + + JPA server now implements the $validate-code operation + + + HAPI-FHIR now has support for _summary and _elements parameters, in server, client, + and JPA server. + + + _revinclude results from JPA server should have a Bundle.entry.search.mode of + "include" and not "match". Thanks to Josh Mandel for reporting! + + + Resource references using resource instance objects instead of resource IDs + will correctly qualify the IDs with the resource type if they aren't already qualified + + + Testpage Overlay project now properly allows a custom client + factory to be used (e.g. for custom authentication, etc.) Thanks + to Chin Huang (@pukkaone) for the pull request! + + + JPA server should reject IDs containing invalid characters (e.g. "abc:123") + but should allow client assigned IDs that contain text but do not start with + text. Thanks to Josh Mandel for reporting! + + + :text modifier on server and JPA server did not work correctly. Thanks to + Josh Mandel for reporting! + + + Fix issue in client where parameter values containing a comma were + sometimes double escaped. + + + _include parameters now support the new _include:recurse=FOO]]> + syntax that has been introduced in DSTU2 in the Client, Server, and JPA Server modules. + Non-recursive behaviour is now the default (previously it was recursive) and :recurse + needs to be explicitly stated in order to support recursion. + + + New operations added to JPA server to force re-indexing of all + resources (really only useful after indexes change or bugs are + fixed) + + + JPA server did not correctly index search parameters + of type "URI". Thanks to David Hay for reporting! Note that if you are using the JPA server, this change means that + there are two new tables added to the database schema. Updating existing resources in the database may fail unless you + set default values for the resource + table by issuing a SQL command similar to the following (false may be 0 or something else, depending on the database platform in use) + update hfj_resource set sp_coords_present = false;
    + update hfj_resource set sp_uri_present = false;
    ]]> +
    + + FIx issue in JPA server where profile declarations, tags, and + security labels were not always properly removed by an update that + was trying to remove them. Also don't store duplicates. + + + Instance $meta operations on JPA server did not previously return the + resource version and lastUpdated time + + + Server responses populate Bundle.entry.fullUrl if possible. Thanks + to Bill de Beaubien for reporting! + + + XML parser failed to initialize in environments where a very old Woodstox + library is in use (earlier than 4.0). Thanks to Bill de Beaubien for + reporting! + + + Invalid/unexpected attributes found when parsing composite elements + should be logged or reported to the parser error handler + + + JPA server can now store Conformance resources, per a request + from David Hay + + + ResponseHighlightingInterceptor now skips handling responses if it + finds a URL parameter of _raw=true]]> (in other + words, if this parameter is found, the response won't be returned as + HTML even if the request is detected as coming from a browser. + + + RestfulServer now supports dynamically adding and removing resource providers + at runtime. Thanks to Bill Denton for adding this. + + + JPA server now correctly suppresses contents of deleted resources + in history + + + JPA server returned deleted resources in search results when using the _tag, _id, _profile, or _security search parameters + + + Fix issue with build on Windows. Thanks to Bryce van Dyk for the pull request! + + + JPA server now supports $validate operation completely, including delete mode + and profile validation using the RI InstanceValidator + +
    + + + Add support for reference implementation structures. + + + Parsers did not encode the resource meta element if the resource + had tags but no other meta elements. Thanks to Bill de Beaubien and + Claude Nanjo for finding this. + + + Correct performance issue with :missing=true search requests where the parameter is a resource link. Thanks to wanghaisheng for all his help in testing this. + + + The self link in the Bundle returned by searches on the server does not respect the + server's address strategy (which resulted in an internal IP being shown on fhirtest.uhn.ca) + + + Introduce ResponseHighlighterInterceptor, which provides syntax highlighting on RESTful server responses + if the server detects that the request is coming from a browser. This interceptor has been added + to fhirtest.uhn.ca responses. + + + Performing a create operation in a client used an incorrect URL if the + resource had an ID set. ID should be ignored for creates. Thanks to + Peter Girard for reporting! + + + Add better addXXX() methods to structures, which take the datatype being added as a parameter. Thanks to Claude Nanjo for the + suggestion! + + + Add a new parser validation mechanism (see the + validation page]]> for info) which can be + used to validate resources as they are being parsed, and optionally fail if invalid/unexpected + elements are found in resource bodies during parsing. + + + IParser#parseResource(Class, String) method, which is used to parse a resource into the given + structure will now throw a DataFormatException if the structure is for the wrong type of + resource for the one actually found in the input String (or Reader). For example, if a Patient + resource is being parsed into Organization.class this will now cause an error. Previously, + the XML parser would ignore the type and the JSON parser would fail. This also caused + operations to not parse correctly if they returned a resource type other than + parameters with JSON encoding (e.g. the $everything operation on UHN's test server). + Thanks to Avinash Shanbhag for reporting! + + + Web tester UI now supports _revinclude + + + Support link elements in Bundle.entry when parsing in DSTU2 mode + using the old (non-resource) Bundle class. Thanks to GitHub user + @joedai for reporting! + + + LoggingInterceptor for server now supports logging DSTU2 extended operations by name + + + Woodstox XML parser has a default setting to limit the maximum + length of an attribute to 512kb. This caused issues handling + large attachments, so this setting has been increased to 100Mb. + Thanks to Nikos Kyriakoulakos for reporting! + + + Some HTML entities were not correctly converted during parsing. Thanks to + Nick Kitto for reporting! + + + In the JPA Server: + Transactions creating resources with temporary/placeholder resource IDs + and other resources with references to those placeholder IDs previously + did not work if the reference did not contain the resource type + (e.g. Patient/urn:oid:0.1.2.3 instead of urn:oid:0.1.2.3). The + latter is actually the correct way of specifying a reference to a + placeholder, but the former was the only way that worked. Both forms + now work, in order to be lenient. Thanks to Bill De Beaubien for + reporting! + + + When parsing Bundles, if Bundle.entry.base is set to "cid:" (for DSTU1) + or "urn:uuid:" / "urn:oid:" (for DSTU2) this is now correctly passed as + the base in resource.getId(). Conversely, when + encoding bundles, if a resource ID has a base defined, + and Bundle.entry.base is empty, it will now be + automatically set by the parser. + + + Add fluent client method for validate operation, and support the + new DSTU2 style extended operation for $validate if the client is + in DSTU2 mode. Thanks to Eric from the FHIR Skype Implementers chat for + reporting. + + + Server now supports complete Accept header content negotiation, including + q values specifying order of preference. Previously the q value was ignored. + + + Server in DSTU2 mode now indicates that whether it has support for Transaction operation or not. Thanks to Kevin Paschke for pointing out that this wasn't working! + + + Questionnaire.title now gets correctly indexed in JPA server (it has no path, so it is a special case) + + + JPA server now supports ifNoneMatch in GET within a transaction request. + + + DateRangeParam now supports null values in the constructor for lower or upper bounds (but + still not both) + + + Generic/fluent client and JPA server now both support _lastUpdated search parameter + which was added in DSTU2 + + + JPA server now supports sorting on reference parameters. Thanks to + Vishal Kachroo for reporting that this wasn't working! + + + Prevent Last-Updated header in responses coming back to the client from + overwriting the 'lastUpdated' value in the meta element in DSTU2 + resources. This is important because 'lastUpdated' can have more + precision than the equivalent header, but the client previously + gave the header priority. + + + JPA server supports _count parameter in transaction containing search URL (nested search) + + + DSTU2 servers now indicate support for conditional create/update/delete in their + conformance statement. + + + Support for the Prefer header has been added to the server, client, and + JPA modules. + + + JPA server failed to search for deep chained parameters across multiple references, + e.g. "Location.partof.partof.organization". Thanks to Ismael Sarmento Jr for + reporting! + + + Prevent crash when encoding resources with contained resources + if the contained resources contained a circular reference to each other + + + Add $meta, $meta-add, and $meta-delete operations to generic client + + + + + Bump the version of a few dependencies to the + latest versions: + +
  • Phloc-commons (for schematron validation) 4.3.5 -> 4.3.6
  • +
  • Apache HttpClient 4.3.6 -> 4.4
  • +
  • Woodstox 4.4.0 -> 4.4.1
  • +
  • SLF4j 1.7.9 -> 1.7.10
  • +
  • Spring (used in hapi-fhir-jpaserver-base module) 4.1.3.RELEASE -> 4.1.5.RELEASE
  • + + ]]> +
    + + Add support for "profile" and "tag" elements in the resource Meta block + when parsing DSTU2 structures. + + + When a user manually creates the list of contained resources in a resource, + the encoder fails to encode any resources that don't have a '#' at the + start of their ID. This is unintuitive, so we now assume that '123' means '#123'. + Thanks to myungchoi for reporting and providing a test case! + + + Add methods for setting the default encoding (XML/JSON) and + oretty print behaviour in the Fluent Client. Thanks to Stackoverflow + user ewall for the idea. + + + JPA Server did not mark a resource as "no longer deleted" if it + was updated after being deleted. Thanks to Elliott Lavy and Lloyd + McKenzie for reporting! + + + Fix regression in 0.9 - Server responds with an HTTP 500 and a NullPointerException instead of an HTTP 400 and a useful error message if the client requests an unknown resource type + + + Add support for + _revinclude]]> + parameter in client, server, and JPA. + + + Include constants on resources (such as + Observation.INCLUDE_VALUE_STRING]]>) + have been switched in the DSTU2 structures to use + the new syntax required in DSTU2: [resource name]:[search param NAME] + insead of the DSTU1 style [resource name].[search param PATH] + + + When encoding resources, the parser will now convert any resource + references to versionless references automatically (i.e. it will + omit the version part automatically if one is present in the reference) + since references between resources must be versionless. Additionally, + references in server responses will omit the server base URL part of the + reference if the base matches the base for the server giving + the response. + + + Narrative generator incorrectly sets the Resource.text.status to 'generated' even if the + given resource type does not have a template (and therefore no narrative is actually generated). + Thanks to Bill de Beaubien for reporting! + + + Searching in JPA server with no search parameter returns deleted resources when it should exclude them. + + + Remove Eclipse and IntelliJ artifacts (.project, *.iml, etc) from version control. Thanks + to Doug Martin for the suggestion! + + + REST server methods may now have a parameter of + type NarrativeModeEnum which will be populated with + the value of the _narrative URL parameter + if one was supplied. Annotation client methods + may also include a parameter of this type, and it + will be used to populate this parameter on the request + URL if it is not null. Thanks to Neal Acharya for the + idea! + + + Android JAR now includes servlet-API classes, as the project will not + work without them. Thanks + + + Requested _include values are preserved across paging links when the + server returns multiple pages. Thanks to Bill de Beaubien for + reporting! + + + Add new server address strategy "ApacheProxyAddressStrategy" which uses + headers "x-forwarded-host" and "x-forwarded-proto" to determine the + server's address. This is useful if you are deploying a HAPI FHIR + server behind an Apache proxy (e.g. for load balancing or other reasons). + Thanks to Bill de Beaubien for contributing! + + + Resource references between separate resources found in a single + bundle did not get populated with the actual resource when parsing a + DSTU2 style bundle. Thanks to Nick Peterson for reporting and figuring + out why none of our unit tests were actually catching the problem! + + + JSON encoder did not encode contained resources when encoding + a DSTU2 style bundle. Thanks to Mohammad Jafari and baopingle + for all of their help in tracking this issue down and developing + useful unit tests to demonstrate it. + + + Client now supports invoking transcation using a DSTU2-style + Bundle resource as the input. + + + JPA Server $everything operation could sometimes include a duplicate copy of + the main focus resource if it was referred to in a deep chain. Thanks + to David Hay for reporting! + + + JPA Server $everything operation now allows a _count parameter + + + JPA server failed to index resources containing ContactPointDt elements with + populated values (e.g. Patient.telecom). Thanks to Mohammad Jafari for reporting! + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Terser's IModelVisitor now supplies to the path to the element. This is + an API change, but I don't think there are many users of the IModelVisitor yet. + Please let us know if this is a big hardship and we can find an alternate way + of making this change. + + + Prevent server from returning a Content-Location header for search + response when using the DSTU2 bundle format + + + JPA server (uhnfhirtest.uhn.ca) sometimes included an empty + "text" element in Bundles being returned. + + + Add a framework for the Web Tester UI to allow its internal FHIR client to + be configured (e.g. to add an authorization interceptor so that it adds + credentials to client requests it makes). Thanks to Harsha Kumara for + the suggestion! + + + Fix regression in early 1.0 builds where resource type sometimes does not get + populated in a resource ID when the resource is parsed. Thanks to + Nick Peterson for reporting, and for providing a test case! + + + Allow fluent/generic client users to execute a transaction using a raw string (containing a bundle resource) + as input instead of a Bundle resource class instance. + + + Disable date validation in the web tester UI, so that it is possible to + enter partial dates, or dates without times, or even test out invalid date + options. + + + Make BaseElement#getUndeclaredExtensions() and BaseElement#getUndeclaredExtensions() return + a mutable list so that it is possible to delete extensions from a resource instance. + + + Server conformance statement check in clients (this is the check + where the first time a given FhirContext is used to access a given server + base URL, it will first check the server's Conformance statement to ensure + that it supports the correct version of FHIR) now uses any + registered client interceptors. In addition, IGenericClient now has a method + "forceConformanceCheck()" which manually triggers this check. Thanks to + Doug Martin for reporting and suggesting! + + + Rename the Spring Bean definition for the JPA server EntityManager from + "myEntityManagerFactory" to just "entityManagerFactory" as this is the + default bean name expected in other parts of the Spring framework. + Thanks to Mohammad Jafari for the suggestion! + + + Improve error message when a user tries to perform a create/update with an invalid + or missing Content-Type header. Thanks to wanghaisheng for reporting! (This was + actually a three part bug, so the following two fixes also reference this + bug number) + + + Add support for :missing qualifier in generic/fluent client. + + + Add support for :missing qualifier in JPA server. + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Add an exception for RESTful clients/servers to represent the + HTTP 403 Forbidden status code. Thanks to Joel Costigliola for + the patch! + + + Transaction server operations incorrectly used the "Accept" header instead of the "Content-Type" header to determine the + POST request encoding. Thanks to Rene Spronk for providing a test case! + +
    + + + Support for DSTU2 features introduced: New resource definitions, Bundle resource, + encoding changes (ID in resource bodt, meta tag) + + + Fix an issue encoding extensions on primitive types in JSON. Previously the "_value" object + would be an array even if the field it was extending was not repeatable. This is not correct + according to the specification, nor can HAPI's parser parse this correctly. The encoder + has been corrected, and the parser has been adjusted to be able to handle resources with + extensions encoded in this way. Thanks to Mohammad Jafari for reporting! + + + Library now checks if custom resource types can be instantiated on startup + (e.g. because they don't have a no-argument constructor) in order to + avoid failing later + + + Bump a few dependency JARs to the latest versions in Maven POM: + +
  • SLF4j (in base module) - Bumped to 1.7.9
  • +
  • Apache HTTPClient (in base module) - Bumped to 4.3.6
  • +
  • Hibernate (in JPA module) - Bumped to 4.3.7
  • + + ]]> +
    + + IdDt failed to recognize local identifiers containing fragments that look like + real identifiers as being local identifiers even though they started with '#'. + For example, a local resource reference of "#aa/_history/aa" would be incorrectly + parsed as a non-local reference. + Thanks to Mohammad Jafari for reporting! + + + Last-Modified]]> + header in server was incorrectly using FHIR date format instead + of RFC-1123 format. + + + Server create and update methods failed with an IllegalArgumentException if + the method type was a custom resource definition type (instead of a built-in + HAPI type). Thanks to Neal Acharya for the analysis. + + + JPA server module now supports + _include]]> + value of + *]]>. Thanks to Bill de Beaubien for reporting! + + + IdDt method + + returned String (unlike all of the other "withFoo" methods on that class), + and did not work correctly if the IdDt already had a server base. This + has been corrected. Note that the return type for this method has been + changed, so code may need to be updated. + + + In previous versions of HAPI, the XML parser encoded multiple contained + resources in a single + <contained></contained>]]> + tag, even though the FHIR specification rerquires a separate + <contained></contained>]]> + tag for each resource. This has been corrected. Note that the parser will + correctly parse either form (this has always been the case) so this + change should not cause any breakage in HAPI based trading partners, but + may cause issues if other applications have been coded to depend on the + incorrect behaviour. Thanks to Mochaholic for reporting! + + + Custom/user defined resource definitions which contained more than one + child with no order defined failed to initialize properly. Thanks to + Andy Huang for reporting and figuring out where the + problem was! + + + RESTful Client now queries the server (only once per server base URL) to ensure that + the given server corresponds to the correct version of the FHIR specification, as + defined by the FhirContext. This behaviour can be disabled by setting the + appropriate configuration on the + RestfulClientConfig. Thanks to Grahame Grieve for the suggestion! + + + JPA module now supports deleting resource via transaction + + + DateClientParam#second() incorrectly used DAY precision instead + of SECOND precision. Thanks to Tom Wilson for the pull request! + + + Fix issue where HAPI failed to initialize correctly if Woodstox library was not on the classpath, even + if StAX API was configured to use a different provider. Thanks to + James Butler for reporting and figuring out where the issue was! + + + Calling BaseDateTimeDt#setValue(Date, TemporalPrecisionEnum) did not always actually respect + the given precision when the value was encoded. Thanks to jacksonjesse for + reporting! + + + Encoders (both XML and JSON) will no longer encode contained resources if they are + not referenced anywhere in the resource via a local reference. This is just a convenience + for users who have parsed a resource with contained resources and want to remove some + before re-encoding. Thanks to Alexander Kley for reporting! + + + Add support for DSTU2 style security labels in the parser and encoder. Thanks to + Mohammad Jafari for the contribution! + + + Server requests for Binary resources where the client has explicitly requested XML or JSON responses + (either with a _format]]> URL parameter, or an Accept]]> request header) + will be responded to using the Binary FHIR resource type instead of as Binary blobs. This is + in accordance with the recommended behaviour in the FHIR specification. + + + Add new properties to RestfulServer: "DefaultResponseEncoding", which allows + users to configure a default encoding (XML/JSON) to use if none is specified in the + client request. Currently defaults to XML. Also "DefaultPrettyPrint", which specifies + whether to pretty print responses by default. Both properties can be overridden + on individual requets using the appropriate Accept header or request URL parameters. + + + Add support for quantity search params in FHIR tester UI + + + Add support for FHIR "extended operations" as defined in the FHIR DSTU2 + specification, for the Generic Client, Annotation Client, and + Server. + + + Observation.applies[x] and other similar search fields with multiple allowable + value types were not being correctly indexed in the JPA server. + + + DateClientParam.before() incorrectly placed "<=" instead of + "<" in the request URL. Thanks to Ryan for reporting! + + + Server now only automatically adds _include resources which are provided + as references if the client request actually requested that specific include. + See RestfulServer + + + User defined resource types which contain extensions that use a bound code type + (e.g. an BoundCodeDt with a custom Enum) failed to parse correctly. Thanks + to baopingle for reporting and providing a test case! + + + Sorting is now supported in the Web Testing UI (previously a button existed for sorting, but it didn't do anything) + + + Server will no longer include stack traces in the OperationOutcome returned to the client + when an exception is thrown. A new interceptor called ExceptionHandlingInterceptor has been + created which adds this functionality back if it is needed (e.g. for DEV setups). See the + server interceptor documentation for more information. Thanks to Andy Huang for the suggestion! + +
    + + + API CHANGE:]]> The "FHIR structures" for DSTU1 (the classes which model the + resources and composite datatypes) have been moved out of the core JAR into their + own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast + version is finalized. See the + DSTU2 page]]> + for more information. + + + Deprocated API Removal: The following classes (which were deprocated previously) + have now been removed: +
      +
    • ISecurityManager: If you are using this class, the same functionality + is available through the more general purpose + server interceptor + capabilities. +
    • CodingListParam: This class was made redundant by the + TokenOrListParam + class, which can be used in its place. +
    + ]]> +
    + + API Change: The IResource#getResourceMetadata() method has been changed + from returning + Map<ResourceMetadataKeyEnum<?>, Object> + to returning a new type called + ResourceMetadataMap. This new type implements + Map<ResourceMetadataKeyEnum<?>, Object> + itself, so this change should not break existing code, but may + require a clean build in order to run correctly. + ]]> + + + Profile generation on the server was not working due to IdDt being + incorrectly used. Thanks to Bill de Beaubien for the pull request! + + + Profiles did not generate correctly if a resource definition class had a + defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request! + + + Remove unnecessary IOException from narrative generator API. Thanks to + Petro Mykhailysyn for the pull request! + + + Introduced a new + @ProvidesResources]]> annotation which can be added to + resource provider and servers to allow them to declare additional resource + classes they are able to serve. This is useful if you have a server which can + serve up multiple classes for the same resource type (e.g. a server that sometimes + returns a default Patient, but sometimes uses a custom subclass). + Thanks to Bill de Beaubien for the pull request! + + + Introduced a new + @Destroy]]> annotation which can be added to + a resource provider method. This method will be called by the server when it + is being closed/destroyed (e.g. when the application is being undeployed, the + container is being shut down, etc.) + Thanks to Bill de Beaubien for the pull request! + + + Add a new method to the server interceptor + framework which allows interceptors to be notified of any exceptions and + runtime errors within server methods. Interceptors may optionally also + override the default error handling behaviour of the RestfulServer. + + + Add constants to BaseResource for the "_id" search parameter which all resources + should support. + + + DateRangeParam parameters on the server now return correct + getLowerBoundAsInstant()]]> + and + getUpperBoundAsInstant()]]> + values if a single unqualified value is passed in. For example, if + a query containing + &birthdate=2012-10-01]]> + is received, previously these two methods would both return the same + value, but with this fix + getUpperBoundAsInstant()]]> + now returns the instant at 23:59:59.9999. + + + Resource fields with a type of "*" (or Any) sometimes failed to parse if a + value type of "code" was used. Thanks to Bill de Beaubien for reporting! + + + Remove dependency on JAXB libraries, which were used to parse and encode + dates and times (even in the JSON parser). JAXB is built in to most JDKs + but the version bundled with IBM's JDK is flaky and resulted in a number + of problems when deploying to Websphere. + + + Primitive datatypes now preserve their original string value when parsing resources, + as well as containing the "parsed value". For instance, a DecimalDt field value of + 1.0000]]> will be parsed into the corresponding + decimal value, but will also retain the original value with the corresponding + level of precision. This allows vadliator rules to be applied to + original values as received "over the wire", such as well formatted but + invalid dates, e.g. "2001-15-01". Thanks to Joe Athman for reporting and + helping to come up with a fix! + + + When using Generic Client, if performing a + or operation using a String as the resource body, + the client will auto-detect the FHIR encoding style and send an appropriate + header. + + + JPA module (and public HAPI-FHIR test server) were unable to process resource types + where at least one search parameter has no path specified. These now correctly save + (although the server does not yet process these params, and it should). Thanks to + GitHub user shvoidlee for reporting and help with analysis! + + + Generic/Fluent Client "create" and "update" method requests were not setting a content type header + + + DateDt left precision value as in the constructor + . + + + RESTful server now doesn't overwrite resource IDs if they are absolute. In other words, if + a server's Resource Provider returns a resource with ID "Patient/123" it will be translated to + "[base url]/Patient/123" but if the RP returns ID "http://foo/Patient/123" the ID will be + returned exactly as is. Thanks to Bill de Beaubien for the suggestion! + + + JPA module Transaction operation was not correctly replacing logical IDs + beginning with "cid:" with server assigned IDs, as required by the + specification. + + + did not visit or find children in contained resources when + searching a resource. This caused server implementations to not always return contained + resources when they are included with a resource being returned. + + + Add a method which returns the name of the + resource in question (e.g. "Patient", or "Observation"). This is intended as a + convenience to users. + + + Do not strip version from resource references in resources returned + from server search methods. Thanks to Bill de Beaubien for reporting! + + + Correct an issue with the validator where changes to the underlying + OperationOutcome produced by a validation cycle cause the validation + results to be incorrect. + + + Client interceptors registered to an interface based client instance + were applied to other client instances for the same client interface as well. (Issue + did not affect generic/fluent clients) + + + DateDt, DateTimeDt and types InstantDt types now do not throw an exception + if they are used to parse a value with the wrong level of precision for + the given type but do throw an exception if the wrong level of precision + is passed into their constructors.
    ]]> + This means that HAPI FHIR can now successfully parse resources from external + sources that have the wrong level of precision, but will generate a validation + error if the resource is validated. Thanks to Alexander Kley for the suggestion! +
    + + Encoding a Binary resource without a content type set should not result in a NullPointerException. Thanks + to Alexander Kley for reporting! + + + Server gives a more helpful error message if multiple IResourceProvider implementations + are provided for the same resource type. Thanks to wanghaisheng for the idea! + + + Bring DSTU1 resource definitions up to version 0.0.82-2929]]> + Bring DEV resource definitions up to 0.4.0-3775]]> + Thanks to crinacimpian for reporting! + + + JPA server did not correctly process _include requests if included + resources were present with a non-numeric identifier. Thanks to + Bill de Beaubien for reporting! + + + Client requests which include a resource/bundle body (e.g. create, + update, transaction) were not including a charset in the content type + header, leading to servers incorrectly assuming ISO-8859/1. Thanks to + shvoidlee for reporting! + + + Clean up the way that Profile resources are automatically exported + by the server for custom resource profile classes. See the + @ResourceDef]]> + JavaDoc for information on how this works. + + + Add convenience methods to TokenOrListParam to test whether any of a set of tokens match + the given requested list. + + + Add a protected method to RestfulServer which allows developers to + implement their own method for determining which part of the request + URL is the FHIR request path (useful if you are embedding the RestulServer inside + of another web framework). Thanks to Harsha Kumara for the pull request! + +
    + + + API CHANGE:]]> The TagList class previously implemented ArrayList semantics, + but this has been replaced with LinkedHashMap semantics. This means that the list of + tags will no longer accept duplicate tags, but that tag order will still be + preserved. Thanks to Bill de Beaubien for reporting! + + + Server was incorrectly including contained resources being returned as both contained resources, and as + top-level resources in the returned bundle for search operations. + Thanks to Bill de Beaubien for reporting! This also fixes Issue #20, thanks to + lephty for reporting! + + + Documentation fixes + + + Add a collection of new methods on the generic client which support the + read, + read, + and search + ]]> + operations using an absolute URL. This allows developers to perform these operations using + URLs they obtained from other sources (or external resource references within resources). In + addition, the existing read/vread operations will now access absolute URL references if + they are passed in. Thanks to Doug Martin of the Regenstrief Center for Biomedical Informatics + for contributing this implementation! + + + Server implementation was not correctly figuring out its own FHIR Base URL when deployed + on Amazon Web Service server. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + XML Parser failed to encode fields with both a resource reference child and + a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + HAPI now runs successfully on Servlet 2.5 containers (such as Tomcat 6). Thanks to + Bernard Gitaadji for reporting and diagnosing the issue! + + + Summary (in the bundle entry) is now encoded by the XML and JSON parsers if supplied. Thanks to David Hay of + Orion Health for reporting this! + + + Conformance profiles which are automatically generated by the server were missing a few mandatory elements, + which meant that the profile did not correctly validate. Thanks to Bill de Beaubien of Systems Made Simple + for reporting this! + + + XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters + escaped properly in encoded messages. + + + Resources containing entities which are not valid in basic XML (e.g. &sect;) will have those + entities converted to their equivalent unicode characters when resources are encoded, since FHIR does + not allow extended entities in resource instances. + + + Add a new client interceptor which adds HTTP Authorization Bearer Tokens (for use with OAUTH2 servers) + to client requests. + + + Add phloc-commons dependency explicitly, which resolves an issue building HAPI from source on + some platforms. Thanks to Odysseas Pentakalos for the patch! + + + HAPI now logs a single line indicating the StAX implementation being used upon the + first time an XML parser is created. + + + Update methods on the server did not return a "content-location" header, but + only a "location" header. Both are required according to the FHIR specification. + Thanks to Bill de Beaubien of Systems Made Simple for reporting this! + + + Parser failed to correctly read contained Binary resources. Thanks to Alexander Kley for + the patch! + + + Calling encode multiple times on a resource with contained resources caused the contained + resources to be re-added (and the actual message to grow) with each encode pass. Thanks to + Alexander Kley for the test case! + + + JSON-encoded contained resources with the incorrect "_id" element (which should be "id", but some + incorrect examples exist on the FHIR specification) now parse correctly. In other words, HAPI + previously only accepted the correct "id" element, but now it also accepts the incorrect + "_id" element just to be more lenient. + + + Several unit tests failed on Windows (or any platform with non UTF-8 default encoding). This may + have also caused resource validation to fail occasionally on these platforms as well. + Thanks to Bill de Beaubien for reporting! + + + toString() method on TokenParam was incorrectly showing the system as the value. + Thanks to Bill de Beaubien for reporting! + + + Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks + to David Hay of Orion Health for reporting! + + + Add a + Vagrant]]> + based environment (basically a fully built, self contained development environment) for + trying out the HAPI server modules. Thanks to Preston Lee for the pull request, and for + offering to maintain this! + + + Change validation API so that it uses a return type instead of exceptions to communicate + validation failures. Thanks to Joe Athman for the pull request! + + + Add a client interceptor which adds an HTTP cookie to each client request. Thanks to + Petro Mykhailysyn for the pull request! + + + + + + Add server interceptor framework, and new interceptor for logging incoming + requests. + + + Add server validation framework for validating resources against the FHIR schemas and schematrons + + + Tester UI created double _format and _pretty param entries in searches. Thanks to Gered King of University + Health Network for reporting! + + + Create method was incorrectly returning an HTTP 204 on sucessful completion, but + should be returning an HTTP 200 per the FHIR specification. Thanks to wanghaisheng + for reporting! + + + FHIR Tester UI now correctly sends UTF-8 charset in responses so that message payloads containing + non US-ASCII characters will correctly display in the browser + + + JSON parser was incorrectly encoding extensions on composite elements outside the element itself + (as is done correctly for non-composite elements) instead of inside of them. Thanks to David Hay of + Orion for reporting this! + + + Contained/included resource instances received by a client are now automatically + added to any ResourceReferenceDt instancea in other resources which reference them. + + + Add documentation on how to use eBay CORS Filter to support Cross Origin Resource + Sharing (CORS) to server. CORS support that was built in to the server itself has + been removed, as it did not work correctly (and was reinventing a wheel that others + have done a great job inventing). Thanks to Peter Bernhardt of Relay Health for all the assistance + in testing this! + + + IResource interface did not expose the getLanguage/setLanguage methods from BaseResource, + so the resource language was difficult to access. + + + JSON Parser now gives a more friendly error message if it tries to parse JSON with invalid use + of single quotes + + + Transaction server method is now allowed to return an OperationOutcome in addition to the + incoming resources. The public test server now does this in order to return status information + about the transaction processing. + + + Update method in the server can now flag (via a field on the MethodOutcome object being returned) + that the result was actually a creation, and Create method can indicate that it was actually an + update. This has no effect other than to switch between the HTTP 200 and HTTP 201 status codes on the + response, but this may be useful in some circumstances. + + + Annotation client search methods with a specific resource type (e.g. List<Patient> search()) + won't return any resources that aren't of the correct type that are received in a response + bundle (generally these are referenced resources, so they are populated in the reference fields instead). + Thanks to Tahura Chaudhry of University Health Network for the unit test! + + + Added narrative generator template for OperationOutcome resource + + + Date/time types did not correctly parse values in the format "yyyymmdd" (although the FHIR-defined format + is "yyyy-mm-dd" anyhow, and this is correctly handled). Thanks to Jeffrey Ting of Systems Made Simple + for reporting! + + + Server search method for an unnamed query gets called if the client requests a named query + with the same parameter list. Thanks to Neal Acharya of University Health Network for reporting! + + + Category header (for tags) is correctly read in client for "read" operation + + + Transaction method in server can now have parameter type Bundle instead of + List<IResource> + + + HAPI parsers now use field access to get/set values instead of method accessors and mutators. + This should give a small performance boost. + + + JSON parser encodes resource references incorrectly, using the name "resource" instead + of the name "reference" for the actual reference. Thanks to + Ricky Nguyen for reporting and tracking down the issue! + + + Rename NotImpementedException to NotImplementedException (to correct typo) + + + Server setUseBrowserFriendlyContentType setting also respected for errors (e.g. OperationOutcome with 4xx/5xx status) + + + Fix performance issue in date/time datatypes where pattern matchers were not static + + + Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but + previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting! + + + Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health + for reporting! + + + QuantityParam correctly encodes approximate (~) prefix to values + + + If a server defines a method with parameter "_id", incoming search requests for that method may + get delegated to the wrong method. Thanks to Neal Acharya for reporting! + + + SecurityEvent.Object structural element has been renamed to + SecurityEvent.ObjectElement to avoid conflicting names with the + java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for + reporting! + + + Text/narrative blocks that were created with a non-empty + namespace prefix (e.g. <xhtml:div xmlns:xhtml="...">...</xhtml:div>) + failed to encode correctly (prefix was missing in encoded resource) + + + Resource references previously encoded their children (display and reference) + in the wrong order so references with both would fail schema validation. + + + SecurityEvent resource's enums now use friendly enum names instead of the unfriendly + numeric code values. Thanks to Laurie MacDougall-Sookraj of UHN for the + suggestion! + + + + + HAPI has a number of RESTful method parameter types that have similar but not identical + purposes and confusing names. A cleanup has been undertaken to clean this up. + This means that a number of existing classes + have been deprocated in favour of new naming schemes. +
    ]]> + All annotation-based clients and all server search method parameters are now named + (type)Param, for example: StringParam, TokenParam, etc. +
    ]]> + All generic/fluent client method parameters are now named + (type)ClientParam, for example: StringClientParam, TokenClientParam, etc. +
    ]]> + All renamed classes have been retained and deprocated, so this change should not cause any issues + for existing applications but those applications should be refactored to use the + new parameters when possible. +
    + + Allow server methods to return wildcard generic types (e.g. List<? extends IResource>) + + + Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as + "&identifier=system|codepart1\|codepart2" + + + Add support for OPTIONS verb (which returns the server conformance statement) + + + Add support for CORS headers in server + + + Bump SLF4j dependency to latest version (1.7.7) + + + Add interceptor framework for clients (annotation based and generic), and add interceptors + for configurable logging, capturing requests and responses, and HTTP basic auth. + + + Transaction client invocations with XML encoding were using the wrong content type ("application/xml+fhir" instead + of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one! + + + Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion! + + + If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or + an OperationOutcome resource, include the message in the exception message so that it will be + more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion! + + + Read invocations in the client now process the "Content-Location" header and use it to + populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion! + + + Fix issue where vread invocations on server incorrectly get routed to instance history method if one is + defined. Thanks to Neal Acharya from UHN for surfacing this one! + + + Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary + blobs from being used for nefarious purposes. See + FHIR Tracker Bug 3298]]> + for more information. + + + Support has been added for using an HTTP proxy for outgoing requests. + + + Fix: Primitive extensions declared against custom resource types + are encoded even if they have no value. Thanks to David Hay of Orion for + reporting this! + + + Fix: RESTful server deployed to a location where the URL to access it contained a + space (e.g. a WAR file with a space in the name) failed to work correctly. + Thanks to David Hay of Orion for reporting this! + +
    + + + BREAKING CHANGE:]]>: IdDt has been modified so that it + contains a partial or complete resource identity. Previously it contained + only the simple alphanumeric id of the resource (the part at the end of the "read" URL for + that resource) but it can now contain a complete URL or even a partial URL (e.g. "Patient/123") + and can optionally contain a version (e.g. "Patient/123/_history/456"). New methods have + been added to this datatype which provide just the numeric portion. See the JavaDoc + for more information. + + + API CHANGE:]]>: Most elements in the HAPI FHIR model contain + a getId() and setId() method. This method is confusing because it is only actually used + for IDREF elements (which are rare) but its name makes it easy to confuse with more + important identifiers. For this reason, these methods have been deprocated and replaced with + get/setElementSpecificId() methods. The old methods will be removed at some point. Resource + types are unchanged and retain their get/setId methods. + + + Allow use of QuantityDt as a service parameter to support the "quantity" type. Previously + QuantityDt did not implement IQueryParameterType so it was not valid, and there was no way to + support quantity search parameters on the server (e.g. Observation.value-quantity) + + + Introduce StringParameter type which can be used as a RESTful operation search parameter + type. StringParameter allows ":exact" matches to be specified in clients, and handled in servers. + + + Parsers (XML/JSON) now support deleted entries in bundles + + + Transaction method now supported in servers + + + Support for Binary resources added (in servers, clients, parsers, etc.) + + + Support for Query resources fixed (in parser) + + + Nested contained resources (e.g. encoding a resource with a contained resource that itself contains a resource) + now parse and encode correctly, meaning that all contained resources are placed in the "contained" element + of the root resource, and the parser looks in the root resource for all container levels when stitching + contained resources back together. + + + Server methods with @Include parameter would sometimes fail when no _include was actually + specified in query strings. + + + Client requests for IdentifierDt types (such as Patient.identifier) did not create the correct + query string if the system is null. + + + Add support for paging responses from RESTful servers. + + + Don't fail on narrative blocks in JSON resources with only an XML declaration but no content (these are + produced by the Health Intersections server) + + + Server now automatically compresses responses if the client indicates support + + + Server failed to support optional parameters when type is String and :exact qualifier is used + + + Read method in client correctly populated resource ID in returned object + + + Support added for deleted-entry by/name, by/email, and comment from Tombstones spec + + + + + + + + + +
    diff --git a/src/changes/changes_LOCAL_31097.xml b/src/changes/changes_LOCAL_31097.xml new file mode 100644 index 00000000000..e4c38c9cbe9 --- /dev/null +++ b/src/changes/changes_LOCAL_31097.xml @@ -0,0 +1,2783 @@ + + + + James Agnew + HAPI FHIR Changelog + + + + + JSON parsing in HAPI FHIR has been switched from using JSR353 (javax.json) to + using Google Gson. For this reason we are bumping the major release number to + 2.0. Theoretically this should not affect projects in any major way, but Gson + does have subtle differences. Two differences which popped up a fair bit in + our own testing: + +
      + A space is placed after the : in keys, e.g. what was previously + encoded as "resourceType":"Patient" is now encoded + as "resourceType": "Patient" (this broke a number of + our unit tests with hardcoded resource definitions) +
    +
      + Trailing content after a valid json resource is rejected by + Gson (it was ignored by the Glassfish parser we were previously + using even though it was invalid) +
    + + ]]> +
    + + STU3 structure definitions have been updated to the + STU3 ballot candidate versions (1.5.0 - SVN 9395) + + + Both client and server now support the new Content Types decided in + FHIR #10199]]>. +
    ]]> + This means that the server now supports + application/fhir+xml and application/fhir+json]]> + in addition to the older style + application/xml+fhir and application/json+fhir]]>. + In order to facilitate migration by implementors, the old style remains the default + for now, but the server will respond using the new style if the request contains it. The + client now uses an Accept]]> header value which requests both + styles with a preference given to the new style when running in DSTU3 mode. +
    ]]> + As a part of this change, the server has also been enhanced so that if a request + contains a Content-Type header but no Accept header, the response will prefer the + encoding specified by the Content-Type header. +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Logback (used in sample projects): 1.1.5 -> 1.1.7
  • +
  • Phloc Commons (used by schematron validator): 4.4.4 -> 4.4.5
  • +
  • Commons-IO: 2.4 -> 2.5
  • +
  • Apache HTTPClient: 4.5.1 -> 4.5.2
  • +
  • Apache HTTPCore: 4.4.4 -> 4.4.5
  • +
  • Jersey (JAX-RS tests): 2.22.2 -> 2.23.1
  • +
  • Spring (JPA, Web Tester): 4.3.0 -> 4.3.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.4
  • + + ]]> +
    + + + Fix issue in DSTU1 Bundle parsing where unexpected elements in the bundle resulted in a failure + to parse. + + + DSTU2 QuestionnaireResponse validator failed with an exception if the + QuestionnaireResponse contained certain groups with no content + + + Fluent client should ignore parameter values which are null instead of including + them as ?foo=null]]> + + + When using _elements]]> parameter on server, the server was not + automatically adding the SUBSETTED]]> tag as it should + + + JPA server should now automatically detect + if Hibernate Search (Lucene) is configured to be + disabled and will not attempt to use it. This + prevents a crash for some operations. + + + A new server interceptor "BanUnsupprtedHttpMethodsInterceptor" has been added + which causes the server to return an HTTP 405 if an unsupported HTTP + verb is received from the client + + + Fix an issue where resource IDs were not correctly set when using + DSTU2 HL7org structures with the JAX-RS module. Thanks to Carlo Mion + for the pull request! + + + hapi-fhir-testpage-overlay project contained an unneccesary + dependency on hapi-fhir-jpaserver-base module, which resulted in + projects using the overlay having a large number of unnneded + JARs included + + + It is not possible to configure both the parser and the context to + preserve versions in resource references (default behaviour is to + strip versions from references). Thanks to GitHub user @cknaap + for the suggestion! + + + Tag#setCode(String)]]> did not actually set the code it was supposed to + set. Thanks to Tim Tschampel for reporting! + + + JPA server's /Bundle]]> endpoint cleared + the Bundle.entry.fullUrl]]> field on stored + bundles, resulting in invalid content being saved. Thanks to Mirjam + Baltus for reporting! + + + JPA server now returns HTTP 200 instead of HTTP 404 for + conditional deletes which did not find any matches, + per FHIR-I decision. + + + Client that declares explicitly that it is searching/reading/etc for + a custom type did not automatically parse into that type. + + + Allow servers to specify the authentication realm of their choosing when + throwing an AuthenticationException. Thanks to GitHub user @allanbrohansen + for the suggestion! + + + Add a new client implementation which uses the + OkHttp]]> + library as the HTTP client implementation (instead of Apache HttpClient). + This is particularly useful for Android (where HttpClient is a pain) but + could also be useful in other places too. + Thanks to Matt Clarke of Orion Health for the contribution! + + + Fix a regression when parsing resources that have contained + resources, where the reference in the outer resource which + links to the contained resource sometimes did does not get + populated with the actual target resource instance. Thanks to + Neal Acharya for reporting! + + + hapi-fhir-cli upload-terminology command now has an argument + "-b FOO" that lets you add an authorization header in the form + Authorization: Bearer FOO]]> + + + Parser failed to successfully encode a custom resource + if it contained custom fields that also used custom + types. Thanks to GitHub user @sjanic for reporting! + + + Inprove handling of _text and _content searches in JPA server to do better + matching on partial strings + +
    + + + Performance has been improved for the initial FhirContext + object creation by avoiding a lot of unnecessary reflection. HAPI FHIR + 1.5 had a regression compared to previous releases + and this has been corrected, but other improvements have been + made so that this release is faster than previous releases too. +
    ]]> + In addition, a new "deferred scan" mode has been implemented for + even faster initialization on slower environments (e.g. Android). + See the performance documentation]]> + for more information. +
    ]]> + The following shows our benchmarks for context initialization across several + versions of HAPI: + +
  • Version 1.4: 560ms
  • +
  • Version 1.5: 800ms
  • +
  • Version 1.6: 340ms
  • +
  • Version 1.6 (deferred mode): 240ms
  • + + ]]> +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Spring (JPA, Web Tester): 4.2.5 -> 4.3.0
  • +
  • Spring-Data (JPA): 1.9.2 -> 1.10.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.3
  • +
  • Jetty (CLI): 9.3.9 -> 9.3.10
  • + + ]]> +
    + + Remove some clases that were deprecated over a year ago and have + suitable replacements: + +
  • QualifiedDateParam has been removed, but DateParam may be used instead
  • +
  • PathSpecification has been removedm but Include may be used instead
  • + + ]]> +
    + + ResponseValidatingInterceptor threw an InternalErrorException (HTTP 500) for operations + that do not return any content (e.g. delete). Thanks to Mohammad Jafari for reporting! + + + REST server now throws an HTTP 400 instead of an HTTP 500 if an operation which takes + a FHIR resource in the request body (e.g. create, update) contains invalid content that + the parser is unable to parse. Thanks to Jim Steel for the suggestion! + + + Deprecate fluent client search operations without an explicit declaration of the + bundle type being used. This also means that in a client + .search()]]> + operation, the + .returnBundle(Bundle.class)]]> + needs to be the last statement before + .execute()]]> + + + Server now respects the parameter _format=application/xml+fhir"]]> + which is technically invalid since the + should be escaped, but is likely to be used. Also, + a parameter of _format=html]]> can now be used, which + forces SyntaxHighlightingInterceptor to use HTML even + if the headers wouldn't otherwise trigger it. + Thanks to Jim Steel for reporting! + + + Improve performance when parsing large bundles by fixing a loop over all of the + entries inthe bundle to stitch together cross-references, which was happening once + per entry instead of once overall. Thanks to Erick on the HAPI FHIR Google Group for + noticing that this was an issue! + + + JSON parser no longer allows the resource ID to be specified in an element called "_id" + (the correct one is "id"). Previously _id was allowed because some early FHIR examples + used that form, but this was never actually valid so it is now being removed. + + + JPA server now allows "forced IDs" (ids containing non-numeric, client assigned IDs) + to use the same logical ID part on different resource types. E.g. A server may now have + both Patient/foo and Obervation/foo on the same server.
    ]]> + Note that existing databases will need to modify index "IDX_FORCEDID" as + it is no longer unique, and perform a reindexing pass. +
    + + When serializing/encoding custom types which replace exsting choice fields by + fixing the choice to a single type, the parser would forget that the + field was a choice and would use the wrong name (e.g. "abatement" instead of + "abatementDateType"). Thanks to Yaroslav Kovbas for reporting and + providing a unit test! + + + JPA server transactions sometimes created an incorrect resource reference + if a resource being saved contained references that had a display value but + not an actual reference. Thanks to David Hay for reporting! + + + When performing a REST Client create or update with + Prefer: return=representation]]> set, + if the server does not honour the Prefer header, the client + will automatically fetch the resource before returning. Thanks + to Ewout Kramer for the idea! + + + DSTU3 structures now have + setFoo(List)]]> + and + setGetFooFirstRep()]]> + methods, bringing them back to parity with the HAPI + DSTU2 structures. Thanks to Rahul Somasunderam and + Claude Nanjo for the suggestions! + + + JPA server has now been refactored to use the + new FluentPath search parameter definitions + for DSTU3 resources. + + + RequestValidatingInterceptor and ResponseValidatingInterceptor + both have new method setIgnoreValidatorExceptions]]> + which causes validator exceptions to be ignored, rather than causing + processing to be aborted. + + + LoggingInterceptor on server has a new parameter + ${requestBodyFhir}]]> which logs the entire request body. + + + JAX-RS server module now supports DSTU3 resources (previously it only supported DSTU2). Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Generated conformance statements for DSTU3 servers did not properly reference their + OperationDefinitions. Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Properly handle null arrays when parsing JSON resources. Thanks to Subhro for + fixing this and providing a pull request! + + + STU3 validator failed to validate codes where the + code was a child code within the code system that contained it + (i.e. not a top level code). Thanks to Jon + Zammit for reporting! + + + Restore the setType method in the DSTU1 Bundle + class, as it was accidentally commented out. Thanks + to GitHub user @Virdulys for the pull request! + + + JPA server now supports composite search parameters + where the type of the composite parameter is + a quantity (e.g. Observation:component-code-component-value-quantity) + + + Remove the Remittance resource from DSTU2 + structures, as it is not a real resource and + was causing issues with interoperability + with the .NET client. + + + CLI tool cache feature (-c) for upload-example task sometimes failed + to write cache file and exited with an exception. + + + Fix error message in web testing UI when loading pages in a search + result for STU3 endpoints. + + + When encoding JSON resource, the parser will now always + ensure that XHTML narrative content has an + XHTML namespace declaration on the first + DIV tag. This was preventing validation for + some resources using the official validator + rules. + + + Server failed to invoke operations when the name + was escaped (%24execute instead of $execute). + Thanks to Michael Lawley for reporting! + + + JPA server transactions containing a bundle that has multiple entries + trying to delete the same resource caused a 500 internal error + + + JPA module failed to index search parameters that mapped to a Timing datatype, + e.g. CarePlan:activitydate + + + Add a new option to the CLI run-server command called --lowmem]]>. + This option disables some features (e.g. fulltext search) in order to allow the + server to start in memory-constrained environments (e.g Raspberry Pi) + + + When updating a resource via an update operation on the server, if the ID of the + resource is not present in the resource body but is present on the URL, this will + now be treated as a warning instead of as a failure in order to be a bit more + tolerant of errors. If the ID is present in the body but does not agree with the + ID in the URL this remains an error. + + + Server / JPA server date range search params (e.g. Encounter:date) now treat + a single date with no comparator (or the eq comparator) as requiring that the + value be completely contained by the range specified. Thanks to Chris Moesel + for the suggestion. + + + In server, if a parameter was annotated with the annotation, the + count would not appear in the self/prev/next links and would not actually be applied + to the search results by the server. Thanks to Jim Steele for letting us know! + + + Conditional update on server failed to process if the conditional URL did not have any + search parameters that did not start with an underscore. E.g. "Patient?_id=1" failed + even though this is a valid conditional reference. + + + JPA server can now be configured to allow external references (i.e. references that + point to resources on other servers). See + JPA Documentation]]> for information on + how to use this. Thanks to Naminder Soorma for the suggestion! + + + When posting a resource to a server that contains an invalid value in a boolean field + (e.g. Patient with an active value of "1") the server should return an HTTP 400, not + an HTTP 500. Thanks to Jim Steel for reporting! + + + Enable parsers to parse and serialize custom resources that contain custom datatypes. + An example has been added which shows how to do this + here]]> + + + JSON parser was incorrectly encoding resource language attribute in JSON as an + array instead of a string. Thanks to David Hay for reporting! + + + Sébastien Rivière contributed an excellent pull request which adds a + number of enhancements to JAX-RS module: + +
  • Enable the conditional update and delete
  • +
  • Creation of a bundle provider, and support of the @Transaction
  • +
  • Bug fix on the exceptions handling as some exceptions throw outside bean context were not intercept.
  • +
  • Add the possibility to have the stacktrace in the jaxrsException
  • + + ]]> +
    + + FhirTerser.cloneInto method failed to clone correctly if the source + had any extensions. Thanks to GitHub user @Virdulys for submitting and + providing a test case! + + + Update DSTU2 InstanceValidator to latest version from upstream + + + Web Testing UI was not able to correctly post an STU3 transaction + + + DateTime parser incorrectly parsed times where more than 3 digits of + precision were provided on the seconds after the decimal point + + + Improve error messages when the $validate operation is called but no resource + is actually supplied to validate + + + DSTU2+ servers no longer return the Category header, as this has been + removed from the FHIR specification (and tags are now available in the + resource body so the header was duplication/wasted bandwidth) + + + Create and Update operations in server did not + include ETag or Last-Modified headers even though + the spec says they should. Thanks to Jim Steel for + reporting! + + + Update STU3 client and server to use the new sort parameter style (param1,-param2,param). Thanks to GitHub user @euz1e4r for + reporting! + + + QuantityClientParam#withUnit(String) put the unit into the system part of the + parameter value + + + Fluent client searches with date parameters were not correctly using + new prefix style (e.g. gt) instead of old one (e.g. >) + + + Some built-in v3 code systems for STU3 resources were missing + certain codes, which caused false failures when validating + resources. Thanks to GitHub user @Xoude for reporting! + + + Some methods on DSTU2 model structures have JavaDocs that + incorrectly claim that the method will not return null when + in fact it can. Thanks to Rick Riemer for reporting! + + + ResponseHighlightingInterceptor has been modified based on consensus + on Zulip with Grahame that requests that have a parameter of + _format=json]]> or + _format=xml]]> will output raw FHIR content + instead of HTML highlighting the content as they previously did. + HTML content can now be forced via the (previously existing) + _format=html]]> or via the two newly added + values + _format=html/json]]> and + _format=html/xml]]>. Because of this + change, the custom + _raw=true]]> mode has been deprecated and + will be removed at some point. + + + Operation definitions (e.g. for $everything operation) in the generated + server conformance statement should not include the $ prefix in the operation + name or code. Thanks to Dion McMurtrie for reporting! + + + Server generated OperationDefinition resources did not validate + due to some missing elements (kind, status, etc.). + Thanks to + Michael Lawley for reporting! + + + Operations that are defined on multiple resource provider types with + the same name (e.g. "$everything") are now automatically exposed by the server + as separate OperationDefinition resources per resource type. Thanks to + Michael Lawley for reporting! + + + OperationDefinition resources generated automatically by the server for operations + that are defined within resource/plain providers incorrectly stated that + the maximum cardinality was "*" for non-collection types with no explicit + maximum stated, which is not the behaviour that the JavaDoc on the + annotation describes. Thanks to Michael Lawley + for reporting! + + + Server parameters annotated with + @Since]]> + or + @Count]]> + which are of a FHIR type such as IntegerDt or DateTimeType will + now be set to null if the client's URL does not + contain this parameter. Previously they would be populated + with an empty instance of the FHIR type, which was inconsistent with + the way other server parameters worked. + + + Server now supports the _at parameter (including multiple repetitions) + for history operation + + + + AuthorizationInterceptor can now allow or deny requests to extended + operations (e.g. $everything) + + + DecimalType used BigDecimal constructor instead of valueOf method to + create a BigDecimal from a double, resulting in weird floating point + conversions. Thanks to Craig McClendon for reporting! + + + Remove the depdendency on a method from commons-lang3 3.3 which was + causing issues on some Android phones which come with an older version + of this library bundled. Thanks to Paolo Perliti for reporting! + + + Parser is now better able to handle encoding fields which have been + populated with a class that extends the expected class + + + When declaring a child with + order=Child.REPLACE_PARENT]]> + the serialized form still put the element at the + end of the resource instead of in the correct + order + + + Fix STU3 JPA resource providers to allow validate operation + at instance level + +
    + + + Security Fix: XML parser was vulnerable to XXE (XML External Entity) + processing, which could result in local files on disk being disclosed. + See this page]]> + for more information. + Thanks to Jim Steel for reporting! + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.7 -> 5.1.0
  • +
  • Spring (JPA, Web Tester): 4.2.4 -> 4.2.5
  • +
  • SLF4j (All): 1.7.14 -> 1.7.21
  • + + ]]> +
    + + Support comments when parsing and encoding both JSON and XML. Comments are retrieved + and added to the newly created methods + IBase#getFormatCommentsPre() and + IBase#getFormatCommentsPost() + + + Added options to the CLI upload-examples command which allow it to cache + the downloaded content file, or use an arbitrary one. Thanks to Adam Carbone + for the pull request! + + + REST search parameters with a prefix/comparator had not been updated to use + the DSTU2 style prefixes (gt2011-01-10) instead of the DSTU1 style prefixes + (>2011-01-01). The client has been updated so that it uses the new prefixes + if the client has a DSTU2+ context. The server has been updated so that it now + supports both styles. +
    ]]> + As a part of this change, a new enum called + ParamPrefixEnum]]> + has been introduced. This enum replaces the old + QuantityCompararatorEnum]]> + which has a typo in its name and can not represent several new prefixes added since + DSTU1. +
    + + JPA server number and quantity search params now follow the rules for the + use of precision in search terms outlined in the + search page]]> of the + FHIR specification. For example, previously a 1% tolerance was applied for + all searches (10% for approximate search). Now, a tolerance which respects the + precision of the search term is used (but still 10% for approximate search). + + + Fix a failure starting the REST server if a method returns an untyped List, which + among other things prevented resource provider added to the server + as CDI beans in a JBoss enviroment. Thanks to GitHub user fw060 (Fei) for + reporting and figuring out exactly why this wasn't working! + + + JPA server now supports :above and :below qualifiers on URI search params + + + Add optional support (disabled by default for now) to JPA server to support + inline references containing search URLs. These URLs will be resolved when + a resource is being created/updated and replaced with the single matching + resource. This is being used as a part of the May 2016 Connectathon for + a testing scenario. + + + The server no longer adds a + WWW-Authenticate]]> + header to the response if any resource provider code throws an + AuthenticationException]]>. This header is + used for interactive authentication, which isn't generally + appropriate for FHIR. We added code to add this header a long time + ago for testing purposes and it never got removed. Please let us + know if you need the ability to add this header automatically. Thanks + to Lars Kristian Roland for pointing this out. + + + In the client, the create/update operations on a Binary resource + (which use the raw binary's content type as opposed to the FHIR + content type) were not including any request headers (Content-Type, + User-Agent, etc.) Thanks to Peter Van Houte of Agfa Healthcare for + reporting! + + + Handling of Binary resources containing embedded FHIR resources for + create/update/etc operations has been corrected per the FHIR rules + outlined at + Binary Resource]]> + in both the client and server. +
    ]]> + Essentially, if the Binary contains something + that isn't FHIR (e.g. an image with an image content-type) the + client will send the raw data with the image content type to the server. The + server will place the content type and raw data into a Binary resource instance + and pass those to the resource provider. This part was already correct previous + to 1.5. +
    ]]> + On the other hand, if the Binary contains a FHIR content type, the Binary + is now sent by the client to the server as a Binary resource with a FHIR content-type, + and the embedded FHIR content is contained in the appropriate fields. The server + will pass this "outer" Binary resource to the resource provider code. +
    + + The RequestDetails and ActionRequestDetails objects which are passed to + server interceptor methods and may also be used as server provider method + arguments now has a new method + Map<String, String> getUserData() + ]]> + which can be used to pass data and objects between interceptor methods to + to providers. This can be useful, for instance, if an authorization + interceptor wants to pass the logged in user's details to other parts + of the server. + + + IServerInterceptor#incomingRequestPreHandled() is called + for a @Validate method, the resource was not populated in the + ActionRequestDetails argument. Thanks to Ravi Kuchi for reporting! + ]]> + + + [baseUrl]/metadata with an HTTP method + other than GET (e.g. POST, PUT) should result in an HTTP 405. Thanks to + Michael Lawley for reporting! + ]]> + + + Fix a server exception when trying to automatically add the profile tag + to a resource which already has one or more profiles set. Thanks to + Magnus Vinther for reporting! + + + QuantityParam parameters being used in the RESTful server were ignoring + the + :missing]]> + qualifier. Thanks to Alexander Takacs for reporting! + + + Annotation client failed with an exception if the response contained + extensions on fields in the resonse Bundle (e.g. Bundle.entry.search). + Thanks to GitHub user am202 for reporting! + + + Primitive elements with no value but an extension were sometimes not + encoded correctly in XML, and sometimes not parsed correctly in JSON. + Thanks to Bill de Beaubien for reporting! + + + The Web Testing UI has long had an issue where if you click on a button which + navigates to a new page (e.g. search, read, etc) and then click the back button + to return to the original page, the button you clicked remains disabled and can't + be clicked again (on Firefox and Safari). This is now fixed. Unfortunately the fix means that the + buttom will no longer show a "loading" spinner, but there doesn't seem to + be another way of fixing this. Thanks to Mark Scrimshire for reporting! + + + Extensions found while parsing an object that doesn't support extensions are now + reported using the IParserErrorHandler framework in the same way that + other similar errors are handled. This allows the parser to be more lenient + when needed. + + + Improve error message if incorrect type is placed in a list field in the data model. Java + uses generics to prevent this at compile time, but if someone is in an environment without + generics this helps improve the error message at runtime. Thanks to Hugo Soares for + suggesting. + + + Prevent an unneeded warning when parsing a resource containing + a declared extension. Thanks to Matt Blanchette for reporting! + + + Web Tester UI did not invoke VRead even if a version ID was specified. Thanks + to Poseidon for reporting! + + + Per discussion on the FHIR implementer chat, the JPA server no + longer includes _revinclude matches in the Bundle.total count, or the + page size limit. + + + JPA server now persists search results to the database in a new table where they + can be temporaily preserved. This makes the JPA server much more scalable, since it + no longer needs to store large lists of pages in memory between search invocations. +
    ]]> + Old searches are deleted after an hour by default, but this can be changed + via a setting in the DaoConfig. +
    + + JPA servers' resource version history mechanism + has been adjusted so that the history table + keeps a record of all versions including the + current version. This has the very helpful + side effect that history no longer needs to be + paged into memory as a complete set. Previously + history had a hard limit of only being able to + page the most recent 20000 entries. Now it has + no limit. + + + JPA server returned the wrong Bundle.type value (COLLECTION, should be SEARCHSET) + for $everything operation responses. Thanks to Sonali Somase for reporting! + + + REST and JPA server should reject update requests where the resource body does not + contain an ID, or contains an ID which does not match the URL. Previously these + were accepted (the URL ID was trusted) which is incorrect according to the + FHIR specification. Thanks to GitHub user ametke for reporting! +
    ]]> + As a part of this change, server error messages were also improved for + requests where the URL does not contain an ID but needs to (e.g. for + an update) or contains an ID but shouldn't (e.g. for a create) +
    + + When fields of type BoundCodeDt (e.g. Patient.gender) + are serialized and deserialized using Java's native + object serialization, the enum binder was not + serialized too. This meant that values for the + field in the deserialized object could not be + modified. Thanks to Thomas Andersen for reporting! + + + REST Server responded to HTTP OPTIONS requests with + any URI as being a request for the server's + Conformance statement. This is incorrect, as only + a request for OPTIONS [base url]]]> should be treated as such. Thanks to Michael Lawley for reporting! + + + REST annotation style client was not able to handle extended operations + ($foo) where the response from the server was a raw resource instead + of a Parameters resource. Thanks to Andrew Michael Martin for reporting! + + + JPA server applies _lastUpdated filter inline with other searches wherever possible + instead of applying this filter as a second query against the results of the + first query. This should improve performance when searching against large + datasets. + + + Parsers have new method + setDontEncodeElements]]> + which can be used to force the parser to not encode certain elements + in a resource when serializing. For example this can be used to omit + sensitive data or skip the resource metadata. + + + JPA server database design has been adjusted + so that different tables use different sequences + to generate their indexes, resulting in more sequential + resource IDs being assigned by the server + + + Server now correctly serves up Binary resources + using their native content type (instead of as a + FHIR resource) if the request contains an accept + header containing "application/xml" as some browsers + do. + + + DSTU2 resources now have a + getMeta()]]> method which returns a + modifiable view of the resource metadata for convenience. This + matches the equivalent method in the DSTU3 structures. + + + Add a new method to FhirContext called + setDefaultTypeForProfile + ]]> + which can be used to specify that when recources are received which declare + support for specific profiles, a specific custom structures should be used + instead of the default. For example, if you have created a custom Observation + class for a specific profile, you could use this method to cause your custom + type to be used by the parser for resources in a search bundle you receive. +
    + See the documentation page on + Profiles and Extensions + for more information. + ]]> +
    + + Parsing/Encoding a custom resource type which extends a + base type sometimes caused the FhirContext to treat all future + parses of the same resource as using the custom type even when + this was not wanted. +
    ]]> + Custom structures may now be explicitly declared by profile + using the + setDefaultTypeForProfile + ]]> + method. +
    ]]> + This issue was discovered and fixed as a part of the implementation of issue #315. +
    + + Set up the tinder plugin to work as an ant task + as well as a Maven plugin, and to use external + sources. Thanks to Bill Denton for the pull + request! + + + JPA server now allows searching by token + parameter using a system only and no code, + giving a search for any tokens which match + the given token with any code. Previously the + expected behaviour for this search + was not clear in the spec and HAPI had different + behaviour from the other reference servers. + + + Introduce a JAX-RS client provider which can be used instead of the + default Apache HTTP Client provider to provide low level HTTP + services to HAPI's REST client. See + JAX-RS & Alternate HTTP Client Providers]]> + for more information. +
    ]]> + This is useful in cases where you have other non-FHIR REST clients + using a JAX-RS provider and want to take advantage of the + rest of the framework. +
    ]]> + Thanks to Peter Van Houte from Agfa for the amazing work! +
    + + Parser failed with a NPE while encoding resources if the + resource contained a null extension. Thanks to + steve1medix for reporting! + + + In generated model classes (DSTU1/2) don't + use BoundCodeDt and BoundCodeableConceptDt for + coded fields which use example bindings. Thanks + to GitHub user Ricq for reporting! + + + @Operation will now infer the maximum number of repetitions + of their parameters by the type of the parameter. Previously if + a default max() value was not specified in the + @OperationParam annotation on a parameter, the maximum + was assumed to be 1. Now, if a max value is not explicitly specified + and the type of the parameter is a basic type (e.g. StringDt) the + max will be 1. If the parameter is a collection type (e.g. List<StringDt>) + the max will be * + ]]> + + + @Operation + may now use search parameter types, such as + TokenParam and + TokenAndListParam as values. Thanks to + Christian Ohr for reporting! + ]]> + + + Add databases indexes to JPA module search index tables + for the RES_ID column on each. This should help + performance when searching over large datasets. + Thanks to Emmanuel Duviviers for the suggestion! + + + DateTimeType should fail to parse 1974-12-25+10:00 as this is not + a valid time in FHIR. Thanks to Grahame Grieve for reporting! + + + When parsing a Bundle resource, if the Bundle.entry.request.url contains a UUID + but the resource body has no ID, the Resource.id will be populated with the ID from the + Bundle.entry.request.url. This is helpful when round tripping Bundles containing + UUIDs. + + + When parsing a DSTU3 bundle, references between resources did not have + the actual resource instance populated into the reference if the + IDs matched as they did in DSTU1/2. + + + Contained resource references on DSTU3 + resources were not serialized correctly when + using the Json Parser. Thanks to GitHub user + @fw060 for reporting and supplying a patch + which corrects the issue! + + + DSTU3 model classes equalsShallow and equalsDeep both did not work + correctly if a field was null in one object, but contained an empty + object in the other (e.g. a StringType with no actual value in it). These + two should be considered equal, since they would produce the exact same + wire format.
    ]]> + Thanks to GitHub user @ipropper for reporting and providing + a test case! +
    + + JPA server now supports searching for _tag:not=[tag]]]> + which enables finding resources that to not have a given tag/profile/security tag. + Thanks to Lars Kristian Roland for the suggestion! + + + Extensions containing resource references did not get encoded correctly + some of the time. Thanks to Poseidon for reporting! + + + Parsers (both XML and JSON) encoded the first few elements of DSTU3 structures in the wrong order: + Extensions were placed before any other content, which is incorrect (several + elements come first: meta, text, etc.) + + + In server implementations, the Bundle.entry.fullUrl was not getting correctly + populated on Hl7OrgDstu2 servers. Thanks to Christian Ohr for reporting! + + + Ensure that element IDs within resources (i.e. IDs on elements other than the + resource itself) get serialized and parsed correctly. Previously, these didn't get + serialized in a bunch of circumstances. Thanks to Vadim Peretokin for reporting + and providing test cases! + + + Improve CLI error message if the tool can't bind to the requested port. Thanks + to Claude Nanjo for the suggestion! + + + Server param of _summary=text]]> did not + include mandatory elements in return as well as + the text element, even though the FHIR specification + required it. + + + Remove invalid resource type "Documentation" from DSTU2 + structures. + + + JPA server did not respect target types for search parameters. E.g. Appointment:patient has + a path of "Appointment.participant.actor" and a target type of "Patient". The search path + was being correctly handled, but the target type was being ignored. + + + RestfulServer now manually parses URL parameters instead of relying on the container's + parsed parameters. This is useful because many Java servlet containers (e.g. Tomcat, Glassfish) + default to ISO-8859-1 encoding for URLs insetad of the UTF-8 encoding specified by + FHIR. + + + ResponseHighlightingInterceptor now doesn't highlight if the request + has an Origin header, since this probably denotes an AJAX request. + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.3 -> 5.0.7
  • +
  • Springframework (JPA, Web Tester): 4.2.2 -> 4.2.4
  • +
  • Phloc-Commons (Schematron Validator): 4.3.6 -> 4.4.4
  • +
  • Apache httpclient (Client): 4.4 -> 4.5.1
  • +
  • Apache httpcore (Client): 4.4 -> 4.4.4
  • +
  • SLF4j (All): 1.7.13 -> 1.7.14
  • + + ]]> +
    + + Remove a dependency on a Java 1.7 class + (ReflectiveOperationException) in several spots in the + codebase. This dependency was accidentally introduced in + 1.3, and animal-sniffer-plugin failed to detect it (sigh). + + + Add two new server interceptors: + RequestValidatingInterceptor + and + ResponseValidatingInterceptor + ]]> + which can be used to validate incoming requests or outgoing responses using the standard FHIR validation + tools. See the + Server Validation Page + ]]> + for examples of how to use these interceptors. These intereptors have both + been enabled on the + public test page. + ]]> + + + Make IBoundCodeableConcept and IValueSetEnumBinder serializable, + fixing an issue when trying to serialize model classes containing + bound codes. Thanks to Nick Peterson for the Pull Request! + + + Introduce a JAX-RS version of the REST server, which can be used + to deploy the same resource provider implementations which work + on the existing REST server into a JAX-RS (e.g. Jersey) environment. + Thanks to Peter Van Houte from Agfa for the amazing work! + + + CLI now supports writing to file:// URL for 'upload-examples' command + + + GZipped content is now supported for client-to-server uploads (create, update, transaction, etc.). + The server will not automatically detect compressed incoming content and decompress it (this can be + disabled using a RestfulServer configuration setting). A new client interceptor has been added + which compresses outgoing content from the client. + + + JPA server transaction attempted to validate resources twice each, + with one of these times being before anything had been committed to the + database. This meant that if a transaction contained both a Questionnaire + and a QuestionnaireResponse, it would fail because the QuestionnaireResponse + validator wouldn't be able to find the questionnaire. This is now corrected. + + + Add a new method to the generic/fluent client for searching: + .count(int)
    ]]> + This replaces the existing ".limitTo(int)" method which has + now been deprocated because it was badly named and undocumented. +
    + + Profile validator has been configured to allow extensions even if they + aren't explicitly declared in the profile. + + + Add a constraint that the Maven build will only run in JDK 8+. HAPI + remains committed to supporting JDK 6+ in the compiled library, but these + days it can only be built using JDK 8. Thanks to joelsch for the PR! + + + When serializing a value[x] field, if the value type was a profiled type (e.g. markdown is a + profile of string) HAPI 1.3 would use the base type in the element name, e.g. + valueString instead of valueMarkdown. After discussion with Grahame, this appears to + be incorrect behaviour so it has been fixed. + + + Support target parameter type in _include / _revinclude values, e.g. + _include=Patient:careProvider:Organization. Thanks to Joe Portner + for reporting! + + + Use ResponseHighlighterInterceptor in the hapi-fhir-jpaserver-example + project to provide nice syntax highlighting. Thanks to Rob Hausam for + noting that this wasn't there. + + + Introduce custom @CoverageIgnore annotation to hapi-fhir-base in order to + remove dependency on cobertura during build and in runtime. + + + Server-generated conformance statements incorrectly used /Profile/ instead + of /StructureDefinition/ in URL links to structures. + + + JsonParser has been changed so that when serializing numbers it will use + plain format (0.001) instead of scientific format (1e-3). The latter is + valid JSON, and the parser will still correctly parse either format (all + clients should be prepared to) but this change makes serialized + resources appear more consistent between XML and JSON. As a result of this + change, trailing zeros will now be preserved when serializing as well. + + + Add DSTU3 example to hapi-fhir-jpaserver-example. Thanks to Karl + Davis for the Pull Request! + + + RestfulServer#setUseBrowserFriendlyContentTypes has been deprecated and its + functionality removed. The intention of this feature was that if it + detected a request coming in from a browser, it would serve up JSON/XML + using content types that caused the browsers to pretty print. But + each browser has different rules for when to pretty print, and + after we wrote that feature both Chrome and FF changed their rules to break it anyhow. + ResponseHighlightingInterceptor provides a better implementation of + this functionality and should be used instead. + + + Narrative generator framework has removed the + ability to generate resource titles. This + functionality was only useful for DSTU1 + implementations and wasn't compatible + with coming changes to that API. + + + Remove dependency on Servlet-API 3.0+ by using methods available in 2.5 where possible. + Note that we continue to use Servlet-API 3.0+ features in some parts of the JPA API, so + running in an old serlvet container should be tested well before use. Thanks to Bill Denton + for reporting! + + + Add new methods to RestfulClientFactory allowing you to configure the size of the + client pool used by Apache HttpClient. Thanks to Matt Blanchette for the pull + request! + + + Add support for new modifier types on Token search params in Server and + annotation client. + + + Server conformance statement should include search parameter chains if the + chains are explicitly defined via @Search(whitelist={....}). Thanks to lcamilo15 + for reporting! + + + Remove afterPropertiesSet() call in Java config for JPA + server's EntityManagerFactory. This doesn't need to be called + manually, the the manual call led to a warning about + the EntityManager being created twice. + + + Allow server to correctly figure out it's own address even if the container provides + a Servlet Context Path which does not include the root. Thanks to Petro Mykhaylyshyn + for the pull request! + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Commons-lang3 (Core): 3.3.2 -> 3.4
  • +
  • Logback (Core): 1.1.2 -> 1.1.3
  • +
  • SLF4j (Core): 1.7.102 -> 1.7.12
  • +
  • Springframework (JPA, Web Tester): 4.1.5 -> 4.2.2
  • +
  • Hibernate (JPA, Web Tester): 4.2.17 -> 5."
  • +
  • Hibernate Validator (JPA, Web Tester): 5.2.1 -> 5.2.2
  • +
  • Derby (JPA, CLI, Public Server): 10.11.1.1 -> 10.12.1.1
  • +
  • Jetty (JPA, CLI, Public Server): 9.2.6.v20141205 -> 9.3.4.v20151007
  • + + ]]> +
    + + JPA and Tester Overlay now use Spring Java config files instead + of the older XML config files. All example projects have been updated. + + + JPA server removes duplicate resource index entries before storing them + (e.g. if a patient has the same name twice, only one index entry is created + for that name) + + + JPA server did not correctly index search parameters of type "reference" where the + path had multiple entries (i.e. "Resource.path1 | Resource.path2") + + + JPA server _history operations (server, type, instance) not correctly set the + Bundle.entry.request.method to POST or PUT for create and updates of the resource. + + + Support AND/OR on _id search parameter in JPA + + + Constructor for DateRanfeParam which dates in two DateParam instances was ignoring + comparators on the DateParam. + + + In JSON parsing, finding an object where an array was expected led to an unhelpful + error message. Thanks to Avinash Shanbhag for reporting! + + + JPA server gave an unhelpful error message if $meta-add or $meta-delete were called + with no meta elements in the input Parameters + + + Narrative generator did not include OperationOutcome.issue.diagnostics in the + generated narrative. + + + Clients (generic and annotation) did not populate the Accept header on outgoing + requests. This is now populated to indicate that the client supports both XML and + JSON unless the user has explicitly requested one or the other (in which case the + appropriate type only will be send in the accept header). Thanks to + Avinash Shanbhag for reporting! + + + QuestionnaireResponse validator now allows responses to questions of + type OPENCHOICE to be of type 'string' + + + JPA server should reject resources with a reference that points to an incorrectly typed + resource (e.g. points to Patient/123 but resource 123 is actually an Observation) or points + to a resource that is not valid in the location it is found in (e.g. points to Patient/123 but + the field supposed to reference an Organization). Thanks to Bill de Beaubien for reporting! + + + In server, if a client request is received and it has an Accept header indicating + that it supports both XML and JSON with equal weight, the server's default is used instead of the first entry in the list. + + + JPA server now supports searching with sort by token, quantity, + number, Uri, and _lastUpdated (previously only string, date, and _id + were supported) + + + Fix issue in JPA where a search with a _lastUpdated filter which matches no results + would crash if the search also had a _sort + + + Fix several cases where invalid requests would cause an HTTP 500 instead of + a more appropriate 400/404 in the JPA server (vread on invalid version, + delete with no ID, etc.) + + + Fix narrative generation for DSTU2 Medication resource + + + Profile validator now works for valuesets which use + v2 tables + + + JPA server Patient/[id]/$everything operation now supports + _lastUpdated filtering and _sort'ing of results. + + + Fix parser issue where profiled choice element datatypes (e.g. value[x] where one allowable + type is Duration, which is a profile of Quantity) get incorrectly encoded using the + profiled datatype name instead of the base datatype name as required by the FHIR + spec. Thanks to Nehashri Puttu Lokesh for reporting! + + + Some generated Enum types in DSTU2 HAPI structures + did not have latest valueset definitions applied. Thanks + to Bill de Beaubien for reporting! + + + JPA server can now successfully search for tokens pointing at code values + (values with no explicit system but an implied one, such as Patient.gender) + even if the system is supplied in the query. + + + Correct issues with Android library. Thanks to + Thomas Andersen for the submission! + + + JPA server incorrectly rejected match URLs + if they did not contain a question mark. Thanks + to Bill de Beaubien for reporting! + + + Remove invalid entries in OSGi Manifest. Thanks + to Alexander Kley for the fix! + + + JPA server now supports $everything on Patient and Encounter types (patient and encounter instance was already supported) + + + Generic client operation invocations now + have an additional inline method for generating the input + Parameters using chained method calls instead + of by passing a Parameters resource in + + + Parsing an XML resource where the XHTML + namespace was declared before the beginning + of the narrative section caused an invalid + re-encoding when encoding to JSON. + + + Conditional deletes in JPA did not correctly + process if the condition had a chain or a + qualifier, e.g. "Patient?organization.name" or + "Patient.identifier:missing" + + + Generic/fluent client search can now be + performed using a complete URL supplied + by user code. Thanks to Simone Heckmann + pointing out that this was needed! + + + Refactor JPA $everything operations so that + they perform better + + + Server operation methods can now declare the + ID optional, via + @IdParam(optional=true) + meaning that the same operation can also be invoked + at the type level. + + + Make JPA search queries with _lastUpdated parameter a bit more efficient + + + Clean up Android project to make it more lightweight and remove a + number of unneeded dependencies. Thanks to Thomas Andersen + for the pull request! + + + Fix a crash when encoding a Binary resource in JSON encoding + if the resource has no content-type + + + JPA server now supports read/history/search in transaction entries + by calling the actual implementing method in the server (previously + the call was simulated, which meant that many features did not work) + + + ResourceReferenceDt#loadResource(IRestfulClient) did not + use the client's read functionality, so it did not + handle JSON responses or use interceptors. Thanks to + JT for reporting! + + + JPA server maximumn length for a URI search parameter has been reduced from + 256 to 255 in order to accomodate MySQL's indexing requirements + + + Server failed to respond correctly to compartment search operations + if the same provider also contained a read operation. Thanks to GitHub user + @am202 for reporting! + + + Fix issue in testpage-overlay's new Java configuration where only the first + configured server actually gets used. + + + Introduce + IJpaServerInterceptor]]> + interceptors for JPA server which can be used for more fine grained operations. + + + Parser (XML and JSON) shouldn't encode an ID tag in resources + which are part of a bundle when the resource has a UUID/OID + ID. + + + Add ability for a server REST resource provider @Search method + to declare that it should allow even parameters it doesn't + understand. + + + Correctly set the Bundle.type value on all pages of a search result in + the server, and correcltly set the same value in JPA server $everything + results. + + + JPA $everything operations now support new parameters _content + and _text, which work the same way as the same parameters on a + search. This is experimental, since it is not a part of the core + FHIR specification. + + + Process "Accept: text/xml" and "Accept: text/json" headers was + wanting the equivalent FHIR encoding styles. These are not + correct, but the intention is clear so we will honour them + just to be helpful. + + + Generated Enum types for some ValueSets did not include all + codes (specifically, ValueSets which defined concepts containing + child concepts did not result in Enum values for the child concepts) + + + In the JPA server, order of transaction processing should be + DELETE, POST, PUT, GET, and the order should not matter + within entries with the same verb. Thanks to Bill de Beaubien + for reporting! + + + Add the ability to wire JPA conformance providers + using Spring (basically, add default constructors + and setters to the conformance providers). Thanks + to C. Mike Bylund for the pull request! + +
    + + + JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire + if one is declared. + + + SyntaxHighlightingInterceptor now also highlights OperationOutcome responses for errors/exceptions. + + + Model classes do not use BoundCodeableConcept for example bindings that do not + actually point to any codes (e.g. Observation.interpretation). Thanks + to GitHub user @steve1medix for reporting! + + + Server now exports operations as separate resources instead of as contained resources + within Conformance + + + Add new operation $get-resource-counts which will replace the resource + count extensions exported in the Conformance statement by the JPA + server. + + + JPA server sorting often returned unexpected orders when multiple + indexes of the same type were found on the same resource (e.g. multiple string indexed fields). Thanks to Travis Cummings for reporting! + + + Add another method to IServerInterceptor which converts an exception generated on the server + into a BaseServerResponseException. This is useful so that servers using ResponseHighlighterInterceptor + will highlight exceptions even if they aren't created with an OperationOutcome. + + + XmlParser and JsonParser in DSTU2 mode should not encode empty + tags in resource. Thanks to Bill De Beaubien for reporting! + + + OperationDefinitions generated by server did not properly document + their return parameters or the type of their input parameters. + + + Operations in server generated conformance statement should only + appear once per name, since the name needs to be unique. + + + Resources and datatypes are now serializable. This is an + experimental feature which hasn't yet been extensively tested. Please test and give us your feedback! + + + Switch REST server to using HttpServletRequest#getContextPath() to get + the servlet's context path. This means that the server should behave more + predictably, and should work in servlet 2.4 environments. Thanks to + Ken Zeisset for the suggestion! + + + Vagrant environment now has an apt recipt to ensure that + package lists are up to date. Thanks to GitHub user + Brian S. Corbin (@corbinbs) for thr contribution! + + + JPA server and generic client now both support the _tag search parameter + + + Add support for BATCH mode to JPA server transaction operation + + + Server was not correctly unescaping URL parameter values with + a trailing comma or an escaped backslash. Thanks to GitHub user + @SherryH for all of her help in diagnosing this issue! + + + Avoid crash when parsing if an invalid child element is found in + a resource reference. + + + Create new android specialty libraries for DSTU1 and DSTU2 + + + Throwing a server exception (e.g. AuthenticationException) in a server interceptor's + incomingRequestPreProcessed method resulted in the server returning an HTTP 500 instead + of the appropriate error code for the exception being thrown. Thanks to Nagesh Bashyam + for reporting! + + + Fix issue in JSON parser where invalid contained resources (missing + a resourceType element) fail to parse with a confusing NullPointerException. + Thanks to GitHub user @hugosoares for reporting! + + + JPA server now implements the $validate-code operation + + + HAPI-FHIR now has support for _summary and _elements parameters, in server, client, + and JPA server. + + + _revinclude results from JPA server should have a Bundle.entry.search.mode of + "include" and not "match". Thanks to Josh Mandel for reporting! + + + Resource references using resource instance objects instead of resource IDs + will correctly qualify the IDs with the resource type if they aren't already qualified + + + Testpage Overlay project now properly allows a custom client + factory to be used (e.g. for custom authentication, etc.) Thanks + to Chin Huang (@pukkaone) for the pull request! + + + JPA server should reject IDs containing invalid characters (e.g. "abc:123") + but should allow client assigned IDs that contain text but do not start with + text. Thanks to Josh Mandel for reporting! + + + :text modifier on server and JPA server did not work correctly. Thanks to + Josh Mandel for reporting! + + + Fix issue in client where parameter values containing a comma were + sometimes double escaped. + + + _include parameters now support the new _include:recurse=FOO]]> + syntax that has been introduced in DSTU2 in the Client, Server, and JPA Server modules. + Non-recursive behaviour is now the default (previously it was recursive) and :recurse + needs to be explicitly stated in order to support recursion. + + + New operations added to JPA server to force re-indexing of all + resources (really only useful after indexes change or bugs are + fixed) + + + JPA server did not correctly index search parameters + of type "URI". Thanks to David Hay for reporting! Note that if you are using the JPA server, this change means that + there are two new tables added to the database schema. Updating existing resources in the database may fail unless you + set default values for the resource + table by issuing a SQL command similar to the following (false may be 0 or something else, depending on the database platform in use) + update hfj_resource set sp_coords_present = false;
    + update hfj_resource set sp_uri_present = false;
    ]]> +
    + + FIx issue in JPA server where profile declarations, tags, and + security labels were not always properly removed by an update that + was trying to remove them. Also don't store duplicates. + + + Instance $meta operations on JPA server did not previously return the + resource version and lastUpdated time + + + Server responses populate Bundle.entry.fullUrl if possible. Thanks + to Bill de Beaubien for reporting! + + + XML parser failed to initialize in environments where a very old Woodstox + library is in use (earlier than 4.0). Thanks to Bill de Beaubien for + reporting! + + + Invalid/unexpected attributes found when parsing composite elements + should be logged or reported to the parser error handler + + + JPA server can now store Conformance resources, per a request + from David Hay + + + ResponseHighlightingInterceptor now skips handling responses if it + finds a URL parameter of _raw=true]]> (in other + words, if this parameter is found, the response won't be returned as + HTML even if the request is detected as coming from a browser. + + + RestfulServer now supports dynamically adding and removing resource providers + at runtime. Thanks to Bill Denton for adding this. + + + JPA server now correctly suppresses contents of deleted resources + in history + + + JPA server returned deleted resources in search results when using the _tag, _id, _profile, or _security search parameters + + + Fix issue with build on Windows. Thanks to Bryce van Dyk for the pull request! + + + JPA server now supports $validate operation completely, including delete mode + and profile validation using the RI InstanceValidator + +
    + + + Add support for reference implementation structures. + + + Parsers did not encode the resource meta element if the resource + had tags but no other meta elements. Thanks to Bill de Beaubien and + Claude Nanjo for finding this. + + + Correct performance issue with :missing=true search requests where the parameter is a resource link. Thanks to wanghaisheng for all his help in testing this. + + + The self link in the Bundle returned by searches on the server does not respect the + server's address strategy (which resulted in an internal IP being shown on fhirtest.uhn.ca) + + + Introduce ResponseHighlighterInterceptor, which provides syntax highlighting on RESTful server responses + if the server detects that the request is coming from a browser. This interceptor has been added + to fhirtest.uhn.ca responses. + + + Performing a create operation in a client used an incorrect URL if the + resource had an ID set. ID should be ignored for creates. Thanks to + Peter Girard for reporting! + + + Add better addXXX() methods to structures, which take the datatype being added as a parameter. Thanks to Claude Nanjo for the + suggestion! + + + Add a new parser validation mechanism (see the + validation page]]> for info) which can be + used to validate resources as they are being parsed, and optionally fail if invalid/unexpected + elements are found in resource bodies during parsing. + + + IParser#parseResource(Class, String) method, which is used to parse a resource into the given + structure will now throw a DataFormatException if the structure is for the wrong type of + resource for the one actually found in the input String (or Reader). For example, if a Patient + resource is being parsed into Organization.class this will now cause an error. Previously, + the XML parser would ignore the type and the JSON parser would fail. This also caused + operations to not parse correctly if they returned a resource type other than + parameters with JSON encoding (e.g. the $everything operation on UHN's test server). + Thanks to Avinash Shanbhag for reporting! + + + Web tester UI now supports _revinclude + + + Support link elements in Bundle.entry when parsing in DSTU2 mode + using the old (non-resource) Bundle class. Thanks to GitHub user + @joedai for reporting! + + + LoggingInterceptor for server now supports logging DSTU2 extended operations by name + + + Woodstox XML parser has a default setting to limit the maximum + length of an attribute to 512kb. This caused issues handling + large attachments, so this setting has been increased to 100Mb. + Thanks to Nikos Kyriakoulakos for reporting! + + + Some HTML entities were not correctly converted during parsing. Thanks to + Nick Kitto for reporting! + + + In the JPA Server: + Transactions creating resources with temporary/placeholder resource IDs + and other resources with references to those placeholder IDs previously + did not work if the reference did not contain the resource type + (e.g. Patient/urn:oid:0.1.2.3 instead of urn:oid:0.1.2.3). The + latter is actually the correct way of specifying a reference to a + placeholder, but the former was the only way that worked. Both forms + now work, in order to be lenient. Thanks to Bill De Beaubien for + reporting! + + + When parsing Bundles, if Bundle.entry.base is set to "cid:" (for DSTU1) + or "urn:uuid:" / "urn:oid:" (for DSTU2) this is now correctly passed as + the base in resource.getId(). Conversely, when + encoding bundles, if a resource ID has a base defined, + and Bundle.entry.base is empty, it will now be + automatically set by the parser. + + + Add fluent client method for validate operation, and support the + new DSTU2 style extended operation for $validate if the client is + in DSTU2 mode. Thanks to Eric from the FHIR Skype Implementers chat for + reporting. + + + Server now supports complete Accept header content negotiation, including + q values specifying order of preference. Previously the q value was ignored. + + + Server in DSTU2 mode now indicates that whether it has support for Transaction operation or not. Thanks to Kevin Paschke for pointing out that this wasn't working! + + + Questionnaire.title now gets correctly indexed in JPA server (it has no path, so it is a special case) + + + JPA server now supports ifNoneMatch in GET within a transaction request. + + + DateRangeParam now supports null values in the constructor for lower or upper bounds (but + still not both) + + + Generic/fluent client and JPA server now both support _lastUpdated search parameter + which was added in DSTU2 + + + JPA server now supports sorting on reference parameters. Thanks to + Vishal Kachroo for reporting that this wasn't working! + + + Prevent Last-Updated header in responses coming back to the client from + overwriting the 'lastUpdated' value in the meta element in DSTU2 + resources. This is important because 'lastUpdated' can have more + precision than the equivalent header, but the client previously + gave the header priority. + + + JPA server supports _count parameter in transaction containing search URL (nested search) + + + DSTU2 servers now indicate support for conditional create/update/delete in their + conformance statement. + + + Support for the Prefer header has been added to the server, client, and + JPA modules. + + + JPA server failed to search for deep chained parameters across multiple references, + e.g. "Location.partof.partof.organization". Thanks to Ismael Sarmento Jr for + reporting! + + + Prevent crash when encoding resources with contained resources + if the contained resources contained a circular reference to each other + + + Add $meta, $meta-add, and $meta-delete operations to generic client + + + + + Bump the version of a few dependencies to the + latest versions: + +
  • Phloc-commons (for schematron validation) 4.3.5 -> 4.3.6
  • +
  • Apache HttpClient 4.3.6 -> 4.4
  • +
  • Woodstox 4.4.0 -> 4.4.1
  • +
  • SLF4j 1.7.9 -> 1.7.10
  • +
  • Spring (used in hapi-fhir-jpaserver-base module) 4.1.3.RELEASE -> 4.1.5.RELEASE
  • + + ]]> +
    + + Add support for "profile" and "tag" elements in the resource Meta block + when parsing DSTU2 structures. + + + When a user manually creates the list of contained resources in a resource, + the encoder fails to encode any resources that don't have a '#' at the + start of their ID. This is unintuitive, so we now assume that '123' means '#123'. + Thanks to myungchoi for reporting and providing a test case! + + + Add methods for setting the default encoding (XML/JSON) and + oretty print behaviour in the Fluent Client. Thanks to Stackoverflow + user ewall for the idea. + + + JPA Server did not mark a resource as "no longer deleted" if it + was updated after being deleted. Thanks to Elliott Lavy and Lloyd + McKenzie for reporting! + + + Fix regression in 0.9 - Server responds with an HTTP 500 and a NullPointerException instead of an HTTP 400 and a useful error message if the client requests an unknown resource type + + + Add support for + _revinclude]]> + parameter in client, server, and JPA. + + + Include constants on resources (such as + Observation.INCLUDE_VALUE_STRING]]>) + have been switched in the DSTU2 structures to use + the new syntax required in DSTU2: [resource name]:[search param NAME] + insead of the DSTU1 style [resource name].[search param PATH] + + + When encoding resources, the parser will now convert any resource + references to versionless references automatically (i.e. it will + omit the version part automatically if one is present in the reference) + since references between resources must be versionless. Additionally, + references in server responses will omit the server base URL part of the + reference if the base matches the base for the server giving + the response. + + + Narrative generator incorrectly sets the Resource.text.status to 'generated' even if the + given resource type does not have a template (and therefore no narrative is actually generated). + Thanks to Bill de Beaubien for reporting! + + + Searching in JPA server with no search parameter returns deleted resources when it should exclude them. + + + Remove Eclipse and IntelliJ artifacts (.project, *.iml, etc) from version control. Thanks + to Doug Martin for the suggestion! + + + REST server methods may now have a parameter of + type NarrativeModeEnum which will be populated with + the value of the _narrative URL parameter + if one was supplied. Annotation client methods + may also include a parameter of this type, and it + will be used to populate this parameter on the request + URL if it is not null. Thanks to Neal Acharya for the + idea! + + + Android JAR now includes servlet-API classes, as the project will not + work without them. Thanks + + + Requested _include values are preserved across paging links when the + server returns multiple pages. Thanks to Bill de Beaubien for + reporting! + + + Add new server address strategy "ApacheProxyAddressStrategy" which uses + headers "x-forwarded-host" and "x-forwarded-proto" to determine the + server's address. This is useful if you are deploying a HAPI FHIR + server behind an Apache proxy (e.g. for load balancing or other reasons). + Thanks to Bill de Beaubien for contributing! + + + Resource references between separate resources found in a single + bundle did not get populated with the actual resource when parsing a + DSTU2 style bundle. Thanks to Nick Peterson for reporting and figuring + out why none of our unit tests were actually catching the problem! + + + JSON encoder did not encode contained resources when encoding + a DSTU2 style bundle. Thanks to Mohammad Jafari and baopingle + for all of their help in tracking this issue down and developing + useful unit tests to demonstrate it. + + + Client now supports invoking transcation using a DSTU2-style + Bundle resource as the input. + + + JPA Server $everything operation could sometimes include a duplicate copy of + the main focus resource if it was referred to in a deep chain. Thanks + to David Hay for reporting! + + + JPA Server $everything operation now allows a _count parameter + + + JPA server failed to index resources containing ContactPointDt elements with + populated values (e.g. Patient.telecom). Thanks to Mohammad Jafari for reporting! + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Terser's IModelVisitor now supplies to the path to the element. This is + an API change, but I don't think there are many users of the IModelVisitor yet. + Please let us know if this is a big hardship and we can find an alternate way + of making this change. + + + Prevent server from returning a Content-Location header for search + response when using the DSTU2 bundle format + + + JPA server (uhnfhirtest.uhn.ca) sometimes included an empty + "text" element in Bundles being returned. + + + Add a framework for the Web Tester UI to allow its internal FHIR client to + be configured (e.g. to add an authorization interceptor so that it adds + credentials to client requests it makes). Thanks to Harsha Kumara for + the suggestion! + + + Fix regression in early 1.0 builds where resource type sometimes does not get + populated in a resource ID when the resource is parsed. Thanks to + Nick Peterson for reporting, and for providing a test case! + + + Allow fluent/generic client users to execute a transaction using a raw string (containing a bundle resource) + as input instead of a Bundle resource class instance. + + + Disable date validation in the web tester UI, so that it is possible to + enter partial dates, or dates without times, or even test out invalid date + options. + + + Make BaseElement#getUndeclaredExtensions() and BaseElement#getUndeclaredExtensions() return + a mutable list so that it is possible to delete extensions from a resource instance. + + + Server conformance statement check in clients (this is the check + where the first time a given FhirContext is used to access a given server + base URL, it will first check the server's Conformance statement to ensure + that it supports the correct version of FHIR) now uses any + registered client interceptors. In addition, IGenericClient now has a method + "forceConformanceCheck()" which manually triggers this check. Thanks to + Doug Martin for reporting and suggesting! + + + Rename the Spring Bean definition for the JPA server EntityManager from + "myEntityManagerFactory" to just "entityManagerFactory" as this is the + default bean name expected in other parts of the Spring framework. + Thanks to Mohammad Jafari for the suggestion! + + + Improve error message when a user tries to perform a create/update with an invalid + or missing Content-Type header. Thanks to wanghaisheng for reporting! (This was + actually a three part bug, so the following two fixes also reference this + bug number) + + + Add support for :missing qualifier in generic/fluent client. + + + Add support for :missing qualifier in JPA server. + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Add an exception for RESTful clients/servers to represent the + HTTP 403 Forbidden status code. Thanks to Joel Costigliola for + the patch! + + + Transaction server operations incorrectly used the "Accept" header instead of the "Content-Type" header to determine the + POST request encoding. Thanks to Rene Spronk for providing a test case! + +
    + + + Support for DSTU2 features introduced: New resource definitions, Bundle resource, + encoding changes (ID in resource bodt, meta tag) + + + Fix an issue encoding extensions on primitive types in JSON. Previously the "_value" object + would be an array even if the field it was extending was not repeatable. This is not correct + according to the specification, nor can HAPI's parser parse this correctly. The encoder + has been corrected, and the parser has been adjusted to be able to handle resources with + extensions encoded in this way. Thanks to Mohammad Jafari for reporting! + + + Library now checks if custom resource types can be instantiated on startup + (e.g. because they don't have a no-argument constructor) in order to + avoid failing later + + + Bump a few dependency JARs to the latest versions in Maven POM: + +
  • SLF4j (in base module) - Bumped to 1.7.9
  • +
  • Apache HTTPClient (in base module) - Bumped to 4.3.6
  • +
  • Hibernate (in JPA module) - Bumped to 4.3.7
  • + + ]]> +
    + + IdDt failed to recognize local identifiers containing fragments that look like + real identifiers as being local identifiers even though they started with '#'. + For example, a local resource reference of "#aa/_history/aa" would be incorrectly + parsed as a non-local reference. + Thanks to Mohammad Jafari for reporting! + + + Last-Modified]]> + header in server was incorrectly using FHIR date format instead + of RFC-1123 format. + + + Server create and update methods failed with an IllegalArgumentException if + the method type was a custom resource definition type (instead of a built-in + HAPI type). Thanks to Neal Acharya for the analysis. + + + JPA server module now supports + _include]]> + value of + *]]>. Thanks to Bill de Beaubien for reporting! + + + IdDt method + + returned String (unlike all of the other "withFoo" methods on that class), + and did not work correctly if the IdDt already had a server base. This + has been corrected. Note that the return type for this method has been + changed, so code may need to be updated. + + + In previous versions of HAPI, the XML parser encoded multiple contained + resources in a single + <contained></contained>]]> + tag, even though the FHIR specification rerquires a separate + <contained></contained>]]> + tag for each resource. This has been corrected. Note that the parser will + correctly parse either form (this has always been the case) so this + change should not cause any breakage in HAPI based trading partners, but + may cause issues if other applications have been coded to depend on the + incorrect behaviour. Thanks to Mochaholic for reporting! + + + Custom/user defined resource definitions which contained more than one + child with no order defined failed to initialize properly. Thanks to + Andy Huang for reporting and figuring out where the + problem was! + + + RESTful Client now queries the server (only once per server base URL) to ensure that + the given server corresponds to the correct version of the FHIR specification, as + defined by the FhirContext. This behaviour can be disabled by setting the + appropriate configuration on the + RestfulClientConfig. Thanks to Grahame Grieve for the suggestion! + + + JPA module now supports deleting resource via transaction + + + DateClientParam#second() incorrectly used DAY precision instead + of SECOND precision. Thanks to Tom Wilson for the pull request! + + + Fix issue where HAPI failed to initialize correctly if Woodstox library was not on the classpath, even + if StAX API was configured to use a different provider. Thanks to + James Butler for reporting and figuring out where the issue was! + + + Calling BaseDateTimeDt#setValue(Date, TemporalPrecisionEnum) did not always actually respect + the given precision when the value was encoded. Thanks to jacksonjesse for + reporting! + + + Encoders (both XML and JSON) will no longer encode contained resources if they are + not referenced anywhere in the resource via a local reference. This is just a convenience + for users who have parsed a resource with contained resources and want to remove some + before re-encoding. Thanks to Alexander Kley for reporting! + + + Add support for DSTU2 style security labels in the parser and encoder. Thanks to + Mohammad Jafari for the contribution! + + + Server requests for Binary resources where the client has explicitly requested XML or JSON responses + (either with a _format]]> URL parameter, or an Accept]]> request header) + will be responded to using the Binary FHIR resource type instead of as Binary blobs. This is + in accordance with the recommended behaviour in the FHIR specification. + + + Add new properties to RestfulServer: "DefaultResponseEncoding", which allows + users to configure a default encoding (XML/JSON) to use if none is specified in the + client request. Currently defaults to XML. Also "DefaultPrettyPrint", which specifies + whether to pretty print responses by default. Both properties can be overridden + on individual requets using the appropriate Accept header or request URL parameters. + + + Add support for quantity search params in FHIR tester UI + + + Add support for FHIR "extended operations" as defined in the FHIR DSTU2 + specification, for the Generic Client, Annotation Client, and + Server. + + + Observation.applies[x] and other similar search fields with multiple allowable + value types were not being correctly indexed in the JPA server. + + + DateClientParam.before() incorrectly placed "<=" instead of + "<" in the request URL. Thanks to Ryan for reporting! + + + Server now only automatically adds _include resources which are provided + as references if the client request actually requested that specific include. + See RestfulServer + + + User defined resource types which contain extensions that use a bound code type + (e.g. an BoundCodeDt with a custom Enum) failed to parse correctly. Thanks + to baopingle for reporting and providing a test case! + + + Sorting is now supported in the Web Testing UI (previously a button existed for sorting, but it didn't do anything) + + + Server will no longer include stack traces in the OperationOutcome returned to the client + when an exception is thrown. A new interceptor called ExceptionHandlingInterceptor has been + created which adds this functionality back if it is needed (e.g. for DEV setups). See the + server interceptor documentation for more information. Thanks to Andy Huang for the suggestion! + +
    + + + API CHANGE:]]> The "FHIR structures" for DSTU1 (the classes which model the + resources and composite datatypes) have been moved out of the core JAR into their + own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast + version is finalized. See the + DSTU2 page]]> + for more information. + + + Deprocated API Removal: The following classes (which were deprocated previously) + have now been removed: +
      +
    • ISecurityManager: If you are using this class, the same functionality + is available through the more general purpose + server interceptor + capabilities. +
    • CodingListParam: This class was made redundant by the + TokenOrListParam + class, which can be used in its place. +
    + ]]> +
    + + API Change: The IResource#getResourceMetadata() method has been changed + from returning + Map<ResourceMetadataKeyEnum<?>, Object> + to returning a new type called + ResourceMetadataMap. This new type implements + Map<ResourceMetadataKeyEnum<?>, Object> + itself, so this change should not break existing code, but may + require a clean build in order to run correctly. + ]]> + + + Profile generation on the server was not working due to IdDt being + incorrectly used. Thanks to Bill de Beaubien for the pull request! + + + Profiles did not generate correctly if a resource definition class had a + defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request! + + + Remove unnecessary IOException from narrative generator API. Thanks to + Petro Mykhailysyn for the pull request! + + + Introduced a new + @ProvidesResources]]> annotation which can be added to + resource provider and servers to allow them to declare additional resource + classes they are able to serve. This is useful if you have a server which can + serve up multiple classes for the same resource type (e.g. a server that sometimes + returns a default Patient, but sometimes uses a custom subclass). + Thanks to Bill de Beaubien for the pull request! + + + Introduced a new + @Destroy]]> annotation which can be added to + a resource provider method. This method will be called by the server when it + is being closed/destroyed (e.g. when the application is being undeployed, the + container is being shut down, etc.) + Thanks to Bill de Beaubien for the pull request! + + + Add a new method to the server interceptor + framework which allows interceptors to be notified of any exceptions and + runtime errors within server methods. Interceptors may optionally also + override the default error handling behaviour of the RestfulServer. + + + Add constants to BaseResource for the "_id" search parameter which all resources + should support. + + + DateRangeParam parameters on the server now return correct + getLowerBoundAsInstant()]]> + and + getUpperBoundAsInstant()]]> + values if a single unqualified value is passed in. For example, if + a query containing + &birthdate=2012-10-01]]> + is received, previously these two methods would both return the same + value, but with this fix + getUpperBoundAsInstant()]]> + now returns the instant at 23:59:59.9999. + + + Resource fields with a type of "*" (or Any) sometimes failed to parse if a + value type of "code" was used. Thanks to Bill de Beaubien for reporting! + + + Remove dependency on JAXB libraries, which were used to parse and encode + dates and times (even in the JSON parser). JAXB is built in to most JDKs + but the version bundled with IBM's JDK is flaky and resulted in a number + of problems when deploying to Websphere. + + + Primitive datatypes now preserve their original string value when parsing resources, + as well as containing the "parsed value". For instance, a DecimalDt field value of + 1.0000]]> will be parsed into the corresponding + decimal value, but will also retain the original value with the corresponding + level of precision. This allows vadliator rules to be applied to + original values as received "over the wire", such as well formatted but + invalid dates, e.g. "2001-15-01". Thanks to Joe Athman for reporting and + helping to come up with a fix! + + + When using Generic Client, if performing a + or operation using a String as the resource body, + the client will auto-detect the FHIR encoding style and send an appropriate + header. + + + JPA module (and public HAPI-FHIR test server) were unable to process resource types + where at least one search parameter has no path specified. These now correctly save + (although the server does not yet process these params, and it should). Thanks to + GitHub user shvoidlee for reporting and help with analysis! + + + Generic/Fluent Client "create" and "update" method requests were not setting a content type header + + + DateDt left precision value as in the constructor + . + + + RESTful server now doesn't overwrite resource IDs if they are absolute. In other words, if + a server's Resource Provider returns a resource with ID "Patient/123" it will be translated to + "[base url]/Patient/123" but if the RP returns ID "http://foo/Patient/123" the ID will be + returned exactly as is. Thanks to Bill de Beaubien for the suggestion! + + + JPA module Transaction operation was not correctly replacing logical IDs + beginning with "cid:" with server assigned IDs, as required by the + specification. + + + did not visit or find children in contained resources when + searching a resource. This caused server implementations to not always return contained + resources when they are included with a resource being returned. + + + Add a method which returns the name of the + resource in question (e.g. "Patient", or "Observation"). This is intended as a + convenience to users. + + + Do not strip version from resource references in resources returned + from server search methods. Thanks to Bill de Beaubien for reporting! + + + Correct an issue with the validator where changes to the underlying + OperationOutcome produced by a validation cycle cause the validation + results to be incorrect. + + + Client interceptors registered to an interface based client instance + were applied to other client instances for the same client interface as well. (Issue + did not affect generic/fluent clients) + + + DateDt, DateTimeDt and types InstantDt types now do not throw an exception + if they are used to parse a value with the wrong level of precision for + the given type but do throw an exception if the wrong level of precision + is passed into their constructors.
    ]]> + This means that HAPI FHIR can now successfully parse resources from external + sources that have the wrong level of precision, but will generate a validation + error if the resource is validated. Thanks to Alexander Kley for the suggestion! +
    + + Encoding a Binary resource without a content type set should not result in a NullPointerException. Thanks + to Alexander Kley for reporting! + + + Server gives a more helpful error message if multiple IResourceProvider implementations + are provided for the same resource type. Thanks to wanghaisheng for the idea! + + + Bring DSTU1 resource definitions up to version 0.0.82-2929]]> + Bring DEV resource definitions up to 0.4.0-3775]]> + Thanks to crinacimpian for reporting! + + + JPA server did not correctly process _include requests if included + resources were present with a non-numeric identifier. Thanks to + Bill de Beaubien for reporting! + + + Client requests which include a resource/bundle body (e.g. create, + update, transaction) were not including a charset in the content type + header, leading to servers incorrectly assuming ISO-8859/1. Thanks to + shvoidlee for reporting! + + + Clean up the way that Profile resources are automatically exported + by the server for custom resource profile classes. See the + @ResourceDef]]> + JavaDoc for information on how this works. + + + Add convenience methods to TokenOrListParam to test whether any of a set of tokens match + the given requested list. + + + Add a protected method to RestfulServer which allows developers to + implement their own method for determining which part of the request + URL is the FHIR request path (useful if you are embedding the RestulServer inside + of another web framework). Thanks to Harsha Kumara for the pull request! + +
    + + + API CHANGE:]]> The TagList class previously implemented ArrayList semantics, + but this has been replaced with LinkedHashMap semantics. This means that the list of + tags will no longer accept duplicate tags, but that tag order will still be + preserved. Thanks to Bill de Beaubien for reporting! + + + Server was incorrectly including contained resources being returned as both contained resources, and as + top-level resources in the returned bundle for search operations. + Thanks to Bill de Beaubien for reporting! This also fixes Issue #20, thanks to + lephty for reporting! + + + Documentation fixes + + + Add a collection of new methods on the generic client which support the + read, + read, + and search + ]]> + operations using an absolute URL. This allows developers to perform these operations using + URLs they obtained from other sources (or external resource references within resources). In + addition, the existing read/vread operations will now access absolute URL references if + they are passed in. Thanks to Doug Martin of the Regenstrief Center for Biomedical Informatics + for contributing this implementation! + + + Server implementation was not correctly figuring out its own FHIR Base URL when deployed + on Amazon Web Service server. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + XML Parser failed to encode fields with both a resource reference child and + a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + HAPI now runs successfully on Servlet 2.5 containers (such as Tomcat 6). Thanks to + Bernard Gitaadji for reporting and diagnosing the issue! + + + Summary (in the bundle entry) is now encoded by the XML and JSON parsers if supplied. Thanks to David Hay of + Orion Health for reporting this! + + + Conformance profiles which are automatically generated by the server were missing a few mandatory elements, + which meant that the profile did not correctly validate. Thanks to Bill de Beaubien of Systems Made Simple + for reporting this! + + + XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters + escaped properly in encoded messages. + + + Resources containing entities which are not valid in basic XML (e.g. &sect;) will have those + entities converted to their equivalent unicode characters when resources are encoded, since FHIR does + not allow extended entities in resource instances. + + + Add a new client interceptor which adds HTTP Authorization Bearer Tokens (for use with OAUTH2 servers) + to client requests. + + + Add phloc-commons dependency explicitly, which resolves an issue building HAPI from source on + some platforms. Thanks to Odysseas Pentakalos for the patch! + + + HAPI now logs a single line indicating the StAX implementation being used upon the + first time an XML parser is created. + + + Update methods on the server did not return a "content-location" header, but + only a "location" header. Both are required according to the FHIR specification. + Thanks to Bill de Beaubien of Systems Made Simple for reporting this! + + + Parser failed to correctly read contained Binary resources. Thanks to Alexander Kley for + the patch! + + + Calling encode multiple times on a resource with contained resources caused the contained + resources to be re-added (and the actual message to grow) with each encode pass. Thanks to + Alexander Kley for the test case! + + + JSON-encoded contained resources with the incorrect "_id" element (which should be "id", but some + incorrect examples exist on the FHIR specification) now parse correctly. In other words, HAPI + previously only accepted the correct "id" element, but now it also accepts the incorrect + "_id" element just to be more lenient. + + + Several unit tests failed on Windows (or any platform with non UTF-8 default encoding). This may + have also caused resource validation to fail occasionally on these platforms as well. + Thanks to Bill de Beaubien for reporting! + + + toString() method on TokenParam was incorrectly showing the system as the value. + Thanks to Bill de Beaubien for reporting! + + + Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks + to David Hay of Orion Health for reporting! + + + Add a + Vagrant]]> + based environment (basically a fully built, self contained development environment) for + trying out the HAPI server modules. Thanks to Preston Lee for the pull request, and for + offering to maintain this! + + + Change validation API so that it uses a return type instead of exceptions to communicate + validation failures. Thanks to Joe Athman for the pull request! + + + Add a client interceptor which adds an HTTP cookie to each client request. Thanks to + Petro Mykhailysyn for the pull request! + + + + + + Add server interceptor framework, and new interceptor for logging incoming + requests. + + + Add server validation framework for validating resources against the FHIR schemas and schematrons + + + Tester UI created double _format and _pretty param entries in searches. Thanks to Gered King of University + Health Network for reporting! + + + Create method was incorrectly returning an HTTP 204 on sucessful completion, but + should be returning an HTTP 200 per the FHIR specification. Thanks to wanghaisheng + for reporting! + + + FHIR Tester UI now correctly sends UTF-8 charset in responses so that message payloads containing + non US-ASCII characters will correctly display in the browser + + + JSON parser was incorrectly encoding extensions on composite elements outside the element itself + (as is done correctly for non-composite elements) instead of inside of them. Thanks to David Hay of + Orion for reporting this! + + + Contained/included resource instances received by a client are now automatically + added to any ResourceReferenceDt instancea in other resources which reference them. + + + Add documentation on how to use eBay CORS Filter to support Cross Origin Resource + Sharing (CORS) to server. CORS support that was built in to the server itself has + been removed, as it did not work correctly (and was reinventing a wheel that others + have done a great job inventing). Thanks to Peter Bernhardt of Relay Health for all the assistance + in testing this! + + + IResource interface did not expose the getLanguage/setLanguage methods from BaseResource, + so the resource language was difficult to access. + + + JSON Parser now gives a more friendly error message if it tries to parse JSON with invalid use + of single quotes + + + Transaction server method is now allowed to return an OperationOutcome in addition to the + incoming resources. The public test server now does this in order to return status information + about the transaction processing. + + + Update method in the server can now flag (via a field on the MethodOutcome object being returned) + that the result was actually a creation, and Create method can indicate that it was actually an + update. This has no effect other than to switch between the HTTP 200 and HTTP 201 status codes on the + response, but this may be useful in some circumstances. + + + Annotation client search methods with a specific resource type (e.g. List<Patient> search()) + won't return any resources that aren't of the correct type that are received in a response + bundle (generally these are referenced resources, so they are populated in the reference fields instead). + Thanks to Tahura Chaudhry of University Health Network for the unit test! + + + Added narrative generator template for OperationOutcome resource + + + Date/time types did not correctly parse values in the format "yyyymmdd" (although the FHIR-defined format + is "yyyy-mm-dd" anyhow, and this is correctly handled). Thanks to Jeffrey Ting of Systems Made Simple + for reporting! + + + Server search method for an unnamed query gets called if the client requests a named query + with the same parameter list. Thanks to Neal Acharya of University Health Network for reporting! + + + Category header (for tags) is correctly read in client for "read" operation + + + Transaction method in server can now have parameter type Bundle instead of + List<IResource> + + + HAPI parsers now use field access to get/set values instead of method accessors and mutators. + This should give a small performance boost. + + + JSON parser encodes resource references incorrectly, using the name "resource" instead + of the name "reference" for the actual reference. Thanks to + Ricky Nguyen for reporting and tracking down the issue! + + + Rename NotImpementedException to NotImplementedException (to correct typo) + + + Server setUseBrowserFriendlyContentType setting also respected for errors (e.g. OperationOutcome with 4xx/5xx status) + + + Fix performance issue in date/time datatypes where pattern matchers were not static + + + Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but + previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting! + + + Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health + for reporting! + + + QuantityParam correctly encodes approximate (~) prefix to values + + + If a server defines a method with parameter "_id", incoming search requests for that method may + get delegated to the wrong method. Thanks to Neal Acharya for reporting! + + + SecurityEvent.Object structural element has been renamed to + SecurityEvent.ObjectElement to avoid conflicting names with the + java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for + reporting! + + + Text/narrative blocks that were created with a non-empty + namespace prefix (e.g. <xhtml:div xmlns:xhtml="...">...</xhtml:div>) + failed to encode correctly (prefix was missing in encoded resource) + + + Resource references previously encoded their children (display and reference) + in the wrong order so references with both would fail schema validation. + + + SecurityEvent resource's enums now use friendly enum names instead of the unfriendly + numeric code values. Thanks to Laurie MacDougall-Sookraj of UHN for the + suggestion! + + + + + HAPI has a number of RESTful method parameter types that have similar but not identical + purposes and confusing names. A cleanup has been undertaken to clean this up. + This means that a number of existing classes + have been deprocated in favour of new naming schemes. +
    ]]> + All annotation-based clients and all server search method parameters are now named + (type)Param, for example: StringParam, TokenParam, etc. +
    ]]> + All generic/fluent client method parameters are now named + (type)ClientParam, for example: StringClientParam, TokenClientParam, etc. +
    ]]> + All renamed classes have been retained and deprocated, so this change should not cause any issues + for existing applications but those applications should be refactored to use the + new parameters when possible. +
    + + Allow server methods to return wildcard generic types (e.g. List<? extends IResource>) + + + Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as + "&identifier=system|codepart1\|codepart2" + + + Add support for OPTIONS verb (which returns the server conformance statement) + + + Add support for CORS headers in server + + + Bump SLF4j dependency to latest version (1.7.7) + + + Add interceptor framework for clients (annotation based and generic), and add interceptors + for configurable logging, capturing requests and responses, and HTTP basic auth. + + + Transaction client invocations with XML encoding were using the wrong content type ("application/xml+fhir" instead + of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one! + + + Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion! + + + If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or + an OperationOutcome resource, include the message in the exception message so that it will be + more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion! + + + Read invocations in the client now process the "Content-Location" header and use it to + populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion! + + + Fix issue where vread invocations on server incorrectly get routed to instance history method if one is + defined. Thanks to Neal Acharya from UHN for surfacing this one! + + + Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary + blobs from being used for nefarious purposes. See + FHIR Tracker Bug 3298]]> + for more information. + + + Support has been added for using an HTTP proxy for outgoing requests. + + + Fix: Primitive extensions declared against custom resource types + are encoded even if they have no value. Thanks to David Hay of Orion for + reporting this! + + + Fix: RESTful server deployed to a location where the URL to access it contained a + space (e.g. a WAR file with a space in the name) failed to work correctly. + Thanks to David Hay of Orion for reporting this! + +
    + + + BREAKING CHANGE:]]>: IdDt has been modified so that it + contains a partial or complete resource identity. Previously it contained + only the simple alphanumeric id of the resource (the part at the end of the "read" URL for + that resource) but it can now contain a complete URL or even a partial URL (e.g. "Patient/123") + and can optionally contain a version (e.g. "Patient/123/_history/456"). New methods have + been added to this datatype which provide just the numeric portion. See the JavaDoc + for more information. + + + API CHANGE:]]>: Most elements in the HAPI FHIR model contain + a getId() and setId() method. This method is confusing because it is only actually used + for IDREF elements (which are rare) but its name makes it easy to confuse with more + important identifiers. For this reason, these methods have been deprocated and replaced with + get/setElementSpecificId() methods. The old methods will be removed at some point. Resource + types are unchanged and retain their get/setId methods. + + + Allow use of QuantityDt as a service parameter to support the "quantity" type. Previously + QuantityDt did not implement IQueryParameterType so it was not valid, and there was no way to + support quantity search parameters on the server (e.g. Observation.value-quantity) + + + Introduce StringParameter type which can be used as a RESTful operation search parameter + type. StringParameter allows ":exact" matches to be specified in clients, and handled in servers. + + + Parsers (XML/JSON) now support deleted entries in bundles + + + Transaction method now supported in servers + + + Support for Binary resources added (in servers, clients, parsers, etc.) + + + Support for Query resources fixed (in parser) + + + Nested contained resources (e.g. encoding a resource with a contained resource that itself contains a resource) + now parse and encode correctly, meaning that all contained resources are placed in the "contained" element + of the root resource, and the parser looks in the root resource for all container levels when stitching + contained resources back together. + + + Server methods with @Include parameter would sometimes fail when no _include was actually + specified in query strings. + + + Client requests for IdentifierDt types (such as Patient.identifier) did not create the correct + query string if the system is null. + + + Add support for paging responses from RESTful servers. + + + Don't fail on narrative blocks in JSON resources with only an XML declaration but no content (these are + produced by the Health Intersections server) + + + Server now automatically compresses responses if the client indicates support + + + Server failed to support optional parameters when type is String and :exact qualifier is used + + + Read method in client correctly populated resource ID in returned object + + + Support added for deleted-entry by/name, by/email, and comment from Tombstones spec + + + + + + + + + +
    diff --git a/src/changes/changes_REMOTE_31097.xml b/src/changes/changes_REMOTE_31097.xml new file mode 100644 index 00000000000..3d75fcc329d --- /dev/null +++ b/src/changes/changes_REMOTE_31097.xml @@ -0,0 +1,2799 @@ + + + + James Agnew + HAPI FHIR Changelog + + + + + JSON parsing in HAPI FHIR has been switched from using JSR353 (javax.json) to + using Google Gson. For this reason we are bumping the major release number to + 2.0. Theoretically this should not affect projects in any major way, but Gson + does have subtle differences. Two differences which popped up a fair bit in + our own testing: + +
      + A space is placed after the : in keys, e.g. what was previously + encoded as "resourceType":"Patient" is now encoded + as "resourceType": "Patient" (this broke a number of + our unit tests with hardcoded resource definitions) +
    +
      + Trailing content after a valid json resource is rejected by + Gson (it was ignored by the Glassfish parser we were previously + using even though it was invalid) +
    + + ]]> +
    + + STU3 structure definitions have been updated to the + STU3 ballot candidate versions (1.5.0 - SVN 9395) + + + Both client and server now support the new Content Types decided in + FHIR #10199]]>. +
    ]]> + This means that the server now supports + application/fhir+xml and application/fhir+json]]> + in addition to the older style + application/xml+fhir and application/json+fhir]]>. + In order to facilitate migration by implementors, the old style remains the default + for now, but the server will respond using the new style if the request contains it. The + client now uses an Accept]]> header value which requests both + styles with a preference given to the new style when running in DSTU3 mode. +
    ]]> + As a part of this change, the server has also been enhanced so that if a request + contains a Content-Type header but no Accept header, the response will prefer the + encoding specified by the Content-Type header. +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Logback (used in sample projects): 1.1.5 -> 1.1.7
  • +
  • Phloc Commons (used by schematron validator): 4.4.4 -> 4.4.5
  • +
  • Commons-IO: 2.4 -> 2.5
  • +
  • Apache HTTPClient: 4.5.1 -> 4.5.2
  • +
  • Apache HTTPCore: 4.4.4 -> 4.4.5
  • +
  • Jersey (JAX-RS tests): 2.22.2 -> 2.23.1
  • +
  • Spring (JPA, Web Tester): 4.3.0 -> 4.3.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.4
  • + + ]]> +
    + + + Fix issue in DSTU1 Bundle parsing where unexpected elements in the bundle resulted in a failure + to parse. + + + DSTU2 QuestionnaireResponse validator failed with an exception if the + QuestionnaireResponse contained certain groups with no content + + + Fluent client should ignore parameter values which are null instead of including + them as ?foo=null]]> + + + When using _elements]]> parameter on server, the server was not + automatically adding the SUBSETTED]]> tag as it should + + + JPA server should now automatically detect + if Hibernate Search (Lucene) is configured to be + disabled and will not attempt to use it. This + prevents a crash for some operations. + + + A new server interceptor "BanUnsupprtedHttpMethodsInterceptor" has been added + which causes the server to return an HTTP 405 if an unsupported HTTP + verb is received from the client + + + Fix an issue where resource IDs were not correctly set when using + DSTU2 HL7org structures with the JAX-RS module. Thanks to Carlo Mion + for the pull request! + + + hapi-fhir-testpage-overlay project contained an unneccesary + dependency on hapi-fhir-jpaserver-base module, which resulted in + projects using the overlay having a large number of unnneded + JARs included + + + It is not possible to configure both the parser and the context to + preserve versions in resource references (default behaviour is to + strip versions from references). Thanks to GitHub user @cknaap + for the suggestion! + + + Tag#setCode(String)]]> did not actually set the code it was supposed to + set. Thanks to Tim Tschampel for reporting! + + + JPA server's /Bundle]]> endpoint cleared + the Bundle.entry.fullUrl]]> field on stored + bundles, resulting in invalid content being saved. Thanks to Mirjam + Baltus for reporting! + + + JPA server now returns HTTP 200 instead of HTTP 404 for + conditional deletes which did not find any matches, + per FHIR-I decision. + + + Client that declares explicitly that it is searching/reading/etc for + a custom type did not automatically parse into that type. + + + Allow servers to specify the authentication realm of their choosing when + throwing an AuthenticationException. Thanks to GitHub user @allanbrohansen + for the suggestion! + + + Add a new client implementation which uses the + OkHttp]]> + library as the HTTP client implementation (instead of Apache HttpClient). + This is particularly useful for Android (where HttpClient is a pain) but + could also be useful in other places too. + Thanks to Matt Clarke of Orion Health for the contribution! + + + Fix a regression when parsing resources that have contained + resources, where the reference in the outer resource which + links to the contained resource sometimes did does not get + populated with the actual target resource instance. Thanks to + Neal Acharya for reporting! + + + hapi-fhir-cli upload-terminology command now has an argument + "-b FOO" that lets you add an authorization header in the form + Authorization: Bearer FOO]]> + + + Parser failed to successfully encode a custom resource + if it contained custom fields that also used custom + types. Thanks to GitHub user @sjanic for reporting! + + + Servers in STU3 mode will now ignore any ID or VersionID found in the + resource body provided by the client when processing FHIR + update]]> operations. This change has been made + because the FHIR specification now requires servers to ignore + these values. Note that as a result of this change, resources passed + to @Update]]> methods will always have + null]]> ID + + + Add new methods to + AuthorizationInterceptor]]> + which allow user code to declare support for conditional + create, update, and delete. + + + When encoding a resource with a reference to another resource + that has a placeholder ID (e.g. urn:uuid:foo), the urn prefix + was incorrectly stripped from the reference. + +
    + + + Performance has been improved for the initial FhirContext + object creation by avoiding a lot of unnecessary reflection. HAPI FHIR + 1.5 had a regression compared to previous releases + and this has been corrected, but other improvements have been + made so that this release is faster than previous releases too. +
    ]]> + In addition, a new "deferred scan" mode has been implemented for + even faster initialization on slower environments (e.g. Android). + See the performance documentation]]> + for more information. +
    ]]> + The following shows our benchmarks for context initialization across several + versions of HAPI: + +
  • Version 1.4: 560ms
  • +
  • Version 1.5: 800ms
  • +
  • Version 1.6: 340ms
  • +
  • Version 1.6 (deferred mode): 240ms
  • + + ]]> +
    + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Spring (JPA, Web Tester): 4.2.5 -> 4.3.0
  • +
  • Spring-Data (JPA): 1.9.2 -> 1.10.1
  • + +
  • Hibernate Search (JPA): 5.5.2 -> 5.5.3
  • +
  • Jetty (CLI): 9.3.9 -> 9.3.10
  • + + ]]> +
    + + Remove some clases that were deprecated over a year ago and have + suitable replacements: + +
  • QualifiedDateParam has been removed, but DateParam may be used instead
  • +
  • PathSpecification has been removedm but Include may be used instead
  • + + ]]> +
    + + ResponseValidatingInterceptor threw an InternalErrorException (HTTP 500) for operations + that do not return any content (e.g. delete). Thanks to Mohammad Jafari for reporting! + + + REST server now throws an HTTP 400 instead of an HTTP 500 if an operation which takes + a FHIR resource in the request body (e.g. create, update) contains invalid content that + the parser is unable to parse. Thanks to Jim Steel for the suggestion! + + + Deprecate fluent client search operations without an explicit declaration of the + bundle type being used. This also means that in a client + .search()]]> + operation, the + .returnBundle(Bundle.class)]]> + needs to be the last statement before + .execute()]]> + + + Server now respects the parameter _format=application/xml+fhir"]]> + which is technically invalid since the + should be escaped, but is likely to be used. Also, + a parameter of _format=html]]> can now be used, which + forces SyntaxHighlightingInterceptor to use HTML even + if the headers wouldn't otherwise trigger it. + Thanks to Jim Steel for reporting! + + + Improve performance when parsing large bundles by fixing a loop over all of the + entries inthe bundle to stitch together cross-references, which was happening once + per entry instead of once overall. Thanks to Erick on the HAPI FHIR Google Group for + noticing that this was an issue! + + + JSON parser no longer allows the resource ID to be specified in an element called "_id" + (the correct one is "id"). Previously _id was allowed because some early FHIR examples + used that form, but this was never actually valid so it is now being removed. + + + JPA server now allows "forced IDs" (ids containing non-numeric, client assigned IDs) + to use the same logical ID part on different resource types. E.g. A server may now have + both Patient/foo and Obervation/foo on the same server.
    ]]> + Note that existing databases will need to modify index "IDX_FORCEDID" as + it is no longer unique, and perform a reindexing pass. +
    + + When serializing/encoding custom types which replace exsting choice fields by + fixing the choice to a single type, the parser would forget that the + field was a choice and would use the wrong name (e.g. "abatement" instead of + "abatementDateType"). Thanks to Yaroslav Kovbas for reporting and + providing a unit test! + + + JPA server transactions sometimes created an incorrect resource reference + if a resource being saved contained references that had a display value but + not an actual reference. Thanks to David Hay for reporting! + + + When performing a REST Client create or update with + Prefer: return=representation]]> set, + if the server does not honour the Prefer header, the client + will automatically fetch the resource before returning. Thanks + to Ewout Kramer for the idea! + + + DSTU3 structures now have + setFoo(List)]]> + and + setGetFooFirstRep()]]> + methods, bringing them back to parity with the HAPI + DSTU2 structures. Thanks to Rahul Somasunderam and + Claude Nanjo for the suggestions! + + + JPA server has now been refactored to use the + new FluentPath search parameter definitions + for DSTU3 resources. + + + RequestValidatingInterceptor and ResponseValidatingInterceptor + both have new method setIgnoreValidatorExceptions]]> + which causes validator exceptions to be ignored, rather than causing + processing to be aborted. + + + LoggingInterceptor on server has a new parameter + ${requestBodyFhir}]]> which logs the entire request body. + + + JAX-RS server module now supports DSTU3 resources (previously it only supported DSTU2). Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Generated conformance statements for DSTU3 servers did not properly reference their + OperationDefinitions. Thanks + to Phillip Warner for implementing this, and providing a pull request! + + + Properly handle null arrays when parsing JSON resources. Thanks to Subhro for + fixing this and providing a pull request! + + + STU3 validator failed to validate codes where the + code was a child code within the code system that contained it + (i.e. not a top level code). Thanks to Jon + Zammit for reporting! + + + Restore the setType method in the DSTU1 Bundle + class, as it was accidentally commented out. Thanks + to GitHub user @Virdulys for the pull request! + + + JPA server now supports composite search parameters + where the type of the composite parameter is + a quantity (e.g. Observation:component-code-component-value-quantity) + + + Remove the Remittance resource from DSTU2 + structures, as it is not a real resource and + was causing issues with interoperability + with the .NET client. + + + CLI tool cache feature (-c) for upload-example task sometimes failed + to write cache file and exited with an exception. + + + Fix error message in web testing UI when loading pages in a search + result for STU3 endpoints. + + + When encoding JSON resource, the parser will now always + ensure that XHTML narrative content has an + XHTML namespace declaration on the first + DIV tag. This was preventing validation for + some resources using the official validator + rules. + + + Server failed to invoke operations when the name + was escaped (%24execute instead of $execute). + Thanks to Michael Lawley for reporting! + + + JPA server transactions containing a bundle that has multiple entries + trying to delete the same resource caused a 500 internal error + + + JPA module failed to index search parameters that mapped to a Timing datatype, + e.g. CarePlan:activitydate + + + Add a new option to the CLI run-server command called --lowmem]]>. + This option disables some features (e.g. fulltext search) in order to allow the + server to start in memory-constrained environments (e.g Raspberry Pi) + + + When updating a resource via an update operation on the server, if the ID of the + resource is not present in the resource body but is present on the URL, this will + now be treated as a warning instead of as a failure in order to be a bit more + tolerant of errors. If the ID is present in the body but does not agree with the + ID in the URL this remains an error. + + + Server / JPA server date range search params (e.g. Encounter:date) now treat + a single date with no comparator (or the eq comparator) as requiring that the + value be completely contained by the range specified. Thanks to Chris Moesel + for the suggestion. + + + In server, if a parameter was annotated with the annotation, the + count would not appear in the self/prev/next links and would not actually be applied + to the search results by the server. Thanks to Jim Steele for letting us know! + + + Conditional update on server failed to process if the conditional URL did not have any + search parameters that did not start with an underscore. E.g. "Patient?_id=1" failed + even though this is a valid conditional reference. + + + JPA server can now be configured to allow external references (i.e. references that + point to resources on other servers). See + JPA Documentation]]> for information on + how to use this. Thanks to Naminder Soorma for the suggestion! + + + When posting a resource to a server that contains an invalid value in a boolean field + (e.g. Patient with an active value of "1") the server should return an HTTP 400, not + an HTTP 500. Thanks to Jim Steel for reporting! + + + Enable parsers to parse and serialize custom resources that contain custom datatypes. + An example has been added which shows how to do this + here]]> + + + JSON parser was incorrectly encoding resource language attribute in JSON as an + array instead of a string. Thanks to David Hay for reporting! + + + Sébastien Rivière contributed an excellent pull request which adds a + number of enhancements to JAX-RS module: + +
  • Enable the conditional update and delete
  • +
  • Creation of a bundle provider, and support of the @Transaction
  • +
  • Bug fix on the exceptions handling as some exceptions throw outside bean context were not intercept.
  • +
  • Add the possibility to have the stacktrace in the jaxrsException
  • + + ]]> +
    + + FhirTerser.cloneInto method failed to clone correctly if the source + had any extensions. Thanks to GitHub user @Virdulys for submitting and + providing a test case! + + + Update DSTU2 InstanceValidator to latest version from upstream + + + Web Testing UI was not able to correctly post an STU3 transaction + + + DateTime parser incorrectly parsed times where more than 3 digits of + precision were provided on the seconds after the decimal point + + + Improve error messages when the $validate operation is called but no resource + is actually supplied to validate + + + DSTU2+ servers no longer return the Category header, as this has been + removed from the FHIR specification (and tags are now available in the + resource body so the header was duplication/wasted bandwidth) + + + Create and Update operations in server did not + include ETag or Last-Modified headers even though + the spec says they should. Thanks to Jim Steel for + reporting! + + + Update STU3 client and server to use the new sort parameter style (param1,-param2,param). Thanks to GitHub user @euz1e4r for + reporting! + + + QuantityClientParam#withUnit(String) put the unit into the system part of the + parameter value + + + Fluent client searches with date parameters were not correctly using + new prefix style (e.g. gt) instead of old one (e.g. >) + + + Some built-in v3 code systems for STU3 resources were missing + certain codes, which caused false failures when validating + resources. Thanks to GitHub user @Xoude for reporting! + + + Some methods on DSTU2 model structures have JavaDocs that + incorrectly claim that the method will not return null when + in fact it can. Thanks to Rick Riemer for reporting! + + + ResponseHighlightingInterceptor has been modified based on consensus + on Zulip with Grahame that requests that have a parameter of + _format=json]]> or + _format=xml]]> will output raw FHIR content + instead of HTML highlighting the content as they previously did. + HTML content can now be forced via the (previously existing) + _format=html]]> or via the two newly added + values + _format=html/json]]> and + _format=html/xml]]>. Because of this + change, the custom + _raw=true]]> mode has been deprecated and + will be removed at some point. + + + Operation definitions (e.g. for $everything operation) in the generated + server conformance statement should not include the $ prefix in the operation + name or code. Thanks to Dion McMurtrie for reporting! + + + Server generated OperationDefinition resources did not validate + due to some missing elements (kind, status, etc.). + Thanks to + Michael Lawley for reporting! + + + Operations that are defined on multiple resource provider types with + the same name (e.g. "$everything") are now automatically exposed by the server + as separate OperationDefinition resources per resource type. Thanks to + Michael Lawley for reporting! + + + OperationDefinition resources generated automatically by the server for operations + that are defined within resource/plain providers incorrectly stated that + the maximum cardinality was "*" for non-collection types with no explicit + maximum stated, which is not the behaviour that the JavaDoc on the + annotation describes. Thanks to Michael Lawley + for reporting! + + + Server parameters annotated with + @Since]]> + or + @Count]]> + which are of a FHIR type such as IntegerDt or DateTimeType will + now be set to null if the client's URL does not + contain this parameter. Previously they would be populated + with an empty instance of the FHIR type, which was inconsistent with + the way other server parameters worked. + + + Server now supports the _at parameter (including multiple repetitions) + for history operation + + + + AuthorizationInterceptor can now allow or deny requests to extended + operations (e.g. $everything) + + + DecimalType used BigDecimal constructor instead of valueOf method to + create a BigDecimal from a double, resulting in weird floating point + conversions. Thanks to Craig McClendon for reporting! + + + Remove the depdendency on a method from commons-lang3 3.3 which was + causing issues on some Android phones which come with an older version + of this library bundled. Thanks to Paolo Perliti for reporting! + + + Parser is now better able to handle encoding fields which have been + populated with a class that extends the expected class + + + When declaring a child with + order=Child.REPLACE_PARENT]]> + the serialized form still put the element at the + end of the resource instead of in the correct + order + + + Fix STU3 JPA resource providers to allow validate operation + at instance level + +
    + + + Security Fix: XML parser was vulnerable to XXE (XML External Entity) + processing, which could result in local files on disk being disclosed. + See this page]]> + for more information. + Thanks to Jim Steel for reporting! + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.7 -> 5.1.0
  • +
  • Spring (JPA, Web Tester): 4.2.4 -> 4.2.5
  • +
  • SLF4j (All): 1.7.14 -> 1.7.21
  • + + ]]> +
    + + Support comments when parsing and encoding both JSON and XML. Comments are retrieved + and added to the newly created methods + IBase#getFormatCommentsPre() and + IBase#getFormatCommentsPost() + + + Added options to the CLI upload-examples command which allow it to cache + the downloaded content file, or use an arbitrary one. Thanks to Adam Carbone + for the pull request! + + + REST search parameters with a prefix/comparator had not been updated to use + the DSTU2 style prefixes (gt2011-01-10) instead of the DSTU1 style prefixes + (>2011-01-01). The client has been updated so that it uses the new prefixes + if the client has a DSTU2+ context. The server has been updated so that it now + supports both styles. +
    ]]> + As a part of this change, a new enum called + ParamPrefixEnum]]> + has been introduced. This enum replaces the old + QuantityCompararatorEnum]]> + which has a typo in its name and can not represent several new prefixes added since + DSTU1. +
    + + JPA server number and quantity search params now follow the rules for the + use of precision in search terms outlined in the + search page]]> of the + FHIR specification. For example, previously a 1% tolerance was applied for + all searches (10% for approximate search). Now, a tolerance which respects the + precision of the search term is used (but still 10% for approximate search). + + + Fix a failure starting the REST server if a method returns an untyped List, which + among other things prevented resource provider added to the server + as CDI beans in a JBoss enviroment. Thanks to GitHub user fw060 (Fei) for + reporting and figuring out exactly why this wasn't working! + + + JPA server now supports :above and :below qualifiers on URI search params + + + Add optional support (disabled by default for now) to JPA server to support + inline references containing search URLs. These URLs will be resolved when + a resource is being created/updated and replaced with the single matching + resource. This is being used as a part of the May 2016 Connectathon for + a testing scenario. + + + The server no longer adds a + WWW-Authenticate]]> + header to the response if any resource provider code throws an + AuthenticationException]]>. This header is + used for interactive authentication, which isn't generally + appropriate for FHIR. We added code to add this header a long time + ago for testing purposes and it never got removed. Please let us + know if you need the ability to add this header automatically. Thanks + to Lars Kristian Roland for pointing this out. + + + In the client, the create/update operations on a Binary resource + (which use the raw binary's content type as opposed to the FHIR + content type) were not including any request headers (Content-Type, + User-Agent, etc.) Thanks to Peter Van Houte of Agfa Healthcare for + reporting! + + + Handling of Binary resources containing embedded FHIR resources for + create/update/etc operations has been corrected per the FHIR rules + outlined at + Binary Resource]]> + in both the client and server. +
    ]]> + Essentially, if the Binary contains something + that isn't FHIR (e.g. an image with an image content-type) the + client will send the raw data with the image content type to the server. The + server will place the content type and raw data into a Binary resource instance + and pass those to the resource provider. This part was already correct previous + to 1.5. +
    ]]> + On the other hand, if the Binary contains a FHIR content type, the Binary + is now sent by the client to the server as a Binary resource with a FHIR content-type, + and the embedded FHIR content is contained in the appropriate fields. The server + will pass this "outer" Binary resource to the resource provider code. +
    + + The RequestDetails and ActionRequestDetails objects which are passed to + server interceptor methods and may also be used as server provider method + arguments now has a new method + Map<String, String> getUserData() + ]]> + which can be used to pass data and objects between interceptor methods to + to providers. This can be useful, for instance, if an authorization + interceptor wants to pass the logged in user's details to other parts + of the server. + + + IServerInterceptor#incomingRequestPreHandled() is called + for a @Validate method, the resource was not populated in the + ActionRequestDetails argument. Thanks to Ravi Kuchi for reporting! + ]]> + + + [baseUrl]/metadata with an HTTP method + other than GET (e.g. POST, PUT) should result in an HTTP 405. Thanks to + Michael Lawley for reporting! + ]]> + + + Fix a server exception when trying to automatically add the profile tag + to a resource which already has one or more profiles set. Thanks to + Magnus Vinther for reporting! + + + QuantityParam parameters being used in the RESTful server were ignoring + the + :missing]]> + qualifier. Thanks to Alexander Takacs for reporting! + + + Annotation client failed with an exception if the response contained + extensions on fields in the resonse Bundle (e.g. Bundle.entry.search). + Thanks to GitHub user am202 for reporting! + + + Primitive elements with no value but an extension were sometimes not + encoded correctly in XML, and sometimes not parsed correctly in JSON. + Thanks to Bill de Beaubien for reporting! + + + The Web Testing UI has long had an issue where if you click on a button which + navigates to a new page (e.g. search, read, etc) and then click the back button + to return to the original page, the button you clicked remains disabled and can't + be clicked again (on Firefox and Safari). This is now fixed. Unfortunately the fix means that the + buttom will no longer show a "loading" spinner, but there doesn't seem to + be another way of fixing this. Thanks to Mark Scrimshire for reporting! + + + Extensions found while parsing an object that doesn't support extensions are now + reported using the IParserErrorHandler framework in the same way that + other similar errors are handled. This allows the parser to be more lenient + when needed. + + + Improve error message if incorrect type is placed in a list field in the data model. Java + uses generics to prevent this at compile time, but if someone is in an environment without + generics this helps improve the error message at runtime. Thanks to Hugo Soares for + suggesting. + + + Prevent an unneeded warning when parsing a resource containing + a declared extension. Thanks to Matt Blanchette for reporting! + + + Web Tester UI did not invoke VRead even if a version ID was specified. Thanks + to Poseidon for reporting! + + + Per discussion on the FHIR implementer chat, the JPA server no + longer includes _revinclude matches in the Bundle.total count, or the + page size limit. + + + JPA server now persists search results to the database in a new table where they + can be temporaily preserved. This makes the JPA server much more scalable, since it + no longer needs to store large lists of pages in memory between search invocations. +
    ]]> + Old searches are deleted after an hour by default, but this can be changed + via a setting in the DaoConfig. +
    + + JPA servers' resource version history mechanism + has been adjusted so that the history table + keeps a record of all versions including the + current version. This has the very helpful + side effect that history no longer needs to be + paged into memory as a complete set. Previously + history had a hard limit of only being able to + page the most recent 20000 entries. Now it has + no limit. + + + JPA server returned the wrong Bundle.type value (COLLECTION, should be SEARCHSET) + for $everything operation responses. Thanks to Sonali Somase for reporting! + + + REST and JPA server should reject update requests where the resource body does not + contain an ID, or contains an ID which does not match the URL. Previously these + were accepted (the URL ID was trusted) which is incorrect according to the + FHIR specification. Thanks to GitHub user ametke for reporting! +
    ]]> + As a part of this change, server error messages were also improved for + requests where the URL does not contain an ID but needs to (e.g. for + an update) or contains an ID but shouldn't (e.g. for a create) +
    + + When fields of type BoundCodeDt (e.g. Patient.gender) + are serialized and deserialized using Java's native + object serialization, the enum binder was not + serialized too. This meant that values for the + field in the deserialized object could not be + modified. Thanks to Thomas Andersen for reporting! + + + REST Server responded to HTTP OPTIONS requests with + any URI as being a request for the server's + Conformance statement. This is incorrect, as only + a request for OPTIONS [base url]]]> should be treated as such. Thanks to Michael Lawley for reporting! + + + REST annotation style client was not able to handle extended operations + ($foo) where the response from the server was a raw resource instead + of a Parameters resource. Thanks to Andrew Michael Martin for reporting! + + + JPA server applies _lastUpdated filter inline with other searches wherever possible + instead of applying this filter as a second query against the results of the + first query. This should improve performance when searching against large + datasets. + + + Parsers have new method + setDontEncodeElements]]> + which can be used to force the parser to not encode certain elements + in a resource when serializing. For example this can be used to omit + sensitive data or skip the resource metadata. + + + JPA server database design has been adjusted + so that different tables use different sequences + to generate their indexes, resulting in more sequential + resource IDs being assigned by the server + + + Server now correctly serves up Binary resources + using their native content type (instead of as a + FHIR resource) if the request contains an accept + header containing "application/xml" as some browsers + do. + + + DSTU2 resources now have a + getMeta()]]> method which returns a + modifiable view of the resource metadata for convenience. This + matches the equivalent method in the DSTU3 structures. + + + Add a new method to FhirContext called + setDefaultTypeForProfile + ]]> + which can be used to specify that when recources are received which declare + support for specific profiles, a specific custom structures should be used + instead of the default. For example, if you have created a custom Observation + class for a specific profile, you could use this method to cause your custom + type to be used by the parser for resources in a search bundle you receive. +
    + See the documentation page on + Profiles and Extensions + for more information. + ]]> +
    + + Parsing/Encoding a custom resource type which extends a + base type sometimes caused the FhirContext to treat all future + parses of the same resource as using the custom type even when + this was not wanted. +
    ]]> + Custom structures may now be explicitly declared by profile + using the + setDefaultTypeForProfile + ]]> + method. +
    ]]> + This issue was discovered and fixed as a part of the implementation of issue #315. +
    + + Set up the tinder plugin to work as an ant task + as well as a Maven plugin, and to use external + sources. Thanks to Bill Denton for the pull + request! + + + JPA server now allows searching by token + parameter using a system only and no code, + giving a search for any tokens which match + the given token with any code. Previously the + expected behaviour for this search + was not clear in the spec and HAPI had different + behaviour from the other reference servers. + + + Introduce a JAX-RS client provider which can be used instead of the + default Apache HTTP Client provider to provide low level HTTP + services to HAPI's REST client. See + JAX-RS & Alternate HTTP Client Providers]]> + for more information. +
    ]]> + This is useful in cases where you have other non-FHIR REST clients + using a JAX-RS provider and want to take advantage of the + rest of the framework. +
    ]]> + Thanks to Peter Van Houte from Agfa for the amazing work! +
    + + Parser failed with a NPE while encoding resources if the + resource contained a null extension. Thanks to + steve1medix for reporting! + + + In generated model classes (DSTU1/2) don't + use BoundCodeDt and BoundCodeableConceptDt for + coded fields which use example bindings. Thanks + to GitHub user Ricq for reporting! + + + @Operation will now infer the maximum number of repetitions + of their parameters by the type of the parameter. Previously if + a default max() value was not specified in the + @OperationParam annotation on a parameter, the maximum + was assumed to be 1. Now, if a max value is not explicitly specified + and the type of the parameter is a basic type (e.g. StringDt) the + max will be 1. If the parameter is a collection type (e.g. List<StringDt>) + the max will be * + ]]> + + + @Operation + may now use search parameter types, such as + TokenParam and + TokenAndListParam as values. Thanks to + Christian Ohr for reporting! + ]]> + + + Add databases indexes to JPA module search index tables + for the RES_ID column on each. This should help + performance when searching over large datasets. + Thanks to Emmanuel Duviviers for the suggestion! + + + DateTimeType should fail to parse 1974-12-25+10:00 as this is not + a valid time in FHIR. Thanks to Grahame Grieve for reporting! + + + When parsing a Bundle resource, if the Bundle.entry.request.url contains a UUID + but the resource body has no ID, the Resource.id will be populated with the ID from the + Bundle.entry.request.url. This is helpful when round tripping Bundles containing + UUIDs. + + + When parsing a DSTU3 bundle, references between resources did not have + the actual resource instance populated into the reference if the + IDs matched as they did in DSTU1/2. + + + Contained resource references on DSTU3 + resources were not serialized correctly when + using the Json Parser. Thanks to GitHub user + @fw060 for reporting and supplying a patch + which corrects the issue! + + + DSTU3 model classes equalsShallow and equalsDeep both did not work + correctly if a field was null in one object, but contained an empty + object in the other (e.g. a StringType with no actual value in it). These + two should be considered equal, since they would produce the exact same + wire format.
    ]]> + Thanks to GitHub user @ipropper for reporting and providing + a test case! +
    + + JPA server now supports searching for _tag:not=[tag]]]> + which enables finding resources that to not have a given tag/profile/security tag. + Thanks to Lars Kristian Roland for the suggestion! + + + Extensions containing resource references did not get encoded correctly + some of the time. Thanks to Poseidon for reporting! + + + Parsers (both XML and JSON) encoded the first few elements of DSTU3 structures in the wrong order: + Extensions were placed before any other content, which is incorrect (several + elements come first: meta, text, etc.) + + + In server implementations, the Bundle.entry.fullUrl was not getting correctly + populated on Hl7OrgDstu2 servers. Thanks to Christian Ohr for reporting! + + + Ensure that element IDs within resources (i.e. IDs on elements other than the + resource itself) get serialized and parsed correctly. Previously, these didn't get + serialized in a bunch of circumstances. Thanks to Vadim Peretokin for reporting + and providing test cases! + + + Improve CLI error message if the tool can't bind to the requested port. Thanks + to Claude Nanjo for the suggestion! + + + Server param of _summary=text]]> did not + include mandatory elements in return as well as + the text element, even though the FHIR specification + required it. + + + Remove invalid resource type "Documentation" from DSTU2 + structures. + + + JPA server did not respect target types for search parameters. E.g. Appointment:patient has + a path of "Appointment.participant.actor" and a target type of "Patient". The search path + was being correctly handled, but the target type was being ignored. + + + RestfulServer now manually parses URL parameters instead of relying on the container's + parsed parameters. This is useful because many Java servlet containers (e.g. Tomcat, Glassfish) + default to ISO-8859-1 encoding for URLs insetad of the UTF-8 encoding specified by + FHIR. + + + ResponseHighlightingInterceptor now doesn't highlight if the request + has an Origin header, since this probably denotes an AJAX request. + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Hibernate (JPA, Web Tester): 5.0.3 -> 5.0.7
  • +
  • Springframework (JPA, Web Tester): 4.2.2 -> 4.2.4
  • +
  • Phloc-Commons (Schematron Validator): 4.3.6 -> 4.4.4
  • +
  • Apache httpclient (Client): 4.4 -> 4.5.1
  • +
  • Apache httpcore (Client): 4.4 -> 4.4.4
  • +
  • SLF4j (All): 1.7.13 -> 1.7.14
  • + + ]]> +
    + + Remove a dependency on a Java 1.7 class + (ReflectiveOperationException) in several spots in the + codebase. This dependency was accidentally introduced in + 1.3, and animal-sniffer-plugin failed to detect it (sigh). + + + Add two new server interceptors: + RequestValidatingInterceptor + and + ResponseValidatingInterceptor + ]]> + which can be used to validate incoming requests or outgoing responses using the standard FHIR validation + tools. See the + Server Validation Page + ]]> + for examples of how to use these interceptors. These intereptors have both + been enabled on the + public test page. + ]]> + + + Make IBoundCodeableConcept and IValueSetEnumBinder serializable, + fixing an issue when trying to serialize model classes containing + bound codes. Thanks to Nick Peterson for the Pull Request! + + + Introduce a JAX-RS version of the REST server, which can be used + to deploy the same resource provider implementations which work + on the existing REST server into a JAX-RS (e.g. Jersey) environment. + Thanks to Peter Van Houte from Agfa for the amazing work! + + + CLI now supports writing to file:// URL for 'upload-examples' command + + + GZipped content is now supported for client-to-server uploads (create, update, transaction, etc.). + The server will not automatically detect compressed incoming content and decompress it (this can be + disabled using a RestfulServer configuration setting). A new client interceptor has been added + which compresses outgoing content from the client. + + + JPA server transaction attempted to validate resources twice each, + with one of these times being before anything had been committed to the + database. This meant that if a transaction contained both a Questionnaire + and a QuestionnaireResponse, it would fail because the QuestionnaireResponse + validator wouldn't be able to find the questionnaire. This is now corrected. + + + Add a new method to the generic/fluent client for searching: + .count(int)
    ]]> + This replaces the existing ".limitTo(int)" method which has + now been deprocated because it was badly named and undocumented. +
    + + Profile validator has been configured to allow extensions even if they + aren't explicitly declared in the profile. + + + Add a constraint that the Maven build will only run in JDK 8+. HAPI + remains committed to supporting JDK 6+ in the compiled library, but these + days it can only be built using JDK 8. Thanks to joelsch for the PR! + + + When serializing a value[x] field, if the value type was a profiled type (e.g. markdown is a + profile of string) HAPI 1.3 would use the base type in the element name, e.g. + valueString instead of valueMarkdown. After discussion with Grahame, this appears to + be incorrect behaviour so it has been fixed. + + + Support target parameter type in _include / _revinclude values, e.g. + _include=Patient:careProvider:Organization. Thanks to Joe Portner + for reporting! + + + Use ResponseHighlighterInterceptor in the hapi-fhir-jpaserver-example + project to provide nice syntax highlighting. Thanks to Rob Hausam for + noting that this wasn't there. + + + Introduce custom @CoverageIgnore annotation to hapi-fhir-base in order to + remove dependency on cobertura during build and in runtime. + + + Server-generated conformance statements incorrectly used /Profile/ instead + of /StructureDefinition/ in URL links to structures. + + + JsonParser has been changed so that when serializing numbers it will use + plain format (0.001) instead of scientific format (1e-3). The latter is + valid JSON, and the parser will still correctly parse either format (all + clients should be prepared to) but this change makes serialized + resources appear more consistent between XML and JSON. As a result of this + change, trailing zeros will now be preserved when serializing as well. + + + Add DSTU3 example to hapi-fhir-jpaserver-example. Thanks to Karl + Davis for the Pull Request! + + + RestfulServer#setUseBrowserFriendlyContentTypes has been deprecated and its + functionality removed. The intention of this feature was that if it + detected a request coming in from a browser, it would serve up JSON/XML + using content types that caused the browsers to pretty print. But + each browser has different rules for when to pretty print, and + after we wrote that feature both Chrome and FF changed their rules to break it anyhow. + ResponseHighlightingInterceptor provides a better implementation of + this functionality and should be used instead. + + + Narrative generator framework has removed the + ability to generate resource titles. This + functionality was only useful for DSTU1 + implementations and wasn't compatible + with coming changes to that API. + + + Remove dependency on Servlet-API 3.0+ by using methods available in 2.5 where possible. + Note that we continue to use Servlet-API 3.0+ features in some parts of the JPA API, so + running in an old serlvet container should be tested well before use. Thanks to Bill Denton + for reporting! + + + Add new methods to RestfulClientFactory allowing you to configure the size of the + client pool used by Apache HttpClient. Thanks to Matt Blanchette for the pull + request! + + + Add support for new modifier types on Token search params in Server and + annotation client. + + + Server conformance statement should include search parameter chains if the + chains are explicitly defined via @Search(whitelist={....}). Thanks to lcamilo15 + for reporting! + + + Remove afterPropertiesSet() call in Java config for JPA + server's EntityManagerFactory. This doesn't need to be called + manually, the the manual call led to a warning about + the EntityManager being created twice. + + + Allow server to correctly figure out it's own address even if the container provides + a Servlet Context Path which does not include the root. Thanks to Petro Mykhaylyshyn + for the pull request! + +
    + + + Bump the version of a few dependencies to the + latest versions (dependent HAPI modules listed in brackets): + +
  • Commons-lang3 (Core): 3.3.2 -> 3.4
  • +
  • Logback (Core): 1.1.2 -> 1.1.3
  • +
  • SLF4j (Core): 1.7.102 -> 1.7.12
  • +
  • Springframework (JPA, Web Tester): 4.1.5 -> 4.2.2
  • +
  • Hibernate (JPA, Web Tester): 4.2.17 -> 5."
  • +
  • Hibernate Validator (JPA, Web Tester): 5.2.1 -> 5.2.2
  • +
  • Derby (JPA, CLI, Public Server): 10.11.1.1 -> 10.12.1.1
  • +
  • Jetty (JPA, CLI, Public Server): 9.2.6.v20141205 -> 9.3.4.v20151007
  • + + ]]> +
    + + JPA and Tester Overlay now use Spring Java config files instead + of the older XML config files. All example projects have been updated. + + + JPA server removes duplicate resource index entries before storing them + (e.g. if a patient has the same name twice, only one index entry is created + for that name) + + + JPA server did not correctly index search parameters of type "reference" where the + path had multiple entries (i.e. "Resource.path1 | Resource.path2") + + + JPA server _history operations (server, type, instance) not correctly set the + Bundle.entry.request.method to POST or PUT for create and updates of the resource. + + + Support AND/OR on _id search parameter in JPA + + + Constructor for DateRanfeParam which dates in two DateParam instances was ignoring + comparators on the DateParam. + + + In JSON parsing, finding an object where an array was expected led to an unhelpful + error message. Thanks to Avinash Shanbhag for reporting! + + + JPA server gave an unhelpful error message if $meta-add or $meta-delete were called + with no meta elements in the input Parameters + + + Narrative generator did not include OperationOutcome.issue.diagnostics in the + generated narrative. + + + Clients (generic and annotation) did not populate the Accept header on outgoing + requests. This is now populated to indicate that the client supports both XML and + JSON unless the user has explicitly requested one or the other (in which case the + appropriate type only will be send in the accept header). Thanks to + Avinash Shanbhag for reporting! + + + QuestionnaireResponse validator now allows responses to questions of + type OPENCHOICE to be of type 'string' + + + JPA server should reject resources with a reference that points to an incorrectly typed + resource (e.g. points to Patient/123 but resource 123 is actually an Observation) or points + to a resource that is not valid in the location it is found in (e.g. points to Patient/123 but + the field supposed to reference an Organization). Thanks to Bill de Beaubien for reporting! + + + In server, if a client request is received and it has an Accept header indicating + that it supports both XML and JSON with equal weight, the server's default is used instead of the first entry in the list. + + + JPA server now supports searching with sort by token, quantity, + number, Uri, and _lastUpdated (previously only string, date, and _id + were supported) + + + Fix issue in JPA where a search with a _lastUpdated filter which matches no results + would crash if the search also had a _sort + + + Fix several cases where invalid requests would cause an HTTP 500 instead of + a more appropriate 400/404 in the JPA server (vread on invalid version, + delete with no ID, etc.) + + + Fix narrative generation for DSTU2 Medication resource + + + Profile validator now works for valuesets which use + v2 tables + + + JPA server Patient/[id]/$everything operation now supports + _lastUpdated filtering and _sort'ing of results. + + + Fix parser issue where profiled choice element datatypes (e.g. value[x] where one allowable + type is Duration, which is a profile of Quantity) get incorrectly encoded using the + profiled datatype name instead of the base datatype name as required by the FHIR + spec. Thanks to Nehashri Puttu Lokesh for reporting! + + + Some generated Enum types in DSTU2 HAPI structures + did not have latest valueset definitions applied. Thanks + to Bill de Beaubien for reporting! + + + JPA server can now successfully search for tokens pointing at code values + (values with no explicit system but an implied one, such as Patient.gender) + even if the system is supplied in the query. + + + Correct issues with Android library. Thanks to + Thomas Andersen for the submission! + + + JPA server incorrectly rejected match URLs + if they did not contain a question mark. Thanks + to Bill de Beaubien for reporting! + + + Remove invalid entries in OSGi Manifest. Thanks + to Alexander Kley for the fix! + + + JPA server now supports $everything on Patient and Encounter types (patient and encounter instance was already supported) + + + Generic client operation invocations now + have an additional inline method for generating the input + Parameters using chained method calls instead + of by passing a Parameters resource in + + + Parsing an XML resource where the XHTML + namespace was declared before the beginning + of the narrative section caused an invalid + re-encoding when encoding to JSON. + + + Conditional deletes in JPA did not correctly + process if the condition had a chain or a + qualifier, e.g. "Patient?organization.name" or + "Patient.identifier:missing" + + + Generic/fluent client search can now be + performed using a complete URL supplied + by user code. Thanks to Simone Heckmann + pointing out that this was needed! + + + Refactor JPA $everything operations so that + they perform better + + + Server operation methods can now declare the + ID optional, via + @IdParam(optional=true) + meaning that the same operation can also be invoked + at the type level. + + + Make JPA search queries with _lastUpdated parameter a bit more efficient + + + Clean up Android project to make it more lightweight and remove a + number of unneeded dependencies. Thanks to Thomas Andersen + for the pull request! + + + Fix a crash when encoding a Binary resource in JSON encoding + if the resource has no content-type + + + JPA server now supports read/history/search in transaction entries + by calling the actual implementing method in the server (previously + the call was simulated, which meant that many features did not work) + + + ResourceReferenceDt#loadResource(IRestfulClient) did not + use the client's read functionality, so it did not + handle JSON responses or use interceptors. Thanks to + JT for reporting! + + + JPA server maximumn length for a URI search parameter has been reduced from + 256 to 255 in order to accomodate MySQL's indexing requirements + + + Server failed to respond correctly to compartment search operations + if the same provider also contained a read operation. Thanks to GitHub user + @am202 for reporting! + + + Fix issue in testpage-overlay's new Java configuration where only the first + configured server actually gets used. + + + Introduce + IJpaServerInterceptor]]> + interceptors for JPA server which can be used for more fine grained operations. + + + Parser (XML and JSON) shouldn't encode an ID tag in resources + which are part of a bundle when the resource has a UUID/OID + ID. + + + Add ability for a server REST resource provider @Search method + to declare that it should allow even parameters it doesn't + understand. + + + Correctly set the Bundle.type value on all pages of a search result in + the server, and correcltly set the same value in JPA server $everything + results. + + + JPA $everything operations now support new parameters _content + and _text, which work the same way as the same parameters on a + search. This is experimental, since it is not a part of the core + FHIR specification. + + + Process "Accept: text/xml" and "Accept: text/json" headers was + wanting the equivalent FHIR encoding styles. These are not + correct, but the intention is clear so we will honour them + just to be helpful. + + + Generated Enum types for some ValueSets did not include all + codes (specifically, ValueSets which defined concepts containing + child concepts did not result in Enum values for the child concepts) + + + In the JPA server, order of transaction processing should be + DELETE, POST, PUT, GET, and the order should not matter + within entries with the same verb. Thanks to Bill de Beaubien + for reporting! + + + Add the ability to wire JPA conformance providers + using Spring (basically, add default constructors + and setters to the conformance providers). Thanks + to C. Mike Bylund for the pull request! + +
    + + + JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire + if one is declared. + + + SyntaxHighlightingInterceptor now also highlights OperationOutcome responses for errors/exceptions. + + + Model classes do not use BoundCodeableConcept for example bindings that do not + actually point to any codes (e.g. Observation.interpretation). Thanks + to GitHub user @steve1medix for reporting! + + + Server now exports operations as separate resources instead of as contained resources + within Conformance + + + Add new operation $get-resource-counts which will replace the resource + count extensions exported in the Conformance statement by the JPA + server. + + + JPA server sorting often returned unexpected orders when multiple + indexes of the same type were found on the same resource (e.g. multiple string indexed fields). Thanks to Travis Cummings for reporting! + + + Add another method to IServerInterceptor which converts an exception generated on the server + into a BaseServerResponseException. This is useful so that servers using ResponseHighlighterInterceptor + will highlight exceptions even if they aren't created with an OperationOutcome. + + + XmlParser and JsonParser in DSTU2 mode should not encode empty + tags in resource. Thanks to Bill De Beaubien for reporting! + + + OperationDefinitions generated by server did not properly document + their return parameters or the type of their input parameters. + + + Operations in server generated conformance statement should only + appear once per name, since the name needs to be unique. + + + Resources and datatypes are now serializable. This is an + experimental feature which hasn't yet been extensively tested. Please test and give us your feedback! + + + Switch REST server to using HttpServletRequest#getContextPath() to get + the servlet's context path. This means that the server should behave more + predictably, and should work in servlet 2.4 environments. Thanks to + Ken Zeisset for the suggestion! + + + Vagrant environment now has an apt recipt to ensure that + package lists are up to date. Thanks to GitHub user + Brian S. Corbin (@corbinbs) for thr contribution! + + + JPA server and generic client now both support the _tag search parameter + + + Add support for BATCH mode to JPA server transaction operation + + + Server was not correctly unescaping URL parameter values with + a trailing comma or an escaped backslash. Thanks to GitHub user + @SherryH for all of her help in diagnosing this issue! + + + Avoid crash when parsing if an invalid child element is found in + a resource reference. + + + Create new android specialty libraries for DSTU1 and DSTU2 + + + Throwing a server exception (e.g. AuthenticationException) in a server interceptor's + incomingRequestPreProcessed method resulted in the server returning an HTTP 500 instead + of the appropriate error code for the exception being thrown. Thanks to Nagesh Bashyam + for reporting! + + + Fix issue in JSON parser where invalid contained resources (missing + a resourceType element) fail to parse with a confusing NullPointerException. + Thanks to GitHub user @hugosoares for reporting! + + + JPA server now implements the $validate-code operation + + + HAPI-FHIR now has support for _summary and _elements parameters, in server, client, + and JPA server. + + + _revinclude results from JPA server should have a Bundle.entry.search.mode of + "include" and not "match". Thanks to Josh Mandel for reporting! + + + Resource references using resource instance objects instead of resource IDs + will correctly qualify the IDs with the resource type if they aren't already qualified + + + Testpage Overlay project now properly allows a custom client + factory to be used (e.g. for custom authentication, etc.) Thanks + to Chin Huang (@pukkaone) for the pull request! + + + JPA server should reject IDs containing invalid characters (e.g. "abc:123") + but should allow client assigned IDs that contain text but do not start with + text. Thanks to Josh Mandel for reporting! + + + :text modifier on server and JPA server did not work correctly. Thanks to + Josh Mandel for reporting! + + + Fix issue in client where parameter values containing a comma were + sometimes double escaped. + + + _include parameters now support the new _include:recurse=FOO]]> + syntax that has been introduced in DSTU2 in the Client, Server, and JPA Server modules. + Non-recursive behaviour is now the default (previously it was recursive) and :recurse + needs to be explicitly stated in order to support recursion. + + + New operations added to JPA server to force re-indexing of all + resources (really only useful after indexes change or bugs are + fixed) + + + JPA server did not correctly index search parameters + of type "URI". Thanks to David Hay for reporting! Note that if you are using the JPA server, this change means that + there are two new tables added to the database schema. Updating existing resources in the database may fail unless you + set default values for the resource + table by issuing a SQL command similar to the following (false may be 0 or something else, depending on the database platform in use) + update hfj_resource set sp_coords_present = false;
    + update hfj_resource set sp_uri_present = false;
    ]]> +
    + + FIx issue in JPA server where profile declarations, tags, and + security labels were not always properly removed by an update that + was trying to remove them. Also don't store duplicates. + + + Instance $meta operations on JPA server did not previously return the + resource version and lastUpdated time + + + Server responses populate Bundle.entry.fullUrl if possible. Thanks + to Bill de Beaubien for reporting! + + + XML parser failed to initialize in environments where a very old Woodstox + library is in use (earlier than 4.0). Thanks to Bill de Beaubien for + reporting! + + + Invalid/unexpected attributes found when parsing composite elements + should be logged or reported to the parser error handler + + + JPA server can now store Conformance resources, per a request + from David Hay + + + ResponseHighlightingInterceptor now skips handling responses if it + finds a URL parameter of _raw=true]]> (in other + words, if this parameter is found, the response won't be returned as + HTML even if the request is detected as coming from a browser. + + + RestfulServer now supports dynamically adding and removing resource providers + at runtime. Thanks to Bill Denton for adding this. + + + JPA server now correctly suppresses contents of deleted resources + in history + + + JPA server returned deleted resources in search results when using the _tag, _id, _profile, or _security search parameters + + + Fix issue with build on Windows. Thanks to Bryce van Dyk for the pull request! + + + JPA server now supports $validate operation completely, including delete mode + and profile validation using the RI InstanceValidator + +
    + + + Add support for reference implementation structures. + + + Parsers did not encode the resource meta element if the resource + had tags but no other meta elements. Thanks to Bill de Beaubien and + Claude Nanjo for finding this. + + + Correct performance issue with :missing=true search requests where the parameter is a resource link. Thanks to wanghaisheng for all his help in testing this. + + + The self link in the Bundle returned by searches on the server does not respect the + server's address strategy (which resulted in an internal IP being shown on fhirtest.uhn.ca) + + + Introduce ResponseHighlighterInterceptor, which provides syntax highlighting on RESTful server responses + if the server detects that the request is coming from a browser. This interceptor has been added + to fhirtest.uhn.ca responses. + + + Performing a create operation in a client used an incorrect URL if the + resource had an ID set. ID should be ignored for creates. Thanks to + Peter Girard for reporting! + + + Add better addXXX() methods to structures, which take the datatype being added as a parameter. Thanks to Claude Nanjo for the + suggestion! + + + Add a new parser validation mechanism (see the + validation page]]> for info) which can be + used to validate resources as they are being parsed, and optionally fail if invalid/unexpected + elements are found in resource bodies during parsing. + + + IParser#parseResource(Class, String) method, which is used to parse a resource into the given + structure will now throw a DataFormatException if the structure is for the wrong type of + resource for the one actually found in the input String (or Reader). For example, if a Patient + resource is being parsed into Organization.class this will now cause an error. Previously, + the XML parser would ignore the type and the JSON parser would fail. This also caused + operations to not parse correctly if they returned a resource type other than + parameters with JSON encoding (e.g. the $everything operation on UHN's test server). + Thanks to Avinash Shanbhag for reporting! + + + Web tester UI now supports _revinclude + + + Support link elements in Bundle.entry when parsing in DSTU2 mode + using the old (non-resource) Bundle class. Thanks to GitHub user + @joedai for reporting! + + + LoggingInterceptor for server now supports logging DSTU2 extended operations by name + + + Woodstox XML parser has a default setting to limit the maximum + length of an attribute to 512kb. This caused issues handling + large attachments, so this setting has been increased to 100Mb. + Thanks to Nikos Kyriakoulakos for reporting! + + + Some HTML entities were not correctly converted during parsing. Thanks to + Nick Kitto for reporting! + + + In the JPA Server: + Transactions creating resources with temporary/placeholder resource IDs + and other resources with references to those placeholder IDs previously + did not work if the reference did not contain the resource type + (e.g. Patient/urn:oid:0.1.2.3 instead of urn:oid:0.1.2.3). The + latter is actually the correct way of specifying a reference to a + placeholder, but the former was the only way that worked. Both forms + now work, in order to be lenient. Thanks to Bill De Beaubien for + reporting! + + + When parsing Bundles, if Bundle.entry.base is set to "cid:" (for DSTU1) + or "urn:uuid:" / "urn:oid:" (for DSTU2) this is now correctly passed as + the base in resource.getId(). Conversely, when + encoding bundles, if a resource ID has a base defined, + and Bundle.entry.base is empty, it will now be + automatically set by the parser. + + + Add fluent client method for validate operation, and support the + new DSTU2 style extended operation for $validate if the client is + in DSTU2 mode. Thanks to Eric from the FHIR Skype Implementers chat for + reporting. + + + Server now supports complete Accept header content negotiation, including + q values specifying order of preference. Previously the q value was ignored. + + + Server in DSTU2 mode now indicates that whether it has support for Transaction operation or not. Thanks to Kevin Paschke for pointing out that this wasn't working! + + + Questionnaire.title now gets correctly indexed in JPA server (it has no path, so it is a special case) + + + JPA server now supports ifNoneMatch in GET within a transaction request. + + + DateRangeParam now supports null values in the constructor for lower or upper bounds (but + still not both) + + + Generic/fluent client and JPA server now both support _lastUpdated search parameter + which was added in DSTU2 + + + JPA server now supports sorting on reference parameters. Thanks to + Vishal Kachroo for reporting that this wasn't working! + + + Prevent Last-Updated header in responses coming back to the client from + overwriting the 'lastUpdated' value in the meta element in DSTU2 + resources. This is important because 'lastUpdated' can have more + precision than the equivalent header, but the client previously + gave the header priority. + + + JPA server supports _count parameter in transaction containing search URL (nested search) + + + DSTU2 servers now indicate support for conditional create/update/delete in their + conformance statement. + + + Support for the Prefer header has been added to the server, client, and + JPA modules. + + + JPA server failed to search for deep chained parameters across multiple references, + e.g. "Location.partof.partof.organization". Thanks to Ismael Sarmento Jr for + reporting! + + + Prevent crash when encoding resources with contained resources + if the contained resources contained a circular reference to each other + + + Add $meta, $meta-add, and $meta-delete operations to generic client + + + + + Bump the version of a few dependencies to the + latest versions: + +
  • Phloc-commons (for schematron validation) 4.3.5 -> 4.3.6
  • +
  • Apache HttpClient 4.3.6 -> 4.4
  • +
  • Woodstox 4.4.0 -> 4.4.1
  • +
  • SLF4j 1.7.9 -> 1.7.10
  • +
  • Spring (used in hapi-fhir-jpaserver-base module) 4.1.3.RELEASE -> 4.1.5.RELEASE
  • + + ]]> +
    + + Add support for "profile" and "tag" elements in the resource Meta block + when parsing DSTU2 structures. + + + When a user manually creates the list of contained resources in a resource, + the encoder fails to encode any resources that don't have a '#' at the + start of their ID. This is unintuitive, so we now assume that '123' means '#123'. + Thanks to myungchoi for reporting and providing a test case! + + + Add methods for setting the default encoding (XML/JSON) and + oretty print behaviour in the Fluent Client. Thanks to Stackoverflow + user ewall for the idea. + + + JPA Server did not mark a resource as "no longer deleted" if it + was updated after being deleted. Thanks to Elliott Lavy and Lloyd + McKenzie for reporting! + + + Fix regression in 0.9 - Server responds with an HTTP 500 and a NullPointerException instead of an HTTP 400 and a useful error message if the client requests an unknown resource type + + + Add support for + _revinclude]]> + parameter in client, server, and JPA. + + + Include constants on resources (such as + Observation.INCLUDE_VALUE_STRING]]>) + have been switched in the DSTU2 structures to use + the new syntax required in DSTU2: [resource name]:[search param NAME] + insead of the DSTU1 style [resource name].[search param PATH] + + + When encoding resources, the parser will now convert any resource + references to versionless references automatically (i.e. it will + omit the version part automatically if one is present in the reference) + since references between resources must be versionless. Additionally, + references in server responses will omit the server base URL part of the + reference if the base matches the base for the server giving + the response. + + + Narrative generator incorrectly sets the Resource.text.status to 'generated' even if the + given resource type does not have a template (and therefore no narrative is actually generated). + Thanks to Bill de Beaubien for reporting! + + + Searching in JPA server with no search parameter returns deleted resources when it should exclude them. + + + Remove Eclipse and IntelliJ artifacts (.project, *.iml, etc) from version control. Thanks + to Doug Martin for the suggestion! + + + REST server methods may now have a parameter of + type NarrativeModeEnum which will be populated with + the value of the _narrative URL parameter + if one was supplied. Annotation client methods + may also include a parameter of this type, and it + will be used to populate this parameter on the request + URL if it is not null. Thanks to Neal Acharya for the + idea! + + + Android JAR now includes servlet-API classes, as the project will not + work without them. Thanks + + + Requested _include values are preserved across paging links when the + server returns multiple pages. Thanks to Bill de Beaubien for + reporting! + + + Add new server address strategy "ApacheProxyAddressStrategy" which uses + headers "x-forwarded-host" and "x-forwarded-proto" to determine the + server's address. This is useful if you are deploying a HAPI FHIR + server behind an Apache proxy (e.g. for load balancing or other reasons). + Thanks to Bill de Beaubien for contributing! + + + Resource references between separate resources found in a single + bundle did not get populated with the actual resource when parsing a + DSTU2 style bundle. Thanks to Nick Peterson for reporting and figuring + out why none of our unit tests were actually catching the problem! + + + JSON encoder did not encode contained resources when encoding + a DSTU2 style bundle. Thanks to Mohammad Jafari and baopingle + for all of their help in tracking this issue down and developing + useful unit tests to demonstrate it. + + + Client now supports invoking transcation using a DSTU2-style + Bundle resource as the input. + + + JPA Server $everything operation could sometimes include a duplicate copy of + the main focus resource if it was referred to in a deep chain. Thanks + to David Hay for reporting! + + + JPA Server $everything operation now allows a _count parameter + + + JPA server failed to index resources containing ContactPointDt elements with + populated values (e.g. Patient.telecom). Thanks to Mohammad Jafari for reporting! + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Terser's IModelVisitor now supplies to the path to the element. This is + an API change, but I don't think there are many users of the IModelVisitor yet. + Please let us know if this is a big hardship and we can find an alternate way + of making this change. + + + Prevent server from returning a Content-Location header for search + response when using the DSTU2 bundle format + + + JPA server (uhnfhirtest.uhn.ca) sometimes included an empty + "text" element in Bundles being returned. + + + Add a framework for the Web Tester UI to allow its internal FHIR client to + be configured (e.g. to add an authorization interceptor so that it adds + credentials to client requests it makes). Thanks to Harsha Kumara for + the suggestion! + + + Fix regression in early 1.0 builds where resource type sometimes does not get + populated in a resource ID when the resource is parsed. Thanks to + Nick Peterson for reporting, and for providing a test case! + + + Allow fluent/generic client users to execute a transaction using a raw string (containing a bundle resource) + as input instead of a Bundle resource class instance. + + + Disable date validation in the web tester UI, so that it is possible to + enter partial dates, or dates without times, or even test out invalid date + options. + + + Make BaseElement#getUndeclaredExtensions() and BaseElement#getUndeclaredExtensions() return + a mutable list so that it is possible to delete extensions from a resource instance. + + + Server conformance statement check in clients (this is the check + where the first time a given FhirContext is used to access a given server + base URL, it will first check the server's Conformance statement to ensure + that it supports the correct version of FHIR) now uses any + registered client interceptors. In addition, IGenericClient now has a method + "forceConformanceCheck()" which manually triggers this check. Thanks to + Doug Martin for reporting and suggesting! + + + Rename the Spring Bean definition for the JPA server EntityManager from + "myEntityManagerFactory" to just "entityManagerFactory" as this is the + default bean name expected in other parts of the Spring framework. + Thanks to Mohammad Jafari for the suggestion! + + + Improve error message when a user tries to perform a create/update with an invalid + or missing Content-Type header. Thanks to wanghaisheng for reporting! (This was + actually a three part bug, so the following two fixes also reference this + bug number) + + + Add support for :missing qualifier in generic/fluent client. + + + Add support for :missing qualifier in JPA server. + + + Add a new configuration method on the parsers, + setStripVersionsFromReferences(boolean)]]> which + configures the parser to preserve versions in resource reference links when + encoding. By default, these are removed. + + + Add an exception for RESTful clients/servers to represent the + HTTP 403 Forbidden status code. Thanks to Joel Costigliola for + the patch! + + + Transaction server operations incorrectly used the "Accept" header instead of the "Content-Type" header to determine the + POST request encoding. Thanks to Rene Spronk for providing a test case! + +
    + + + Support for DSTU2 features introduced: New resource definitions, Bundle resource, + encoding changes (ID in resource bodt, meta tag) + + + Fix an issue encoding extensions on primitive types in JSON. Previously the "_value" object + would be an array even if the field it was extending was not repeatable. This is not correct + according to the specification, nor can HAPI's parser parse this correctly. The encoder + has been corrected, and the parser has been adjusted to be able to handle resources with + extensions encoded in this way. Thanks to Mohammad Jafari for reporting! + + + Library now checks if custom resource types can be instantiated on startup + (e.g. because they don't have a no-argument constructor) in order to + avoid failing later + + + Bump a few dependency JARs to the latest versions in Maven POM: + +
  • SLF4j (in base module) - Bumped to 1.7.9
  • +
  • Apache HTTPClient (in base module) - Bumped to 4.3.6
  • +
  • Hibernate (in JPA module) - Bumped to 4.3.7
  • + + ]]> +
    + + IdDt failed to recognize local identifiers containing fragments that look like + real identifiers as being local identifiers even though they started with '#'. + For example, a local resource reference of "#aa/_history/aa" would be incorrectly + parsed as a non-local reference. + Thanks to Mohammad Jafari for reporting! + + + Last-Modified]]> + header in server was incorrectly using FHIR date format instead + of RFC-1123 format. + + + Server create and update methods failed with an IllegalArgumentException if + the method type was a custom resource definition type (instead of a built-in + HAPI type). Thanks to Neal Acharya for the analysis. + + + JPA server module now supports + _include]]> + value of + *]]>. Thanks to Bill de Beaubien for reporting! + + + IdDt method + + returned String (unlike all of the other "withFoo" methods on that class), + and did not work correctly if the IdDt already had a server base. This + has been corrected. Note that the return type for this method has been + changed, so code may need to be updated. + + + In previous versions of HAPI, the XML parser encoded multiple contained + resources in a single + <contained></contained>]]> + tag, even though the FHIR specification rerquires a separate + <contained></contained>]]> + tag for each resource. This has been corrected. Note that the parser will + correctly parse either form (this has always been the case) so this + change should not cause any breakage in HAPI based trading partners, but + may cause issues if other applications have been coded to depend on the + incorrect behaviour. Thanks to Mochaholic for reporting! + + + Custom/user defined resource definitions which contained more than one + child with no order defined failed to initialize properly. Thanks to + Andy Huang for reporting and figuring out where the + problem was! + + + RESTful Client now queries the server (only once per server base URL) to ensure that + the given server corresponds to the correct version of the FHIR specification, as + defined by the FhirContext. This behaviour can be disabled by setting the + appropriate configuration on the + RestfulClientConfig. Thanks to Grahame Grieve for the suggestion! + + + JPA module now supports deleting resource via transaction + + + DateClientParam#second() incorrectly used DAY precision instead + of SECOND precision. Thanks to Tom Wilson for the pull request! + + + Fix issue where HAPI failed to initialize correctly if Woodstox library was not on the classpath, even + if StAX API was configured to use a different provider. Thanks to + James Butler for reporting and figuring out where the issue was! + + + Calling BaseDateTimeDt#setValue(Date, TemporalPrecisionEnum) did not always actually respect + the given precision when the value was encoded. Thanks to jacksonjesse for + reporting! + + + Encoders (both XML and JSON) will no longer encode contained resources if they are + not referenced anywhere in the resource via a local reference. This is just a convenience + for users who have parsed a resource with contained resources and want to remove some + before re-encoding. Thanks to Alexander Kley for reporting! + + + Add support for DSTU2 style security labels in the parser and encoder. Thanks to + Mohammad Jafari for the contribution! + + + Server requests for Binary resources where the client has explicitly requested XML or JSON responses + (either with a _format]]> URL parameter, or an Accept]]> request header) + will be responded to using the Binary FHIR resource type instead of as Binary blobs. This is + in accordance with the recommended behaviour in the FHIR specification. + + + Add new properties to RestfulServer: "DefaultResponseEncoding", which allows + users to configure a default encoding (XML/JSON) to use if none is specified in the + client request. Currently defaults to XML. Also "DefaultPrettyPrint", which specifies + whether to pretty print responses by default. Both properties can be overridden + on individual requets using the appropriate Accept header or request URL parameters. + + + Add support for quantity search params in FHIR tester UI + + + Add support for FHIR "extended operations" as defined in the FHIR DSTU2 + specification, for the Generic Client, Annotation Client, and + Server. + + + Observation.applies[x] and other similar search fields with multiple allowable + value types were not being correctly indexed in the JPA server. + + + DateClientParam.before() incorrectly placed "<=" instead of + "<" in the request URL. Thanks to Ryan for reporting! + + + Server now only automatically adds _include resources which are provided + as references if the client request actually requested that specific include. + See RestfulServer + + + User defined resource types which contain extensions that use a bound code type + (e.g. an BoundCodeDt with a custom Enum) failed to parse correctly. Thanks + to baopingle for reporting and providing a test case! + + + Sorting is now supported in the Web Testing UI (previously a button existed for sorting, but it didn't do anything) + + + Server will no longer include stack traces in the OperationOutcome returned to the client + when an exception is thrown. A new interceptor called ExceptionHandlingInterceptor has been + created which adds this functionality back if it is needed (e.g. for DEV setups). See the + server interceptor documentation for more information. Thanks to Andy Huang for the suggestion! + +
    + + + API CHANGE:]]> The "FHIR structures" for DSTU1 (the classes which model the + resources and composite datatypes) have been moved out of the core JAR into their + own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast + version is finalized. See the + DSTU2 page]]> + for more information. + + + Deprocated API Removal: The following classes (which were deprocated previously) + have now been removed: +
      +
    • ISecurityManager: If you are using this class, the same functionality + is available through the more general purpose + server interceptor + capabilities. +
    • CodingListParam: This class was made redundant by the + TokenOrListParam + class, which can be used in its place. +
    + ]]> +
    + + API Change: The IResource#getResourceMetadata() method has been changed + from returning + Map<ResourceMetadataKeyEnum<?>, Object> + to returning a new type called + ResourceMetadataMap. This new type implements + Map<ResourceMetadataKeyEnum<?>, Object> + itself, so this change should not break existing code, but may + require a clean build in order to run correctly. + ]]> + + + Profile generation on the server was not working due to IdDt being + incorrectly used. Thanks to Bill de Beaubien for the pull request! + + + Profiles did not generate correctly if a resource definition class had a + defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request! + + + Remove unnecessary IOException from narrative generator API. Thanks to + Petro Mykhailysyn for the pull request! + + + Introduced a new + @ProvidesResources]]> annotation which can be added to + resource provider and servers to allow them to declare additional resource + classes they are able to serve. This is useful if you have a server which can + serve up multiple classes for the same resource type (e.g. a server that sometimes + returns a default Patient, but sometimes uses a custom subclass). + Thanks to Bill de Beaubien for the pull request! + + + Introduced a new + @Destroy]]> annotation which can be added to + a resource provider method. This method will be called by the server when it + is being closed/destroyed (e.g. when the application is being undeployed, the + container is being shut down, etc.) + Thanks to Bill de Beaubien for the pull request! + + + Add a new method to the server interceptor + framework which allows interceptors to be notified of any exceptions and + runtime errors within server methods. Interceptors may optionally also + override the default error handling behaviour of the RestfulServer. + + + Add constants to BaseResource for the "_id" search parameter which all resources + should support. + + + DateRangeParam parameters on the server now return correct + getLowerBoundAsInstant()]]> + and + getUpperBoundAsInstant()]]> + values if a single unqualified value is passed in. For example, if + a query containing + &birthdate=2012-10-01]]> + is received, previously these two methods would both return the same + value, but with this fix + getUpperBoundAsInstant()]]> + now returns the instant at 23:59:59.9999. + + + Resource fields with a type of "*" (or Any) sometimes failed to parse if a + value type of "code" was used. Thanks to Bill de Beaubien for reporting! + + + Remove dependency on JAXB libraries, which were used to parse and encode + dates and times (even in the JSON parser). JAXB is built in to most JDKs + but the version bundled with IBM's JDK is flaky and resulted in a number + of problems when deploying to Websphere. + + + Primitive datatypes now preserve their original string value when parsing resources, + as well as containing the "parsed value". For instance, a DecimalDt field value of + 1.0000]]> will be parsed into the corresponding + decimal value, but will also retain the original value with the corresponding + level of precision. This allows vadliator rules to be applied to + original values as received "over the wire", such as well formatted but + invalid dates, e.g. "2001-15-01". Thanks to Joe Athman for reporting and + helping to come up with a fix! + + + When using Generic Client, if performing a + or operation using a String as the resource body, + the client will auto-detect the FHIR encoding style and send an appropriate + header. + + + JPA module (and public HAPI-FHIR test server) were unable to process resource types + where at least one search parameter has no path specified. These now correctly save + (although the server does not yet process these params, and it should). Thanks to + GitHub user shvoidlee for reporting and help with analysis! + + + Generic/Fluent Client "create" and "update" method requests were not setting a content type header + + + DateDt left precision value as in the constructor + . + + + RESTful server now doesn't overwrite resource IDs if they are absolute. In other words, if + a server's Resource Provider returns a resource with ID "Patient/123" it will be translated to + "[base url]/Patient/123" but if the RP returns ID "http://foo/Patient/123" the ID will be + returned exactly as is. Thanks to Bill de Beaubien for the suggestion! + + + JPA module Transaction operation was not correctly replacing logical IDs + beginning with "cid:" with server assigned IDs, as required by the + specification. + + + did not visit or find children in contained resources when + searching a resource. This caused server implementations to not always return contained + resources when they are included with a resource being returned. + + + Add a method which returns the name of the + resource in question (e.g. "Patient", or "Observation"). This is intended as a + convenience to users. + + + Do not strip version from resource references in resources returned + from server search methods. Thanks to Bill de Beaubien for reporting! + + + Correct an issue with the validator where changes to the underlying + OperationOutcome produced by a validation cycle cause the validation + results to be incorrect. + + + Client interceptors registered to an interface based client instance + were applied to other client instances for the same client interface as well. (Issue + did not affect generic/fluent clients) + + + DateDt, DateTimeDt and types InstantDt types now do not throw an exception + if they are used to parse a value with the wrong level of precision for + the given type but do throw an exception if the wrong level of precision + is passed into their constructors.
    ]]> + This means that HAPI FHIR can now successfully parse resources from external + sources that have the wrong level of precision, but will generate a validation + error if the resource is validated. Thanks to Alexander Kley for the suggestion! +
    + + Encoding a Binary resource without a content type set should not result in a NullPointerException. Thanks + to Alexander Kley for reporting! + + + Server gives a more helpful error message if multiple IResourceProvider implementations + are provided for the same resource type. Thanks to wanghaisheng for the idea! + + + Bring DSTU1 resource definitions up to version 0.0.82-2929]]> + Bring DEV resource definitions up to 0.4.0-3775]]> + Thanks to crinacimpian for reporting! + + + JPA server did not correctly process _include requests if included + resources were present with a non-numeric identifier. Thanks to + Bill de Beaubien for reporting! + + + Client requests which include a resource/bundle body (e.g. create, + update, transaction) were not including a charset in the content type + header, leading to servers incorrectly assuming ISO-8859/1. Thanks to + shvoidlee for reporting! + + + Clean up the way that Profile resources are automatically exported + by the server for custom resource profile classes. See the + @ResourceDef]]> + JavaDoc for information on how this works. + + + Add convenience methods to TokenOrListParam to test whether any of a set of tokens match + the given requested list. + + + Add a protected method to RestfulServer which allows developers to + implement their own method for determining which part of the request + URL is the FHIR request path (useful if you are embedding the RestulServer inside + of another web framework). Thanks to Harsha Kumara for the pull request! + +
    + + + API CHANGE:]]> The TagList class previously implemented ArrayList semantics, + but this has been replaced with LinkedHashMap semantics. This means that the list of + tags will no longer accept duplicate tags, but that tag order will still be + preserved. Thanks to Bill de Beaubien for reporting! + + + Server was incorrectly including contained resources being returned as both contained resources, and as + top-level resources in the returned bundle for search operations. + Thanks to Bill de Beaubien for reporting! This also fixes Issue #20, thanks to + lephty for reporting! + + + Documentation fixes + + + Add a collection of new methods on the generic client which support the + read, + read, + and search + ]]> + operations using an absolute URL. This allows developers to perform these operations using + URLs they obtained from other sources (or external resource references within resources). In + addition, the existing read/vread operations will now access absolute URL references if + they are passed in. Thanks to Doug Martin of the Regenstrief Center for Biomedical Informatics + for contributing this implementation! + + + Server implementation was not correctly figuring out its own FHIR Base URL when deployed + on Amazon Web Service server. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + XML Parser failed to encode fields with both a resource reference child and + a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of + Systems Made Simple for their help in figuring out this issue! + + + HAPI now runs successfully on Servlet 2.5 containers (such as Tomcat 6). Thanks to + Bernard Gitaadji for reporting and diagnosing the issue! + + + Summary (in the bundle entry) is now encoded by the XML and JSON parsers if supplied. Thanks to David Hay of + Orion Health for reporting this! + + + Conformance profiles which are automatically generated by the server were missing a few mandatory elements, + which meant that the profile did not correctly validate. Thanks to Bill de Beaubien of Systems Made Simple + for reporting this! + + + XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters + escaped properly in encoded messages. + + + Resources containing entities which are not valid in basic XML (e.g. &sect;) will have those + entities converted to their equivalent unicode characters when resources are encoded, since FHIR does + not allow extended entities in resource instances. + + + Add a new client interceptor which adds HTTP Authorization Bearer Tokens (for use with OAUTH2 servers) + to client requests. + + + Add phloc-commons dependency explicitly, which resolves an issue building HAPI from source on + some platforms. Thanks to Odysseas Pentakalos for the patch! + + + HAPI now logs a single line indicating the StAX implementation being used upon the + first time an XML parser is created. + + + Update methods on the server did not return a "content-location" header, but + only a "location" header. Both are required according to the FHIR specification. + Thanks to Bill de Beaubien of Systems Made Simple for reporting this! + + + Parser failed to correctly read contained Binary resources. Thanks to Alexander Kley for + the patch! + + + Calling encode multiple times on a resource with contained resources caused the contained + resources to be re-added (and the actual message to grow) with each encode pass. Thanks to + Alexander Kley for the test case! + + + JSON-encoded contained resources with the incorrect "_id" element (which should be "id", but some + incorrect examples exist on the FHIR specification) now parse correctly. In other words, HAPI + previously only accepted the correct "id" element, but now it also accepts the incorrect + "_id" element just to be more lenient. + + + Several unit tests failed on Windows (or any platform with non UTF-8 default encoding). This may + have also caused resource validation to fail occasionally on these platforms as well. + Thanks to Bill de Beaubien for reporting! + + + toString() method on TokenParam was incorrectly showing the system as the value. + Thanks to Bill de Beaubien for reporting! + + + Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks + to David Hay of Orion Health for reporting! + + + Add a + Vagrant]]> + based environment (basically a fully built, self contained development environment) for + trying out the HAPI server modules. Thanks to Preston Lee for the pull request, and for + offering to maintain this! + + + Change validation API so that it uses a return type instead of exceptions to communicate + validation failures. Thanks to Joe Athman for the pull request! + + + Add a client interceptor which adds an HTTP cookie to each client request. Thanks to + Petro Mykhailysyn for the pull request! + + + + + + Add server interceptor framework, and new interceptor for logging incoming + requests. + + + Add server validation framework for validating resources against the FHIR schemas and schematrons + + + Tester UI created double _format and _pretty param entries in searches. Thanks to Gered King of University + Health Network for reporting! + + + Create method was incorrectly returning an HTTP 204 on sucessful completion, but + should be returning an HTTP 200 per the FHIR specification. Thanks to wanghaisheng + for reporting! + + + FHIR Tester UI now correctly sends UTF-8 charset in responses so that message payloads containing + non US-ASCII characters will correctly display in the browser + + + JSON parser was incorrectly encoding extensions on composite elements outside the element itself + (as is done correctly for non-composite elements) instead of inside of them. Thanks to David Hay of + Orion for reporting this! + + + Contained/included resource instances received by a client are now automatically + added to any ResourceReferenceDt instancea in other resources which reference them. + + + Add documentation on how to use eBay CORS Filter to support Cross Origin Resource + Sharing (CORS) to server. CORS support that was built in to the server itself has + been removed, as it did not work correctly (and was reinventing a wheel that others + have done a great job inventing). Thanks to Peter Bernhardt of Relay Health for all the assistance + in testing this! + + + IResource interface did not expose the getLanguage/setLanguage methods from BaseResource, + so the resource language was difficult to access. + + + JSON Parser now gives a more friendly error message if it tries to parse JSON with invalid use + of single quotes + + + Transaction server method is now allowed to return an OperationOutcome in addition to the + incoming resources. The public test server now does this in order to return status information + about the transaction processing. + + + Update method in the server can now flag (via a field on the MethodOutcome object being returned) + that the result was actually a creation, and Create method can indicate that it was actually an + update. This has no effect other than to switch between the HTTP 200 and HTTP 201 status codes on the + response, but this may be useful in some circumstances. + + + Annotation client search methods with a specific resource type (e.g. List<Patient> search()) + won't return any resources that aren't of the correct type that are received in a response + bundle (generally these are referenced resources, so they are populated in the reference fields instead). + Thanks to Tahura Chaudhry of University Health Network for the unit test! + + + Added narrative generator template for OperationOutcome resource + + + Date/time types did not correctly parse values in the format "yyyymmdd" (although the FHIR-defined format + is "yyyy-mm-dd" anyhow, and this is correctly handled). Thanks to Jeffrey Ting of Systems Made Simple + for reporting! + + + Server search method for an unnamed query gets called if the client requests a named query + with the same parameter list. Thanks to Neal Acharya of University Health Network for reporting! + + + Category header (for tags) is correctly read in client for "read" operation + + + Transaction method in server can now have parameter type Bundle instead of + List<IResource> + + + HAPI parsers now use field access to get/set values instead of method accessors and mutators. + This should give a small performance boost. + + + JSON parser encodes resource references incorrectly, using the name "resource" instead + of the name "reference" for the actual reference. Thanks to + Ricky Nguyen for reporting and tracking down the issue! + + + Rename NotImpementedException to NotImplementedException (to correct typo) + + + Server setUseBrowserFriendlyContentType setting also respected for errors (e.g. OperationOutcome with 4xx/5xx status) + + + Fix performance issue in date/time datatypes where pattern matchers were not static + + + Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but + previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting! + + + Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health + for reporting! + + + QuantityParam correctly encodes approximate (~) prefix to values + + + If a server defines a method with parameter "_id", incoming search requests for that method may + get delegated to the wrong method. Thanks to Neal Acharya for reporting! + + + SecurityEvent.Object structural element has been renamed to + SecurityEvent.ObjectElement to avoid conflicting names with the + java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for + reporting! + + + Text/narrative blocks that were created with a non-empty + namespace prefix (e.g. <xhtml:div xmlns:xhtml="...">...</xhtml:div>) + failed to encode correctly (prefix was missing in encoded resource) + + + Resource references previously encoded their children (display and reference) + in the wrong order so references with both would fail schema validation. + + + SecurityEvent resource's enums now use friendly enum names instead of the unfriendly + numeric code values. Thanks to Laurie MacDougall-Sookraj of UHN for the + suggestion! + + + + + HAPI has a number of RESTful method parameter types that have similar but not identical + purposes and confusing names. A cleanup has been undertaken to clean this up. + This means that a number of existing classes + have been deprocated in favour of new naming schemes. +
    ]]> + All annotation-based clients and all server search method parameters are now named + (type)Param, for example: StringParam, TokenParam, etc. +
    ]]> + All generic/fluent client method parameters are now named + (type)ClientParam, for example: StringClientParam, TokenClientParam, etc. +
    ]]> + All renamed classes have been retained and deprocated, so this change should not cause any issues + for existing applications but those applications should be refactored to use the + new parameters when possible. +
    + + Allow server methods to return wildcard generic types (e.g. List<? extends IResource>) + + + Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as + "&identifier=system|codepart1\|codepart2" + + + Add support for OPTIONS verb (which returns the server conformance statement) + + + Add support for CORS headers in server + + + Bump SLF4j dependency to latest version (1.7.7) + + + Add interceptor framework for clients (annotation based and generic), and add interceptors + for configurable logging, capturing requests and responses, and HTTP basic auth. + + + Transaction client invocations with XML encoding were using the wrong content type ("application/xml+fhir" instead + of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one! + + + Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion! + + + If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or + an OperationOutcome resource, include the message in the exception message so that it will be + more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion! + + + Read invocations in the client now process the "Content-Location" header and use it to + populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion! + + + Fix issue where vread invocations on server incorrectly get routed to instance history method if one is + defined. Thanks to Neal Acharya from UHN for surfacing this one! + + + Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary + blobs from being used for nefarious purposes. See + FHIR Tracker Bug 3298]]> + for more information. + + + Support has been added for using an HTTP proxy for outgoing requests. + + + Fix: Primitive extensions declared against custom resource types + are encoded even if they have no value. Thanks to David Hay of Orion for + reporting this! + + + Fix: RESTful server deployed to a location where the URL to access it contained a + space (e.g. a WAR file with a space in the name) failed to work correctly. + Thanks to David Hay of Orion for reporting this! + +
    + + + BREAKING CHANGE:]]>: IdDt has been modified so that it + contains a partial or complete resource identity. Previously it contained + only the simple alphanumeric id of the resource (the part at the end of the "read" URL for + that resource) but it can now contain a complete URL or even a partial URL (e.g. "Patient/123") + and can optionally contain a version (e.g. "Patient/123/_history/456"). New methods have + been added to this datatype which provide just the numeric portion. See the JavaDoc + for more information. + + + API CHANGE:]]>: Most elements in the HAPI FHIR model contain + a getId() and setId() method. This method is confusing because it is only actually used + for IDREF elements (which are rare) but its name makes it easy to confuse with more + important identifiers. For this reason, these methods have been deprocated and replaced with + get/setElementSpecificId() methods. The old methods will be removed at some point. Resource + types are unchanged and retain their get/setId methods. + + + Allow use of QuantityDt as a service parameter to support the "quantity" type. Previously + QuantityDt did not implement IQueryParameterType so it was not valid, and there was no way to + support quantity search parameters on the server (e.g. Observation.value-quantity) + + + Introduce StringParameter type which can be used as a RESTful operation search parameter + type. StringParameter allows ":exact" matches to be specified in clients, and handled in servers. + + + Parsers (XML/JSON) now support deleted entries in bundles + + + Transaction method now supported in servers + + + Support for Binary resources added (in servers, clients, parsers, etc.) + + + Support for Query resources fixed (in parser) + + + Nested contained resources (e.g. encoding a resource with a contained resource that itself contains a resource) + now parse and encode correctly, meaning that all contained resources are placed in the "contained" element + of the root resource, and the parser looks in the root resource for all container levels when stitching + contained resources back together. + + + Server methods with @Include parameter would sometimes fail when no _include was actually + specified in query strings. + + + Client requests for IdentifierDt types (such as Patient.identifier) did not create the correct + query string if the system is null. + + + Add support for paging responses from RESTful servers. + + + Don't fail on narrative blocks in JSON resources with only an XML declaration but no content (these are + produced by the Health Intersections server) + + + Server now automatically compresses responses if the client indicates support + + + Server failed to support optional parameters when type is String and :exact qualifier is used + + + Read method in client correctly populated resource ID in returned object + + + Support added for deleted-entry by/name, by/email, and comment from Tombstones spec + + + + + + + + + +
    diff --git a/src/site/xdoc/doc_extensions.xml b/src/site/xdoc/doc_extensions.xml index 2199778f7d6..48252a08adc 100644 --- a/src/site/xdoc/doc_extensions.xml +++ b/src/site/xdoc/doc_extensions.xml @@ -240,6 +240,36 @@ + + + +

    + The following example shows a resource containing a composite + extension. +

    + + + + + + +

    + This could be used to create a resource such as the + following: +

    + + + + + + + + + + +]]> + +
    diff --git a/src/site/xdoc/doc_rest_server_security.xml b/src/site/xdoc/doc_rest_server_security.xml index a36ad6d3c2f..87e88e8a6ee 100644 --- a/src/site/xdoc/doc_rest_server_security.xml +++ b/src/site/xdoc/doc_rest_server_security.xml @@ -91,8 +91,10 @@

    This interceptor can help with the complicated task of determining whether a user has the appropriate permission to perform a given task on a FHIR server. This is - done by declaring + done by declaring a set of rules that can selectively allow (whitelist) and/or selectively + block (blacklist) requests.

    +

    AuthorizationInterceptor is a new feature in HAPI FHIR, and has not yet been heavily tested. Use with caution, and do lots of testing! We welcome