Fix #196 - Support deep chained parameters in JPA. Also add support for
Prefer header.
This commit is contained in:
parent
70222ecf15
commit
0f76ba81e1
|
@ -760,6 +760,29 @@ public MethodOutcome updatePatientConditional(
|
|||
}
|
||||
//END SNIPPET: updateConditional
|
||||
|
||||
//START SNIPPET: updatePrefer
|
||||
@Update
|
||||
public MethodOutcome updatePatientPrefer(
|
||||
@ResourceParam Patient thePatient,
|
||||
@IdParam IdDt theId) {
|
||||
|
||||
// Save the patient to the database
|
||||
|
||||
// Update the version and last updated time on the resource
|
||||
IdDt updatedId = theId.withVersion("123");
|
||||
thePatient.setId(updatedId);
|
||||
InstantDt lastUpdated = InstantDt.withCurrentTime();
|
||||
ResourceMetadataKeyEnum.UPDATED.put(thePatient, lastUpdated);
|
||||
|
||||
// Add the resource to the outcome, so that it can be returned by the server
|
||||
// if the client requests it
|
||||
MethodOutcome outcome = new MethodOutcome();
|
||||
outcome.setId(updatedId);
|
||||
outcome.setResource(thePatient);
|
||||
return outcome;
|
||||
}
|
||||
//END SNIPPET: updatePrefer
|
||||
|
||||
//START SNIPPET: updateRaw
|
||||
@Update
|
||||
public MethodOutcome updatePatientWithRawValue (
|
||||
|
|
|
@ -21,16 +21,18 @@ package ca.uhn.fhir.rest.api;
|
|||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
public class MethodOutcome {
|
||||
|
||||
private Boolean myCreated;
|
||||
private IIdType myId;
|
||||
private IBaseOperationOutcome myOperationOutcome;
|
||||
private IBaseResource myResource;
|
||||
private IdDt myVersionId;
|
||||
private Boolean myCreated;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -38,16 +40,6 @@ public class MethodOutcome {
|
|||
public MethodOutcome() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theId
|
||||
* The ID of the created/updated resource
|
||||
*/
|
||||
public MethodOutcome(IIdType theId) {
|
||||
myId = theId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -115,6 +107,24 @@ public class MethodOutcome {
|
|||
myOperationOutcome = theBaseOperationOutcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theId
|
||||
* The ID of the created/updated resource
|
||||
*/
|
||||
public MethodOutcome(IIdType theId) {
|
||||
myId = theId;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will be set to {@link Boolean#TRUE} for instance of MethodOutcome which are
|
||||
* returned to client instances, if the server has responded with an HTTP 201 Created.
|
||||
*/
|
||||
public Boolean getCreated() {
|
||||
return myCreated;
|
||||
}
|
||||
|
||||
public IIdType getId() {
|
||||
return myId;
|
||||
}
|
||||
|
@ -128,6 +138,15 @@ public class MethodOutcome {
|
|||
return myOperationOutcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>From a client response:</b> If the method returned an actual resource body (e.g. a create/update with
|
||||
* "Prefer: return=representation") this field will be populated with the
|
||||
* resource itself.
|
||||
*/
|
||||
public IBaseResource getResource() {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link MethodOutcome#getId()} should return the complete ID including version if it is available
|
||||
*/
|
||||
|
@ -136,14 +155,6 @@ public class MethodOutcome {
|
|||
return myVersionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will be set to {@link Boolean#TRUE} for instance of MethodOutcome which are
|
||||
* returned to client instances, if the server has responded with an HTTP 201 Created.
|
||||
*/
|
||||
public Boolean getCreated() {
|
||||
return myCreated;
|
||||
}
|
||||
|
||||
/**
|
||||
* If not null, indicates whether the resource was created (as opposed to being updated). This is generally not needed, since the server can assume based on the method being called whether the
|
||||
* result was a creation or an update. However, it can be useful if you are implementing an update method that does a create if the ID doesn't already exist.
|
||||
|
@ -175,6 +186,19 @@ public class MethodOutcome {
|
|||
myOperationOutcome = theBaseOperationOutcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>In a server response</b>: This field may be populated in server code with the final resource for operations
|
||||
* where a resource body is being created/updated. E.g. for an update method, this field could be populated with
|
||||
* the resource after the update is applied, with the new version ID, lastUpdate time, etc.
|
||||
* <p>
|
||||
* This field is optional, but if it is populated the server will return the resource body if requested to
|
||||
* do so via the HTTP Prefer header.
|
||||
* </p>
|
||||
*/
|
||||
public void setResource(IBaseResource theResource) {
|
||||
myResource = theResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Put the ID and version ID into the same IdDt instance and pass it to {@link #setId(IdDt)}
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package ca.uhn.fhir.rest.api;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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 java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Represents values for "return" value as provided in the the <a href="https://tools.ietf.org/html/rfc7240#section-4.2">HTTP Prefer header</a>.
|
||||
*/
|
||||
public enum PreferReturnEnum {
|
||||
|
||||
REPRESENTATION("representation"), MINIMAL("minimal");
|
||||
|
||||
private String myHeaderValue;
|
||||
private static HashMap<String, PreferReturnEnum> ourValues;
|
||||
|
||||
private PreferReturnEnum(String theHeaderValue) {
|
||||
myHeaderValue = theHeaderValue;
|
||||
}
|
||||
|
||||
public static PreferReturnEnum fromHeaderValue(String theHeaderValue) {
|
||||
if (ourValues == null) {
|
||||
HashMap<String, PreferReturnEnum> values = new HashMap<String, PreferReturnEnum>();
|
||||
for (PreferReturnEnum next : PreferReturnEnum.values()) {
|
||||
values.put(next.getHeaderValue(), next);
|
||||
}
|
||||
ourValues = values;
|
||||
}
|
||||
return ourValues.get(theHeaderValue);
|
||||
}
|
||||
|
||||
public String getHeaderValue() {
|
||||
return myHeaderValue;
|
||||
}
|
||||
|
||||
}
|
|
@ -64,6 +64,7 @@ import ca.uhn.fhir.model.primitive.UriDt;
|
|||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
||||
import ca.uhn.fhir.rest.gclient.IClientExecutable;
|
||||
import ca.uhn.fhir.rest.gclient.ICreate;
|
||||
|
@ -563,6 +564,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
params.get(parameterName).add(parameterValue);
|
||||
}
|
||||
|
||||
private static void addPreferHeader(PreferReturnEnum thePrefer, BaseHttpClientInvocation theInvocation) {
|
||||
if (thePrefer != null) {
|
||||
theInvocation.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RETURN + '=' + thePrefer.getHeaderValue());
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class BaseClientExecutable<T extends IClientExecutable<?, ?>, Y> implements IClientExecutable<T, Y> {
|
||||
private EncodingEnum myParamEncoding;
|
||||
private Boolean myPrettyPrint;
|
||||
|
@ -650,6 +657,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
private CriterionList myCriterionList;
|
||||
private String myId;
|
||||
private PreferReturnEnum myPrefer;
|
||||
private IBaseResource myResource;
|
||||
private String myResourceBody;
|
||||
private String mySearchUrl;
|
||||
|
@ -693,6 +701,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
invocation = MethodUtil.createCreateInvocation(myResource, myResourceBody, myId, myContext);
|
||||
}
|
||||
|
||||
addPreferHeader(myPrefer, invocation);
|
||||
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource);
|
||||
final String resourceName = def.getName();
|
||||
|
||||
|
@ -703,6 +713,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICreateTyped prefer(PreferReturnEnum theReturn) {
|
||||
myPrefer = theReturn;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICreateTyped resource(IBaseResource theResource) {
|
||||
Validate.notNull(theResource, "Resource can not be null");
|
||||
|
@ -1250,7 +1266,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private final class OperationOutcomeResponseHandler implements IClientResponseHandler<BaseOperationOutcome> {
|
||||
|
||||
@Override
|
||||
public BaseOperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
public BaseOperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (respType == null) {
|
||||
return null;
|
||||
|
@ -1278,7 +1294,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
||||
MethodOutcome response = MethodUtil.process2xxResponse(myContext, myResourceName, theResponseStatusCode, theResponseMimeType, theResponseReader, theHeaders);
|
||||
if (theResponseStatusCode == Constants.STATUS_HTTP_201_CREATED) {
|
||||
response.setCreated(true);
|
||||
|
@ -1418,7 +1434,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||
Class<? extends IBaseResource> bundleType = myContext.getResourceDefinition("Bundle").getImplementingClass();
|
||||
ResourceResponseHandler<IBaseResource> handler = new ResourceResponseHandler<IBaseResource>((Class<IBaseResource>) bundleType, null);
|
||||
|
@ -1443,7 +1459,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public T invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
public T invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (respType == null) {
|
||||
throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
|
||||
|
@ -1463,6 +1479,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private String myCompartmentName;
|
||||
private CriterionList myCriterion = new CriterionList();
|
||||
private List<Include> myInclude = new ArrayList<Include>();
|
||||
private DateRangeParam myLastUpdated;
|
||||
private Integer myParamLimit;
|
||||
private String myResourceId;
|
||||
private String myResourceName;
|
||||
|
@ -1470,7 +1487,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private Class<? extends IBaseBundle> myReturnBundleType;
|
||||
private List<Include> myRevInclude = new ArrayList<Include>();
|
||||
private SearchStyleEnum mySearchStyle;
|
||||
private DateRangeParam myLastUpdated;
|
||||
private List<SortInternal> mySort = new ArrayList<SortInternal>();
|
||||
|
||||
public SearchInternal() {
|
||||
|
@ -1559,6 +1575,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery lastUpdated(DateRangeParam theLastUpdated) {
|
||||
myLastUpdated = theLastUpdated;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery limitTo(int theLimitTo) {
|
||||
if (theLimitTo > 0) {
|
||||
|
@ -1621,12 +1643,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery lastUpdated(DateRangeParam theLastUpdated) {
|
||||
myLastUpdated = theLastUpdated;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
@ -1682,7 +1698,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private final class TagListResponseHandler implements IClientResponseHandler<TagList> {
|
||||
|
||||
@Override
|
||||
public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (respType == null) {
|
||||
throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
|
||||
|
@ -1786,6 +1802,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
private CriterionList myCriterionList;
|
||||
private IIdType myId;
|
||||
private PreferReturnEnum myPrefer;
|
||||
private IBaseResource myResource;
|
||||
private String myResourceBody;
|
||||
private String mySearchUrl;
|
||||
|
@ -1834,6 +1851,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
invocation = MethodUtil.createUpdateInvocation(myResource, myResourceBody, myId, myContext);
|
||||
}
|
||||
|
||||
addPreferHeader(myPrefer, invocation);
|
||||
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource);
|
||||
final String resourceName = def.getName();
|
||||
|
||||
|
@ -1844,6 +1863,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IUpdateExecutable prefer(PreferReturnEnum theReturn) {
|
||||
myPrefer = theReturn;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IUpdateTyped resource(IBaseResource theResource) {
|
||||
Validate.notNull(theResource, "Resource can not be null");
|
||||
|
|
|
@ -22,20 +22,34 @@ package ca.uhn.fhir.rest.gclient;
|
|||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
|
||||
public interface ICreateTyped extends IClientExecutable<ICreateTyped, MethodOutcome> {
|
||||
|
||||
/**
|
||||
* If you want the explicitly state an ID for your created resource, put that ID here. You generally do not
|
||||
* need to invoke this method, so that the server will assign the ID itself.
|
||||
*
|
||||
* <p>
|
||||
* Note that creating a resource by ID is no longer supported as of FHIR DSTU2. You should use the {@link IGenericClient#update()} operation
|
||||
* to create-by-ID in DSTU2.
|
||||
* </p>
|
||||
* @since HAPI 0.9 / FHIR DSTU 2
|
||||
*/
|
||||
ICreateTyped withId(String theId);
|
||||
ICreateWithQuery conditional();
|
||||
|
||||
/**
|
||||
* Specifies that the create should be performed as a conditional create
|
||||
* against a given search URL.
|
||||
*
|
||||
* @param theSearchUrl The search URL to use. The format of this URL should be of the form <code>[ResourceType]?[Parameters]</code>,
|
||||
* for example: <code>Patient?name=Smith&identifier=13.2.4.11.4%7C847366</code>
|
||||
* @since HAPI 0.9 / FHIR DSTU 2
|
||||
*/
|
||||
ICreateTyped conditionalByUrl(String theSearchUrl);
|
||||
|
||||
/**
|
||||
* Add a <code>Prefer</code> header to the request, which requests that the server include
|
||||
* or suppress the resource body as a part of the result. If a resource is returned by the server
|
||||
* it will be parsed an accessible to the client via {@link MethodOutcome#getResource()}
|
||||
*
|
||||
* @since HAPI 1.1
|
||||
*/
|
||||
ICreateTyped prefer(PreferReturnEnum theReturn);
|
||||
|
||||
/**
|
||||
* If you want the explicitly state an ID for your created resource, put that ID here. You generally do not
|
||||
|
@ -49,18 +63,14 @@ public interface ICreateTyped extends IClientExecutable<ICreateTyped, MethodOutc
|
|||
ICreateTyped withId(IdDt theId);
|
||||
|
||||
/**
|
||||
* Specifies that the create should be performed as a conditional create
|
||||
* against a given search URL.
|
||||
*
|
||||
* @param theSearchUrl The search URL to use. The format of this URL should be of the form <code>[ResourceType]?[Parameters]</code>,
|
||||
* for example: <code>Patient?name=Smith&identifier=13.2.4.11.4%7C847366</code>
|
||||
* @since HAPI 0.9 / FHIR DSTU 2
|
||||
* If you want the explicitly state an ID for your created resource, put that ID here. You generally do not
|
||||
* need to invoke this method, so that the server will assign the ID itself.
|
||||
*
|
||||
* <p>
|
||||
* Note that creating a resource by ID is no longer supported as of FHIR DSTU2. You should use the {@link IGenericClient#update()} operation
|
||||
* to create-by-ID in DSTU2.
|
||||
* </p>
|
||||
*/
|
||||
ICreateTyped conditionalByUrl(String theSearchUrl);
|
||||
|
||||
/**
|
||||
* @since HAPI 0.9 / FHIR DSTU 2
|
||||
*/
|
||||
ICreateWithQuery conditional();
|
||||
ICreateTyped withId(String theId);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,8 +21,17 @@ package ca.uhn.fhir.rest.gclient;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
|
||||
public interface IUpdateExecutable extends IClientExecutable<IUpdateExecutable, MethodOutcome>{
|
||||
|
||||
|
||||
/**
|
||||
* Add a <code>Prefer</code> header to the request, which requests that the server include
|
||||
* or suppress the resource body as a part of the result. If a resource is returned by the server
|
||||
* it will be parsed an accessible to the client via {@link MethodOutcome#getResource()}
|
||||
*
|
||||
* @since HAPI 1.1
|
||||
*/
|
||||
IUpdateExecutable prefer(PreferReturnEnum theReturn);
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import java.util.Set;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -39,6 +39,7 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -170,7 +171,8 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
}
|
||||
}
|
||||
|
||||
IBaseOperationOutcome outcome = response != null ? response.getOperationOutcome() : null;
|
||||
IBaseResource outcome = response != null ? response.getOperationOutcome() : null;
|
||||
IBaseResource resource = response != null ? response.getResource() : null;
|
||||
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
|
||||
IServerInterceptor next = theServer.getInterceptors().get(i);
|
||||
boolean continueProcessing = next.outgoingResponse(theRequest, outcome, theRequest.getServletRequest(), theRequest.getServletResponse());
|
||||
|
@ -179,6 +181,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
}
|
||||
}
|
||||
|
||||
boolean allowPrefer = false;
|
||||
switch (getResourceOperationType()) {
|
||||
case CREATE:
|
||||
if (response == null) {
|
||||
|
@ -191,6 +194,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
servletResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||
}
|
||||
addContentLocationHeaders(theRequest, servletResponse, response);
|
||||
allowPrefer = true;
|
||||
break;
|
||||
|
||||
case UPDATE:
|
||||
|
@ -200,6 +204,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||
}
|
||||
addContentLocationHeaders(theRequest, servletResponse, response);
|
||||
allowPrefer = true;
|
||||
break;
|
||||
|
||||
case VALIDATE:
|
||||
|
@ -222,6 +227,16 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
|
||||
theServer.addHeadersToResponse(servletResponse);
|
||||
|
||||
if (resource != null && allowPrefer) {
|
||||
String prefer = theRequest.getServletRequest().getHeader(Constants.HEADER_PREFER);
|
||||
PreferReturnEnum preferReturn = RestfulServerUtils.parsePreferHeader(prefer);
|
||||
if (preferReturn != null) {
|
||||
if (preferReturn == PreferReturnEnum.REPRESENTATION) {
|
||||
outcome = resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outcome != null) {
|
||||
EncodingEnum encoding = RestfulServerUtils.determineResponseEncodingWithDefault(theServer, theRequest.getServletRequest());
|
||||
servletResponse.setContentType(encoding.getResourceContentType());
|
||||
|
@ -229,7 +244,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
IParser parser = encoding.newParser(getContext());
|
||||
parser.setPrettyPrint(RestfulServerUtils.prettyPrintResponse(theServer, theRequest));
|
||||
try {
|
||||
parser.encodeResourceToWriter(response.getOperationOutcome(), writer);
|
||||
parser.encodeResourceToWriter(outcome, writer);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PushbackReader;
|
||||
|
@ -747,6 +748,8 @@ public class MethodUtil {
|
|||
IBaseResource outcome = parser.parseResource(reader);
|
||||
if (outcome instanceof BaseOperationOutcome) {
|
||||
retVal.setOperationOutcome((BaseOperationOutcome) outcome);
|
||||
} else {
|
||||
retVal.setResource(outcome);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ package ca.uhn.fhir.rest.param;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -30,8 +32,8 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
|
||||
public class ReferenceParam extends IdDt implements IQueryParameterType {
|
||||
|
||||
private String myChain;
|
||||
private BaseParam myBase=new BaseParam.ComposableBaseParam();
|
||||
private String myChain;
|
||||
|
||||
public ReferenceParam() {
|
||||
}
|
||||
|
@ -58,6 +60,11 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
return myChain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getMissing() {
|
||||
return myBase.getMissing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryParameterQualifier() {
|
||||
if (myBase.getMissing()!=null) {
|
||||
|
@ -79,6 +86,13 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Class<? extends IBaseResource> getResourceType(FhirContext theCtx) {
|
||||
if (isBlank(getResourceType())) {
|
||||
return null;
|
||||
}
|
||||
return theCtx.getResourceDefinition(getResourceType()).getImplementingClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueAsQueryToken() {
|
||||
if (myBase.getMissing()!=null) {
|
||||
|
@ -95,11 +109,9 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
myChain = theChain;
|
||||
}
|
||||
|
||||
public Class<? extends IBaseResource> getResourceType(FhirContext theCtx) {
|
||||
if (isBlank(getResourceType())) {
|
||||
return null;
|
||||
}
|
||||
return theCtx.getResourceDefinition(getResourceType()).getImplementingClass();
|
||||
@Override
|
||||
public void setMissing(Boolean theMissing) {
|
||||
myBase.setMissing(theMissing);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,21 +146,6 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link TokenParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public TokenParam toTokenParam() {
|
||||
TokenParam retVal = new TokenParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link DateParam}. This is useful if you are using reference parameters and want to handle
|
||||
|
@ -164,21 +161,6 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link StringParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public StringParam toStringParam() {
|
||||
StringParam retVal = new StringParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link NumberParam}. This is useful if you are using reference parameters and want to handle
|
||||
|
@ -193,7 +175,7 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
retVal.setValueAsQueryToken(null, getValueAsQueryToken());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link QuantityParam}. This is useful if you are using reference parameters and want to handle
|
||||
|
@ -210,13 +192,43 @@ public class ReferenceParam extends IdDt implements IQueryParameterType {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean getMissing() {
|
||||
return myBase.getMissing();
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
if (isNotBlank(myChain)) {
|
||||
b.append("chain", myChain);
|
||||
}
|
||||
b.append("value", getValue());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMissing(Boolean theMissing) {
|
||||
myBase.setMissing(theMissing);
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link StringParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public StringParam toStringParam() {
|
||||
StringParam retVal = new StringParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link TokenParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public TokenParam toTokenParam() {
|
||||
TokenParam retVal = new TokenParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -133,6 +133,10 @@ public class Constants {
|
|||
public static final int STATUS_HTTP_501_NOT_IMPLEMENTED = 501;
|
||||
public static final String URL_TOKEN_HISTORY = "_history";
|
||||
public static final String URL_TOKEN_METADATA = "metadata";
|
||||
public static final String HEADER_PREFER = "Prefer";
|
||||
public static final String HEADER_PREFER_RETURN = "return";
|
||||
public static final String HEADER_PREFER_RETURN_MINIMAL = "minimal";
|
||||
public static final String HEADER_PREFER_RETURN_REPRESENTATION = "representation";
|
||||
|
||||
static {
|
||||
Map<String, EncodingEnum> valToEncoding = new HashMap<String, EncodingEnum>();
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.Enumeration;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
@ -57,6 +58,7 @@ import ca.uhn.fhir.model.api.Tag;
|
|||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
||||
|
@ -80,7 +82,7 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String createPagingLink(Set<Include> theIncludes, String theServerBase, String theSearchId, int theOffset, int theCount, EncodingEnum theResponseEncoding, boolean thePrettyPrint) {
|
||||
try {
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
@ -128,6 +130,8 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static RestfulServer.NarrativeModeEnum determineNarrativeMode(RequestDetails theRequest) {
|
||||
Map<String, String[]> requestParams = theRequest.getParameters();
|
||||
String[] narrative = requestParams.get(Constants.PARAM_NARRATIVE);
|
||||
|
@ -281,6 +285,38 @@ public class RestfulServerUtils {
|
|||
return writer;
|
||||
}
|
||||
|
||||
public static PreferReturnEnum parsePreferHeader(String theValue) {
|
||||
if (isBlank(theValue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringTokenizer tok = new StringTokenizer(theValue, ",");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String next = tok.nextToken();
|
||||
int eqIndex = next.indexOf('=');
|
||||
if (eqIndex == -1 || eqIndex >= next.length() - 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = next.substring(0, eqIndex).trim();
|
||||
if (key.equals(Constants.HEADER_PREFER_RETURN) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value = next.substring(eqIndex + 1).trim();
|
||||
if (value.length() < 2) {
|
||||
continue;
|
||||
}
|
||||
if ('"' == value.charAt(0) && '"' == value.charAt(value.length() - 1)) {
|
||||
value = value.substring(1, value.length() - 1);
|
||||
}
|
||||
|
||||
return PreferReturnEnum.fromHeaderValue(value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean prettyPrintResponse(RestfulServer theServer, RequestDetails theRequest) {
|
||||
Map<String, String[]> requestParams = theRequest.getParameters();
|
||||
String[] pretty = requestParams.get(Constants.PARAM_PRETTY);
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.util;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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 static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package org.hl7.fhir.instance.model.api;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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 IBaseOperationOutcome extends IBaseResource {
|
||||
|
||||
|
|
|
@ -48,5 +48,6 @@ ca.uhn.fhir.jpa.dao.BaseFhirSystemDao.transactionInvalidUrl=Unable to perform {0
|
|||
ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.duplicateCreateForcedId=Can not create entity with ID[{0}], a resource with this ID already exists
|
||||
ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.failedToCreateWithClientAssignedNumericId=Can not create resource with ID[{0}], no resource with this ID exists and clients may only assign IDs which begin with a non-numeric character on this server
|
||||
ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.failedToCreateWithClientAssignedId=Can not create resource with ID[{0}], ID must not be supplied on a create (POST) operation
|
||||
ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.invalidParameterChain=Invalid parameter chain: {0}
|
||||
ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.multipleParamsWithSameNameOneIsMissingTrue=This server does not know how to handle multiple "{0}" parameters where one has a value of :missing=true
|
||||
ca.uhn.fhir.jpa.dao.BaseFhirResourceDao.unableToDeleteNotFound=Unable to find resource matching URL "{0}". Deletion failed.
|
||||
|
|
|
@ -20,7 +20,8 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
|
@ -311,7 +312,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
if (addPredicateMissingFalseIfPresent(builder, theParamName, from, codePredicates, nextOr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (params instanceof NumberParam) {
|
||||
NumberParam param = (NumberParam) params;
|
||||
|
||||
|
@ -374,7 +375,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
cq.select(from.get("myId").as(Long.class));
|
||||
|
||||
Subquery<Long> subQ = cq.subquery(Long.class);
|
||||
Root<? extends BaseResourceIndexedSearchParam> subQfrom = subQ.from(theParamTable);
|
||||
Root<? extends BaseResourceIndexedSearchParam> subQfrom = subQ.from(theParamTable);
|
||||
subQ.select(subQfrom.get("myResourcePid").as(Long.class));
|
||||
Predicate subQname = builder.equal(subQfrom.get("myParamName"), theParamName);
|
||||
Predicate subQtype = builder.equal(subQfrom.get("myResourceType"), resourceType);
|
||||
|
@ -383,16 +384,16 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
Predicate joinPredicate = builder.not(builder.in(from.get("myId")).value(subQ));
|
||||
Predicate typePredicate = builder.equal(from.get("myResourceType"), resourceType);
|
||||
Predicate notDeletedPredicate = builder.isNull(from.get("myDeleted"));
|
||||
|
||||
|
||||
if (thePids.size() > 0) {
|
||||
Predicate inPids = (from.get("myId").in(thePids));
|
||||
cq.where(builder.and(inPids, typePredicate, joinPredicate, notDeletedPredicate));
|
||||
} else {
|
||||
cq.where(builder.and(typePredicate, joinPredicate, notDeletedPredicate));
|
||||
}
|
||||
|
||||
|
||||
ourLog.info("Adding :missing qualifier for parameter '{}'", theParamName);
|
||||
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
List<Long> resultList = q.getResultList();
|
||||
HashSet<Long> retVal = new HashSet<Long>(resultList);
|
||||
|
@ -404,15 +405,15 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
cq.select(from.get("myId").as(Long.class));
|
||||
|
||||
|
||||
Subquery<Long> subQ = cq.subquery(Long.class);
|
||||
Root<ResourceLink> subQfrom = subQ.from(ResourceLink.class);
|
||||
Root<ResourceLink> subQfrom = subQ.from(ResourceLink.class);
|
||||
subQ.select(subQfrom.get("mySourceResourcePid").as(Long.class));
|
||||
|
||||
// subQ.where(builder.equal(subQfrom.get("myParamName"), theParamName));
|
||||
|
||||
// subQ.where(builder.equal(subQfrom.get("myParamName"), theParamName));
|
||||
Predicate path = createResourceLinkPathPredicate(theParamName, builder, subQfrom);
|
||||
subQ.where(path);
|
||||
|
||||
|
||||
Predicate joinPredicate = builder.not(builder.in(from.get("myId")).value(subQ));
|
||||
Predicate typePredicate = builder.equal(from.get("myResourceType"), myResourceName);
|
||||
|
||||
|
@ -422,7 +423,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
} else {
|
||||
cq.where(builder.and(typePredicate, joinPredicate));
|
||||
}
|
||||
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
List<Long> resultList = q.getResultList();
|
||||
HashSet<Long> retVal = new HashSet<Long>(resultList);
|
||||
|
@ -433,7 +434,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
if (theList == null || theList.isEmpty()) {
|
||||
return thePids;
|
||||
}
|
||||
|
||||
|
||||
if (Boolean.TRUE.equals(theList.get(0).getMissing())) {
|
||||
return addPredicateParamMissing(thePids, "myParamsQuantity", theParamName, ResourceIndexedSearchParamQuantity.class);
|
||||
}
|
||||
|
@ -450,7 +451,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
if (addPredicateMissingFalseIfPresent(builder, theParamName, from, codePredicates, nextOr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
String systemValue;
|
||||
String unitsValue;
|
||||
QuantityCompararatorEnum cmpValue;
|
||||
|
@ -569,7 +570,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
if (addPredicateMissingFalseIfPresentForResourceLink(builder, theParamName, from, codePredicates, nextOr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (params instanceof ReferenceParam) {
|
||||
ReferenceParam ref = (ReferenceParam) params;
|
||||
|
||||
|
@ -587,10 +588,11 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
codePredicates.add(eq);
|
||||
|
||||
} else {
|
||||
String chain = getContext().getResourceDefinition(myResourceType).getSearchParam(theParamName).getPath();
|
||||
BaseRuntimeChildDefinition def = getContext().newTerser().getDefinition(myResourceType, chain);
|
||||
|
||||
String paramPath = getContext().getResourceDefinition(myResourceType).getSearchParam(theParamName).getPath();
|
||||
BaseRuntimeChildDefinition def = getContext().newTerser().getDefinition(myResourceType, paramPath);
|
||||
if (!(def instanceof RuntimeChildResourceDefinition)) {
|
||||
throw new ConfigurationException("Property " + chain + " of type " + myResourceName + " is not a resource: " + def.getClass());
|
||||
throw new ConfigurationException("Property " + paramPath + " of type " + myResourceName + " is not a resource: " + def.getClass());
|
||||
}
|
||||
List<Class<? extends IBaseResource>> resourceTypes;
|
||||
if (isBlank(ref.getResourceType())) {
|
||||
|
@ -601,9 +603,20 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
RuntimeResourceDefinition resDef = getContext().getResourceDefinition(ref.getResourceType());
|
||||
resourceTypes.add(resDef.getImplementingClass());
|
||||
}
|
||||
|
||||
boolean foundChainMatch = false;
|
||||
for (Class<? extends IBaseResource> nextType : resourceTypes) {
|
||||
RuntimeResourceDefinition typeDef = getContext().getResourceDefinition(nextType);
|
||||
RuntimeSearchParam param = typeDef.getSearchParam(ref.getChain());
|
||||
|
||||
String chain = ref.getChain();
|
||||
String remainingChain = null;
|
||||
int chainDotIndex = chain.indexOf('.');
|
||||
if (chainDotIndex != -1) {
|
||||
remainingChain = chain.substring(chainDotIndex + 1);
|
||||
chain = chain.substring(0, chainDotIndex);
|
||||
}
|
||||
|
||||
RuntimeSearchParam param = typeDef.getSearchParam(chain);
|
||||
if (param == null) {
|
||||
ourLog.debug("Type {} doesn't have search param {}", nextType.getSimpleName(), param);
|
||||
continue;
|
||||
|
@ -613,9 +626,24 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
ourLog.debug("Don't have a DAO for type {}", nextType.getSimpleName(), param);
|
||||
continue;
|
||||
}
|
||||
|
||||
IQueryParameterType chainValue = toParameterType(param, resourceId);
|
||||
Set<Long> pids = dao.searchForIds(ref.getChain(), chainValue);
|
||||
|
||||
IQueryParameterType chainValue;
|
||||
if (remainingChain != null) {
|
||||
if (param.getParamType() != RestSearchParameterTypeEnum.REFERENCE) {
|
||||
ourLog.debug("Type {} parameter {} is not a reference, can not chain {}", new Object[] { nextType.getSimpleName(), chain, remainingChain });
|
||||
continue;
|
||||
}
|
||||
|
||||
chainValue = new ReferenceParam();
|
||||
chainValue.setValueAsQueryToken(null, resourceId);
|
||||
((ReferenceParam)chainValue).setChain(remainingChain);
|
||||
} else {
|
||||
chainValue = toParameterType(param, resourceId);
|
||||
}
|
||||
|
||||
foundChainMatch = true;
|
||||
|
||||
Set<Long> pids = dao.searchForIds(chain, chainValue);
|
||||
if (pids.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -624,10 +652,14 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
codePredicates.add(eq);
|
||||
|
||||
}
|
||||
|
||||
if (!foundChainMatch) {
|
||||
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirResourceDao.class, "invalidParameterChain", theParamName + '.' + ref.getChain()));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
||||
throw new IllegalArgumentException("Invalid token type (expecting ReferenceParam): " + params.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -673,7 +705,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
if (addPredicateMissingFalseIfPresent(builder, theParamName, from, codePredicates, nextOr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Predicate singleCode = createPredicateString(theParameter, theParamName, builder, from);
|
||||
codePredicates.add(singleCode);
|
||||
}
|
||||
|
@ -693,7 +725,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
return new HashSet<Long>(q.getResultList());
|
||||
}
|
||||
|
||||
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates, IQueryParameterType nextOr) {
|
||||
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates,
|
||||
IQueryParameterType nextOr) {
|
||||
boolean missingFalse = false;
|
||||
if (nextOr.getMissing() != null) {
|
||||
if (nextOr.getMissing().booleanValue() == true) {
|
||||
|
@ -707,7 +740,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
return missingFalse;
|
||||
}
|
||||
|
||||
private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, Root<? extends ResourceLink> from, List<Predicate> codePredicates, IQueryParameterType nextOr) {
|
||||
private boolean addPredicateMissingFalseIfPresentForResourceLink(CriteriaBuilder theBuilder, String theParamName, Root<? extends ResourceLink> from, List<Predicate> codePredicates,
|
||||
IQueryParameterType nextOr) {
|
||||
boolean missingFalse = false;
|
||||
if (nextOr.getMissing() != null) {
|
||||
if (nextOr.getMissing().booleanValue() == true) {
|
||||
|
@ -740,7 +774,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
if (addPredicateMissingFalseIfPresent(builder, theParamName, from, codePredicates, nextOr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (nextOr instanceof TokenParam) {
|
||||
TokenParam id = (TokenParam) nextOr;
|
||||
if (id.isText()) {
|
||||
|
@ -1101,9 +1135,9 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
|
||||
private DaoMethodOutcome doCreate(T theResource, String theIfNoneExist, boolean thePerformIndexing) {
|
||||
StopWatch w = new StopWatch();
|
||||
|
||||
|
||||
preProcessResourceForStorage(theResource);
|
||||
|
||||
|
||||
ResourceTable entity = new ResourceTable();
|
||||
entity.setResourceType(toResourceName(theResource));
|
||||
|
||||
|
@ -1147,8 +1181,10 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
}
|
||||
|
||||
/**
|
||||
* May
|
||||
* @param theResource The resource that is about to be stored
|
||||
* May
|
||||
*
|
||||
* @param theResource
|
||||
* The resource that is about to be stored
|
||||
*/
|
||||
protected void preProcessResourceForStorage(T theResource) {
|
||||
// nothing by default
|
||||
|
@ -1242,9 +1278,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
retVal.add(current);
|
||||
}
|
||||
|
||||
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery(
|
||||
"SELECT h FROM ResourceHistoryTable h WHERE h.myResourceId = :PID AND h.myResourceType = :RESTYPE AND h.myUpdated < :END "
|
||||
+ (theSince != null ? " AND h.myUpdated >= :SINCE" : "") + " ORDER BY h.myUpdated ASC", ResourceHistoryTable.class);
|
||||
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery("SELECT h FROM ResourceHistoryTable h WHERE h.myResourceId = :PID AND h.myResourceType = :RESTYPE AND h.myUpdated < :END "
|
||||
+ (theSince != null ? " AND h.myUpdated >= :SINCE" : "") + " ORDER BY h.myUpdated ASC", ResourceHistoryTable.class);
|
||||
q.setParameter("PID", translateForcedIdToPid(theId));
|
||||
q.setParameter("RESTYPE", resourceType);
|
||||
q.setParameter("END", end.getValue(), TemporalType.TIMESTAMP);
|
||||
|
@ -1486,8 +1521,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
throw new ConfigurationException("Unknown search param on resource[" + myResourceName + "] for secondary key[" + mySecondaryPrimaryKeyParamName + "]");
|
||||
}
|
||||
if (sp.getParamType() != RestSearchParameterTypeEnum.TOKEN) {
|
||||
throw new ConfigurationException("Search param on resource[" + myResourceName + "] for secondary key[" + mySecondaryPrimaryKeyParamName
|
||||
+ "] is not a token type, only token is supported");
|
||||
throw new ConfigurationException("Search param on resource[" + myResourceName + "] for secondary key[" + mySecondaryPrimaryKeyParamName + "] is not a token type, only token is supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1636,10 +1670,10 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
cq.select(from.get("myId").as(Long.class));
|
||||
|
||||
|
||||
Predicate predicateIds = (from.get("myId").in(loadPids));
|
||||
Predicate predicateLower = lu.getLowerBoundAsInstant() != null ? builder.greaterThanOrEqualTo(from.<Date>get("myUpdated"), lu.getLowerBoundAsInstant()) : null;
|
||||
Predicate predicateUpper = lu.getUpperBoundAsInstant() != null ? builder.lessThanOrEqualTo(from.<Date>get("myUpdated"), lu.getUpperBoundAsInstant()) : null;
|
||||
Predicate predicateLower = lu.getLowerBoundAsInstant() != null ? builder.greaterThanOrEqualTo(from.<Date> get("myUpdated"), lu.getLowerBoundAsInstant()) : null;
|
||||
Predicate predicateUpper = lu.getUpperBoundAsInstant() != null ? builder.lessThanOrEqualTo(from.<Date> get("myUpdated"), lu.getUpperBoundAsInstant()) : null;
|
||||
if (predicateLower != null && predicateUpper != null) {
|
||||
cq.where(predicateIds, predicateLower, predicateUpper);
|
||||
} else if (predicateLower != null) {
|
||||
|
@ -1719,8 +1753,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
loadResourcesByPid(pidsSubList, retVal, BundleEntrySearchModeEnum.MATCH);
|
||||
|
||||
/*
|
||||
* Load _include resources - Note that _revincludes are handled differently than _include ones, as they are counted towards the total count and paged, so they are loaded
|
||||
* outside the bundle provider
|
||||
* Load _include resources - Note that _revincludes are handled differently than _include ones, as they are counted towards the total count and paged, so they are loaded outside the
|
||||
* bundle provider
|
||||
*/
|
||||
if (theParams.getIncludes() != null && theParams.getIncludes().isEmpty() == false) {
|
||||
Set<IIdType> previouslyLoadedPids = new HashSet<IIdType>();
|
||||
|
@ -1960,6 +1994,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
outcome.setResource(theResource);
|
||||
if (theResource != null) {
|
||||
theResource.setId(theEntity.getIdDt());
|
||||
ResourceMetadataKeyEnum.UPDATED.put(theResource, theEntity.getUpdated());
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
@ -1992,6 +2027,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
qp = new CompositeParam<IQueryParameterType, IQueryParameterType>(leftParam, rightParam);
|
||||
break;
|
||||
case REFERENCE:
|
||||
qp = new ReferenceParam();
|
||||
break;
|
||||
default:
|
||||
throw new InternalErrorException("Don't know how to convert param type: " + theParam.getParamType());
|
||||
}
|
||||
|
|
|
@ -21,36 +21,25 @@ package ca.uhn.fhir.jpa.dao;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
|
||||
public class DaoMethodOutcome extends MethodOutcome {
|
||||
|
||||
private ResourceTable myEntity;
|
||||
private IResource myResource;
|
||||
private ResourceTable myEntity;
|
||||
|
||||
public ResourceTable getEntity() {
|
||||
return myEntity;
|
||||
}
|
||||
public ResourceTable getEntity() {
|
||||
return myEntity;
|
||||
}
|
||||
|
||||
public IResource getResource() {
|
||||
return myResource;
|
||||
}
|
||||
@Override
|
||||
public DaoMethodOutcome setCreated(Boolean theCreated) {
|
||||
super.setCreated(theCreated);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DaoMethodOutcome setCreated(Boolean theCreated) {
|
||||
super.setCreated(theCreated);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DaoMethodOutcome setEntity(ResourceTable theEntity) {
|
||||
myEntity = theEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DaoMethodOutcome setResource(IResource theResource) {
|
||||
myResource = theResource;
|
||||
return this;
|
||||
}
|
||||
public DaoMethodOutcome setEntity(ResourceTable theEntity) {
|
||||
myEntity = theEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -32,8 +33,6 @@ import java.util.Set;
|
|||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.springframework.jmx.access.InvalidInvocationException;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -318,7 +317,7 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
|
|||
FhirTerser terser = getContext().newTerser();
|
||||
|
||||
for (DaoMethodOutcome nextOutcome : idToPersistedOutcome.values()) {
|
||||
IResource nextResource = nextOutcome.getResource();
|
||||
IResource nextResource = (IResource) nextOutcome.getResource();
|
||||
if (nextResource == null) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
|
@ -20,6 +35,7 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.jmx.access.InvalidInvocationException;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||
|
@ -78,7 +94,7 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||
public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||
|
||||
private static ClassPathXmlApplicationContext ourCtx;
|
||||
private static IFhirResourceDao<Device> ourDeviceDao;
|
||||
|
@ -90,28 +106,11 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
private static IFhirResourceDao<Observation> ourObservationDao;
|
||||
private static IFhirResourceDao<Organization> ourOrganizationDao;
|
||||
private static IFhirResourceDao<Patient> ourPatientDao;
|
||||
private static IFhirSystemDao<Bundle> ourSystemDao;
|
||||
private static IFhirResourceDao<Questionnaire> ourQuestionnaireDao;
|
||||
@SuppressWarnings("unused")
|
||||
private static IFhirResourceDao<QuestionnaireAnswers> ourQuestionnaireAnswersDao;
|
||||
private static IFhirResourceDao<Questionnaire> ourQuestionnaireDao;
|
||||
private static IFhirSystemDao<Bundle> ourSystemDao;
|
||||
|
||||
@Test
|
||||
public void testQuestionnaireTitleGetsIndexed() {
|
||||
Questionnaire q = new Questionnaire();
|
||||
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_TITLE");
|
||||
IIdType qid1 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
||||
q = new Questionnaire();
|
||||
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_NOTITLE");
|
||||
IIdType qid2 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
||||
|
||||
IBundleProvider results = ourQuestionnaireDao.search("title", new StringParam("testQuestionnaireTitleGetsIndexedQ_TITLE"));
|
||||
assertEquals(1, results.size());
|
||||
assertEquals(qid1, results.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
assertNotEquals(qid2, results.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChoiceParamConcept() {
|
||||
Observation o1 = new Observation();
|
||||
|
@ -649,6 +648,51 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #196
|
||||
*/
|
||||
@Test
|
||||
public void testInvalidChainNames() {
|
||||
ReferenceParam param = null;
|
||||
|
||||
// OK
|
||||
param = new ReferenceParam("999999999999");
|
||||
param.setChain("organization");
|
||||
ourLocationDao.search("partof", param);
|
||||
|
||||
// OK
|
||||
param = new ReferenceParam("999999999999");
|
||||
param.setChain("organization.name");
|
||||
ourLocationDao.search("partof", param);
|
||||
|
||||
try {
|
||||
param = new ReferenceParam("999999999999");
|
||||
param.setChain("foo");
|
||||
ourLocationDao.search("partof", param);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid parameter chain: partof." + param.getChain()));
|
||||
}
|
||||
|
||||
try {
|
||||
param = new ReferenceParam("999999999999");
|
||||
param.setChain("organization.foo");
|
||||
ourLocationDao.search("partof", param);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid parameter chain: " + param.getChain()));
|
||||
}
|
||||
|
||||
try {
|
||||
param = new ReferenceParam("999999999999");
|
||||
param.setChain("organization.name.foo");
|
||||
ourLocationDao.search("partof", param);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid parameter chain: " + param.getChain()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrganizationName() {
|
||||
|
||||
|
@ -688,6 +732,21 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistContactPoint() {
|
||||
List<IResource> found = toList(ourPatientDao.search(Patient.SP_TELECOM, new TokenParam(null, "555-123-4567")));
|
||||
int initialSize2000 = found.size();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("testPersistContactPoint");
|
||||
patient.addTelecom().setValue("555-123-4567");
|
||||
ourPatientDao.create(patient);
|
||||
|
||||
found = toList(ourPatientDao.search(Patient.SP_TELECOM, new TokenParam(null, "555-123-4567")));
|
||||
assertEquals(1 + initialSize2000, found.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistResourceLink() {
|
||||
Patient patient = new Patient();
|
||||
|
@ -728,21 +787,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistContactPoint() {
|
||||
List<IResource> found = toList(ourPatientDao.search(Patient.SP_TELECOM, new TokenParam(null, "555-123-4567")));
|
||||
int initialSize2000 = found.size();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("testPersistContactPoint");
|
||||
patient.addTelecom().setValue("555-123-4567");
|
||||
ourPatientDao.create(patient);
|
||||
|
||||
found = toList(ourPatientDao.search(Patient.SP_TELECOM, new TokenParam(null, "555-123-4567")));
|
||||
assertEquals(1 + initialSize2000, found.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistSearchParamDate() {
|
||||
List<Patient> found = toList(ourPatientDao.search(Patient.SP_BIRTHDATE, new DateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01")));
|
||||
|
@ -852,6 +896,22 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuestionnaireTitleGetsIndexed() {
|
||||
Questionnaire q = new Questionnaire();
|
||||
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_TITLE");
|
||||
IIdType qid1 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
||||
q = new Questionnaire();
|
||||
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_NOTITLE");
|
||||
IIdType qid2 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
||||
|
||||
IBundleProvider results = ourQuestionnaireDao.search("title", new StringParam("testQuestionnaireTitleGetsIndexedQ_TITLE"));
|
||||
assertEquals(1, results.size());
|
||||
assertEquals(qid1, results.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
assertNotEquals(qid2, results.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadForcedIdVersionHistory() throws InterruptedException {
|
||||
Patient p1 = new Patient();
|
||||
|
@ -875,29 +935,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseIncludes() {
|
||||
String methodName = "testReverseIncludes";
|
||||
Organization org = new Organization();
|
||||
org.setName("X" + methodName + "X");
|
||||
IIdType orgId = ourOrganizationDao.create(org).getId();
|
||||
|
||||
Patient pat = new Patient();
|
||||
pat.addName().addFamily("X" + methodName + "X");
|
||||
pat.getManagingOrganization().setReference(orgId.toUnqualifiedVersionless());
|
||||
ourPatientDao.create(pat);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Organization.SP_NAME, new StringParam("X" + methodName + "X"));
|
||||
map.setRevIncludes(Collections.singleton(Patient.INCLUDE_ORGANIZATION));
|
||||
IBundleProvider resultsP = ourOrganizationDao.search(map);
|
||||
assertEquals(2, resultsP.size());
|
||||
List<IBaseResource> results = resultsP.getResources(0, resultsP.size());
|
||||
assertEquals(2, results.size());
|
||||
assertEquals(Organization.class, results.get(0).getClass());
|
||||
assertEquals(Patient.class, results.get(1).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceInstanceMetaOperation() {
|
||||
deleteEverything();
|
||||
|
@ -1136,6 +1173,29 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReverseIncludes() {
|
||||
String methodName = "testReverseIncludes";
|
||||
Organization org = new Organization();
|
||||
org.setName("X" + methodName + "X");
|
||||
IIdType orgId = ourOrganizationDao.create(org).getId();
|
||||
|
||||
Patient pat = new Patient();
|
||||
pat.addName().addFamily("X" + methodName + "X");
|
||||
pat.getManagingOrganization().setReference(orgId.toUnqualifiedVersionless());
|
||||
ourPatientDao.create(pat);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Organization.SP_NAME, new StringParam("X" + methodName + "X"));
|
||||
map.setRevIncludes(Collections.singleton(Patient.INCLUDE_ORGANIZATION));
|
||||
IBundleProvider resultsP = ourOrganizationDao.search(map);
|
||||
assertEquals(2, resultsP.size());
|
||||
List<IBaseResource> results = resultsP.getResources(0, resultsP.size());
|
||||
assertEquals(2, results.size());
|
||||
assertEquals(Organization.class, results.get(0).getClass());
|
||||
assertEquals(Patient.class, results.get(1).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchAll() {
|
||||
{
|
||||
|
@ -1299,7 +1359,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
@Test
|
||||
public void testSearchLastUpdatedParam() throws InterruptedException {
|
||||
String methodName = "testSearchLastUpdatedParam";
|
||||
|
||||
|
||||
int sleep = 100;
|
||||
Thread.sleep(sleep);
|
||||
|
||||
|
@ -1322,7 +1382,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
Thread.sleep(1100);
|
||||
DateTimeDt beforeR2 = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
|
||||
Thread.sleep(1100);
|
||||
|
||||
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
|
@ -1330,7 +1390,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
patient.addName().addFamily(methodName).addGiven("John");
|
||||
id2 = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
|
@ -1494,6 +1554,52 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchResourceLinkWithChainDouble() {
|
||||
String methodName = "testSearchResourceLinkWithChainDouble";
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setName(methodName);
|
||||
IIdType orgId01 = ourOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locParent = new Location();
|
||||
locParent.setManagingOrganization(new ResourceReferenceDt(orgId01));
|
||||
IIdType locParentId = ourLocationDao.create(locParent).getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locChild = new Location();
|
||||
locChild.setPartOf(new ResourceReferenceDt(locParentId));
|
||||
IIdType locChildId = ourLocationDao.create(locChild).getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locGrandchild = new Location();
|
||||
locGrandchild.setPartOf(new ResourceReferenceDt(locChildId));
|
||||
IIdType locGrandchildId = ourLocationDao.create(locGrandchild).getId().toUnqualifiedVersionless();
|
||||
|
||||
IBundleProvider found;
|
||||
ReferenceParam param;
|
||||
|
||||
found = ourLocationDao.search("organization", new ReferenceParam(orgId01.getIdPart()));
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(locParentId, found.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
param = new ReferenceParam(orgId01.getIdPart());
|
||||
param.setChain("organization");
|
||||
found = ourLocationDao.search("partof", param);
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(locChildId, found.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
param = new ReferenceParam(orgId01.getIdPart());
|
||||
param.setChain("partof.organization");
|
||||
found = ourLocationDao.search("partof", param);
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(locGrandchildId, found.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
param = new ReferenceParam(methodName);
|
||||
param.setChain("partof.organization.name");
|
||||
found = ourLocationDao.search("partof", param);
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(locGrandchildId, found.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchResourceLinkWithChainWithMultipleTypes() {
|
||||
Patient patient = new Patient();
|
||||
|
@ -1609,196 +1715,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingString() {
|
||||
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||
patient.setBirthDate(new DateDt("2011-01-01"));
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
notMissing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// String Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
StringParam param = new StringParam();
|
||||
param.setMissing(false);
|
||||
params.put(Patient.SP_FAMILY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
StringParam param = new StringParam();
|
||||
param.setMissing(true);
|
||||
params.put(Patient.SP_FAMILY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingQuantity() {
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
obs.setValue(new QuantityDt(123));
|
||||
notMissing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Quantity Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
QuantityParam param = new QuantityParam();
|
||||
param.setMissing(false);
|
||||
params.put(Observation.SP_VALUE_QUANTITY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
QuantityParam param = new QuantityParam();
|
||||
param.setMissing(true);
|
||||
params.put(Observation.SP_VALUE_QUANTITY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithToken() {
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
obs.getCode().addCoding().setSystem("urn:system").setCode("002");
|
||||
notMissing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Token Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
TokenParam param = new TokenParam();
|
||||
param.setMissing(false);
|
||||
params.put(Observation.SP_CODE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
TokenParam param = new TokenParam();
|
||||
param.setMissing(true);
|
||||
params.put(Observation.SP_CODE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingDate() {
|
||||
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||
patient.setBirthDate(new DateDt("2011-01-01"));
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
notMissing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Date Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
DateParam param = new DateParam();
|
||||
param.setMissing(false);
|
||||
params.put(Patient.SP_BIRTHDATE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
DateParam param = new DateParam();
|
||||
param.setMissing(true);
|
||||
params.put(Patient.SP_BIRTHDATE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingReference() {
|
||||
IIdType orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||
patient.setBirthDate(new DateDt("2011-01-01"));
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
notMissing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Reference Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
ReferenceParam param = new ReferenceParam();
|
||||
param.setMissing(false);
|
||||
params.put(Patient.SP_ORGANIZATION, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
ReferenceParam param = new ReferenceParam();
|
||||
param.setMissing(true);
|
||||
params.put(Patient.SP_ORGANIZATION, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
assertThat(patients, not(containsInRelativeOrder(orgId)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchStringParamWithNonNormalized() {
|
||||
{
|
||||
|
@ -2046,6 +1962,221 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingDate() {
|
||||
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||
patient.setBirthDate(new DateDt("2011-01-01"));
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
notMissing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Date Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
DateParam param = new DateParam();
|
||||
param.setMissing(false);
|
||||
params.put(Patient.SP_BIRTHDATE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
DateParam param = new DateParam();
|
||||
param.setMissing(true);
|
||||
params.put(Patient.SP_BIRTHDATE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingQuantity() {
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
obs.setValue(new QuantityDt(123));
|
||||
notMissing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Quantity Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
QuantityParam param = new QuantityParam();
|
||||
param.setMissing(false);
|
||||
params.put(Observation.SP_VALUE_QUANTITY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
QuantityParam param = new QuantityParam();
|
||||
param.setMissing(true);
|
||||
params.put(Observation.SP_VALUE_QUANTITY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingReference() {
|
||||
IIdType orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||
patient.setBirthDate(new DateDt("2011-01-01"));
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
notMissing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Reference Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
ReferenceParam param = new ReferenceParam();
|
||||
param.setMissing(false);
|
||||
params.put(Patient.SP_ORGANIZATION, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
ReferenceParam param = new ReferenceParam();
|
||||
param.setMissing(true);
|
||||
params.put(Patient.SP_ORGANIZATION, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
assertThat(patients, not(containsInRelativeOrder(orgId)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissingString() {
|
||||
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("Tester_testSearchStringParam").addGiven("John");
|
||||
patient.setBirthDate(new DateDt("2011-01-01"));
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
notMissing = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// String Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
StringParam param = new StringParam();
|
||||
param.setMissing(false);
|
||||
params.put(Patient.SP_FAMILY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
StringParam param = new StringParam();
|
||||
param.setMissing(true);
|
||||
params.put(Patient.SP_FAMILY, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithNoResults() {
|
||||
Device dev = new Device();
|
||||
dev.addIdentifier().setSystem("Foo");
|
||||
ourDeviceDao.create(dev);
|
||||
|
||||
IBundleProvider value = ourDeviceDao.search(new SearchParameterMap());
|
||||
ourLog.info("Initial size: " + value.size());
|
||||
for (IBaseResource next : value.getResources(0, value.size())) {
|
||||
ourLog.info("Deleting: {}", next.getIdElement());
|
||||
ourDeviceDao.delete((IIdType) next.getIdElement());
|
||||
}
|
||||
|
||||
value = ourDeviceDao.search(new SearchParameterMap());
|
||||
if (value.size() > 0) {
|
||||
ourLog.info("Found: " + (value.getResources(0, 1).get(0).getIdElement()));
|
||||
fail(ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(value.getResources(0, 1).get(0)));
|
||||
}
|
||||
assertEquals(0, value.size());
|
||||
|
||||
List<IBaseResource> res = value.getResources(0, 0);
|
||||
assertTrue(res.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithToken() {
|
||||
IIdType notMissing;
|
||||
IIdType missing;
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
missing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
Observation obs = new Observation();
|
||||
obs.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
obs.getCode().addCoding().setSystem("urn:system").setCode("002");
|
||||
notMissing = ourObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
// Token Param
|
||||
{
|
||||
HashMap<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
TokenParam param = new TokenParam();
|
||||
param.setMissing(false);
|
||||
params.put(Observation.SP_CODE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||
}
|
||||
{
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
TokenParam param = new TokenParam();
|
||||
param.setMissing(true);
|
||||
params.put(Observation.SP_CODE, param);
|
||||
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByDate() {
|
||||
Patient p = new Patient();
|
||||
|
@ -2148,6 +2279,67 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
assertThat(actual, contains(id4, id3, id2, id1, idMethodName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByReference() {
|
||||
String methodName = "testSortByReference";
|
||||
|
||||
Organization o1 = new Organization();
|
||||
IIdType oid1 = ourOrganizationDao.create(o1).getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization o2 = new Organization();
|
||||
IIdType oid2 = ourOrganizationDao.create(o2).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||
p.getManagingOrganization().setReference(oid1);
|
||||
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||
p.getManagingOrganization().setReference(oid2);
|
||||
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||
p.getManagingOrganization().setReference(oid1);
|
||||
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.getManagingOrganization().setReference(oid2);
|
||||
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm;
|
||||
List<IIdType> actual;
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_ORGANIZATION));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual.subList(0, 2), containsInAnyOrder(id1, id3));
|
||||
assertThat(actual.subList(2, 4), containsInAnyOrder(id2, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_ORGANIZATION).setOrder(SortOrderEnum.ASC));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual.subList(0, 2), containsInAnyOrder(id1, id3));
|
||||
assertThat(actual.subList(2, 4), containsInAnyOrder(id2, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_ORGANIZATION).setOrder(SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual.subList(0, 2), containsInAnyOrder(id2, id4));
|
||||
assertThat(actual.subList(2, 4), containsInAnyOrder(id1, id3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByString() {
|
||||
Patient p = new Patient();
|
||||
|
@ -2195,67 +2387,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
assertThat(actual, contains(id3, id2, id1, id4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByReference() {
|
||||
String methodName = "testSortByReference";
|
||||
|
||||
Organization o1 = new Organization();
|
||||
IIdType oid1 = ourOrganizationDao.create(o1).getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization o2 = new Organization();
|
||||
IIdType oid2 = ourOrganizationDao.create(o2).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||
p.getManagingOrganization().setReference(oid1);
|
||||
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||
p.getManagingOrganization().setReference(oid2);
|
||||
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||
p.getManagingOrganization().setReference(oid1);
|
||||
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.getManagingOrganization().setReference(oid2);
|
||||
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm;
|
||||
List<IIdType> actual;
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_ORGANIZATION));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual.subList(0, 2), containsInAnyOrder(id1, id3));
|
||||
assertThat(actual.subList(2, 4), containsInAnyOrder(id2, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_ORGANIZATION).setOrder(SortOrderEnum.ASC));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual.subList(0, 2), containsInAnyOrder(id1, id3));
|
||||
assertThat(actual.subList(2, 4), containsInAnyOrder(id2, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_ORGANIZATION).setOrder(SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(ourPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual.subList(0, 2), containsInAnyOrder(id2, id4));
|
||||
assertThat(actual.subList(2, 4), containsInAnyOrder(id1, id3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreUnversionedResources() {
|
||||
Organization o1 = new Organization();
|
||||
|
@ -2508,7 +2639,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
assertEquals(published, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(1)));
|
||||
assertEquals(updated, ResourceMetadataKeyEnum.UPDATED.get((IResource) history.get(1)));
|
||||
assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue());
|
||||
assertEquals(published2, ResourceMetadataKeyEnum.PUBLISHED.get( (IResource) history.get(0)));
|
||||
assertEquals(published2, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(0)));
|
||||
assertEquals(updated2, ResourceMetadataKeyEnum.UPDATED.get((IResource) history.get(0)));
|
||||
assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue());
|
||||
|
||||
|
@ -2683,29 +2814,4 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
|||
FhirSystemDaoDstu2Test.doDeleteEverything(ourSystemDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithNoResults() {
|
||||
Device dev = new Device();
|
||||
dev.addIdentifier().setSystem("Foo");
|
||||
ourDeviceDao.create(dev);
|
||||
|
||||
IBundleProvider value = ourDeviceDao.search(new SearchParameterMap());
|
||||
ourLog.info("Initial size: " + value.size());
|
||||
for (IBaseResource next : value.getResources(0, value.size())) {
|
||||
ourLog.info("Deleting: {}", next.getIdElement());
|
||||
ourDeviceDao.delete((IIdType) next.getIdElement());
|
||||
}
|
||||
|
||||
value = ourDeviceDao.search(new SearchParameterMap());
|
||||
if (value.size() > 0) {
|
||||
ourLog.info("Found: " + (value.getResources(0, 1).get(0).getIdElement()));
|
||||
fail(ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(value.getResources(0, 1).get(0)));
|
||||
}
|
||||
assertEquals(0, value.size());
|
||||
|
||||
List<IBaseResource> res = value.getResources(0, 0);
|
||||
assertTrue(res.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -989,6 +989,53 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdateResourceWithPrefer() throws IOException, Exception {
|
||||
String methodName = "testUpdateResourceWithPrefer";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
String resource = ourCtx.newXmlParser().encodeResourceToString(pt);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient");
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
IdDt id;
|
||||
try {
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue();
|
||||
assertThat(newIdString, startsWith(ourServerBase + "/Patient/"));
|
||||
id = new IdDt(newIdString);
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
Date before = new Date();
|
||||
Thread.sleep(100);
|
||||
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient/" + id.getIdPart());
|
||||
put.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RETURN + '=' + Constants.HEADER_PREFER_RETURN_REPRESENTATION);
|
||||
put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
response = ourHttpClient.execute(put);
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
|
||||
Patient respPt = ourCtx.newXmlParser().parseResource(Patient.class, responseString);
|
||||
assertEquals("2", respPt.getId().getVersionIdPart());
|
||||
|
||||
InstantDt updateTime = ResourceMetadataKeyEnum.UPDATED.get(respPt);
|
||||
assertTrue(updateTime.getValue().after(before));
|
||||
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdateWithClientSuppliedIdWhichDoesntExist() {
|
||||
|
@ -1036,6 +1083,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testValidateResourceWithId() throws IOException {
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import java.util.regex.Matcher;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
|
||||
public class RestfulServerUtilsTest {
|
||||
|
||||
@Test
|
||||
|
@ -28,4 +30,31 @@ public class RestfulServerUtilsTest {
|
|||
assertEquals("application/json+fhir", m.group(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParsePreferHeaderBad() {
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader(null));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader(""));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("foo"));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("foo,bar"));
|
||||
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return"));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return="));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return= "));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return= "));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return= "));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return= "));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return= "));
|
||||
assertEquals(null, RestfulServerUtils.parsePreferHeader("return =\"minimal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParsePreferHeaderGood() {
|
||||
assertEquals(PreferReturnEnum.MINIMAL, RestfulServerUtils.parsePreferHeader("return=minimal"));
|
||||
assertEquals(PreferReturnEnum.REPRESENTATION, RestfulServerUtils.parsePreferHeader("return=representation"));
|
||||
assertEquals(PreferReturnEnum.MINIMAL, RestfulServerUtils.parsePreferHeader("return = minimal "));
|
||||
assertEquals(PreferReturnEnum.MINIMAL, RestfulServerUtils.parsePreferHeader("return = \"minimal\" "));
|
||||
assertEquals(PreferReturnEnum.MINIMAL, RestfulServerUtils.parsePreferHeader("return =\"minimal\""));
|
||||
assertEquals(PreferReturnEnum.MINIMAL, RestfulServerUtils.parsePreferHeader("return =\"minimal\""));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
|
|||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.XmlParserDstu2Test;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -178,6 +179,65 @@ public class GenericClientDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePrefer() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
client.create().resource(p).prefer(PreferReturnEnum.MINIMAL).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER).length);
|
||||
assertEquals(Constants.HEADER_PREFER_RETURN + '=' + Constants.HEADER_PREFER_RETURN_MINIMAL, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER)[0].getValue());
|
||||
idx++;
|
||||
|
||||
client.create().resource(p).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER).length);
|
||||
assertEquals(Constants.HEADER_PREFER_RETURN + '=' + Constants.HEADER_PREFER_RETURN_REPRESENTATION, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER)[0].getValue());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateReturningResourceBody() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.setId("123");
|
||||
final String formatted = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), Constants.STATUS_HTTP_200_OK, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(formatted), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
p = new Patient();
|
||||
p.setId(new IdDt("1"));
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
MethodOutcome output = client.create().resource(p).execute();
|
||||
assertNotNull(output.getResource());
|
||||
assertEquals("Patient/123", output.getResource().getIdElement().toUnqualifiedVersionless().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteConditional() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -268,56 +328,6 @@ public class GenericClientDstu2Test {
|
|||
idx++;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReadUpdatedHeaderDoesntOverwriteResourceValue() throws Exception {
|
||||
|
||||
//@formatter:off
|
||||
final String input = "<Bundle xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
" <id value=\"e2ee823b-ee4d-472d-b79d-495c23f16b99\"/>\n" +
|
||||
" <meta>\n" +
|
||||
" <lastUpdated value=\"2015-06-22T15:48:57.554-04:00\"/>\n" +
|
||||
" </meta>\n" +
|
||||
" <type value=\"searchset\"/>\n" +
|
||||
" <base value=\"http://localhost:58109/fhir/context\"/>\n" +
|
||||
" <total value=\"0\"/>\n" +
|
||||
" <link>\n" +
|
||||
" <relation value=\"self\"/>\n" +
|
||||
" <url value=\"http://localhost:58109/fhir/context/Patient?_pretty=true\"/>\n" +
|
||||
" </link>\n" +
|
||||
"</Bundle>";
|
||||
//@formatter:on
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] {
|
||||
new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Sat, 20 Jun 2015 19:32:17 GMT")
|
||||
});
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(input), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response;
|
||||
|
||||
//@formatter:off
|
||||
response = client
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("2015-06-22T15:48:57.554-04:00", ResourceMetadataKeyEnum.UPDATED.get(response).getValueAsString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOperationAsGetWithInParameters() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
@ -401,7 +411,7 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION?param1=STRINGVALIN1¶m1=STRINGVALIN1b¶m2=STRINGVALIN2", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOperationAsGetWithNoInParameters() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
@ -483,13 +493,9 @@ public class GenericClientDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testOperationWithBundleResponseJson() throws Exception {
|
||||
|
||||
final String resp = "{\n" +
|
||||
" \"resourceType\":\"Bundle\",\n" +
|
||||
" \"id\":\"8cef5f2a-0ba9-43a5-be26-c8dde9ff0e19\",\n" +
|
||||
" \"base\":\"http://fhirtest.uhn.ca/baseDstu2\"\n" +
|
||||
"}";
|
||||
|
||||
|
||||
final String resp = "{\n" + " \"resourceType\":\"Bundle\",\n" + " \"id\":\"8cef5f2a-0ba9-43a5-be26-c8dde9ff0e19\",\n" + " \"base\":\"http://fhirtest.uhn.ca/baseDstu2\"\n" + "}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
|
@ -502,7 +508,7 @@ public class GenericClientDstu2Test {
|
|||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Create the input parameters to pass to the server
|
||||
|
@ -829,40 +835,52 @@ public class GenericClientDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #191
|
||||
*/
|
||||
@Test
|
||||
public void testSearchReturningDstu2Bundle() throws Exception {
|
||||
String msg =IOUtils.toString(XmlParserDstu2Test.class.getResourceAsStream("/bundle_orion.xml"));
|
||||
public void testReadUpdatedHeaderDoesntOverwriteResourceValue() throws Exception {
|
||||
|
||||
//@formatter:off
|
||||
final String input = "<Bundle xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
" <id value=\"e2ee823b-ee4d-472d-b79d-495c23f16b99\"/>\n" +
|
||||
" <meta>\n" +
|
||||
" <lastUpdated value=\"2015-06-22T15:48:57.554-04:00\"/>\n" +
|
||||
" </meta>\n" +
|
||||
" <type value=\"searchset\"/>\n" +
|
||||
" <base value=\"http://localhost:58109/fhir/context\"/>\n" +
|
||||
" <total value=\"0\"/>\n" +
|
||||
" <link>\n" +
|
||||
" <relation value=\"self\"/>\n" +
|
||||
" <url value=\"http://localhost:58109/fhir/context/Patient?_pretty=true\"/>\n" +
|
||||
" </link>\n" +
|
||||
"</Bundle>";
|
||||
//@formatter:on
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML+ "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Sat, 20 Jun 2015 19:32:17 GMT") });
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(input), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response;
|
||||
|
||||
//@formatter:off
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response = client.search()
|
||||
.forResource("Observation")
|
||||
.where(Patient.NAME.matches().value("FOO"))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
response = client
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
Link link = response.getLink().get(0);
|
||||
assertEquals("just trying add link", link.getRelation());
|
||||
assertEquals("blarion", link.getUrl());
|
||||
|
||||
Entry entry = response.getEntry().get(0);
|
||||
link = entry.getLink().get(0);
|
||||
assertEquals("orionhealth.edit", link.getRelation());
|
||||
assertEquals("Observation", link.getUrl());
|
||||
assertEquals("2015-06-22T15:48:57.554-04:00", ResourceMetadataKeyEnum.UPDATED.get(response).getValueAsString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchByString() throws Exception {
|
||||
String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
@ -887,6 +905,38 @@ public class GenericClientDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #191
|
||||
*/
|
||||
@Test
|
||||
public void testSearchReturningDstu2Bundle() throws Exception {
|
||||
String msg = IOUtils.toString(XmlParserDstu2Test.class.getResourceAsStream("/bundle_orion.xml"));
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
//@formatter:off
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response = client.search()
|
||||
.forResource("Observation")
|
||||
.where(Patient.NAME.matches().value("FOO"))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
Link link = response.getLink().get(0);
|
||||
assertEquals("just trying add link", link.getRelation());
|
||||
assertEquals("blarion", link.getUrl());
|
||||
|
||||
Entry entry = response.getEntry().get(0);
|
||||
link = entry.getLink().get(0);
|
||||
assertEquals("orionhealth.edit", link.getRelation());
|
||||
assertEquals("Observation", link.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithLastUpdated() throws Exception {
|
||||
String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
@ -1142,45 +1192,63 @@ public class GenericClientDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testValidateNonFluent() throws Exception {
|
||||
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().setDetails("FOOBAR");
|
||||
final String msg = ourCtx.newXmlParser().encodeResourceToString(oo);
|
||||
|
||||
public void testUpdatePrefer() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addGiven("GIVEN");
|
||||
|
||||
int idx = 0;
|
||||
MethodOutcome response;
|
||||
|
||||
//@formatter:off
|
||||
response = client.validate(p);
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||
Patient p = new Patient();
|
||||
p.setId(new IdDt("1"));
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
client.update().resource(p).prefer(PreferReturnEnum.MINIMAL).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER).length);
|
||||
assertEquals(Constants.HEADER_PREFER_RETURN + '=' + Constants.HEADER_PREFER_RETURN_MINIMAL, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER)[0].getValue());
|
||||
idx++;
|
||||
|
||||
client.update().resource(p).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER).length);
|
||||
assertEquals(Constants.HEADER_PREFER_RETURN + '=' + Constants.HEADER_PREFER_RETURN_REPRESENTATION, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_PREFER)[0].getValue());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
private OperationOutcome toOo(IBaseOperationOutcome theOperationOutcome) {
|
||||
return (OperationOutcome) theOperationOutcome;
|
||||
@Test
|
||||
public void testUpdateReturningResourceBody() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.setId("123");
|
||||
final String formatted = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), Constants.STATUS_HTTP_200_OK, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(formatted), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
p = new Patient();
|
||||
p.setId(new IdDt("1"));
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
MethodOutcome output = client.update().resource(p).execute();
|
||||
assertNotNull(output.getResource());
|
||||
assertEquals("Patient/123", output.getResource().getIdElement().toUnqualifiedVersionless().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1205,14 +1273,16 @@ public class GenericClientDstu2Test {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addName().addGiven("GIVEN");
|
||||
|
||||
|
||||
int idx = 0;
|
||||
MethodOutcome response;
|
||||
|
||||
response = client.validate().resource(p).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
|
@ -1220,7 +1290,9 @@ public class GenericClientDstu2Test {
|
|||
response = client.validate().resource(ourCtx.newXmlParser().encodeResourceToString(p)).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate?_format=xml", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
|
@ -1242,6 +1314,50 @@ public class GenericClientDstu2Test {
|
|||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateNonFluent() throws Exception {
|
||||
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().setDetails("FOOBAR");
|
||||
final String msg = ourCtx.newXmlParser().encodeResourceToString(oo);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addGiven("GIVEN");
|
||||
|
||||
int idx = 0;
|
||||
MethodOutcome response;
|
||||
|
||||
//@formatter:off
|
||||
response = client.validate(p);
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
}
|
||||
|
||||
private OperationOutcome toOo(IBaseOperationOutcome theOperationOutcome) {
|
||||
return (OperationOutcome) theOperationOutcome;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forDstu2();
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.emptyOrNullString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isEmptyOrNullString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -30,9 +36,6 @@ import ca.uhn.fhir.rest.annotation.Update;
|
|||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class PreferTest {
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
||||
|
@ -65,6 +68,55 @@ public class PreferTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreatePreferMinimal() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RETURN + "=" + Constants.HEADER_PREFER_RETURN_MINIMAL);
|
||||
httpPost.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(Constants.STATUS_HTTP_201_CREATED, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, is(emptyOrNullString()));
|
||||
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), not(containsString("fhir")));
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("location").getValue());
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("content-location").getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePreferRepresentation() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.addHeader(Constants.HEADER_PREFER, Constants.HEADER_PREFER_RETURN + "=" + Constants.HEADER_PREFER_RETURN_REPRESENTATION);
|
||||
httpPost.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(Constants.STATUS_HTTP_201_CREATED, status.getStatusLine().getStatusCode());
|
||||
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"001\"/><meta><versionId value=\"002\"/></meta></Patient>", responseContent);
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("location").getValue());
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("content-location").getValue());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
|
@ -104,13 +156,26 @@ public class PreferTest {
|
|||
|
||||
@Create()
|
||||
public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
||||
MethodOutcome retVal = new MethodOutcome(new IdDt("Patient/001/_history/002"));
|
||||
IdDt id = new IdDt("Patient/001/_history/002");
|
||||
MethodOutcome retVal = new MethodOutcome(id);
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId(id);
|
||||
retVal.setResource(pt);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Update()
|
||||
public MethodOutcome updatePatient(@ResourceParam Patient thePatient, @IdParam IdDt theIdParam) {
|
||||
return new MethodOutcome(new IdDt("Patient/001/_history/002"));
|
||||
IdDt id = new IdDt("Patient/001/_history/002");
|
||||
MethodOutcome retVal = new MethodOutcome(id);
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId(id);
|
||||
retVal.setResource(pt);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -137,6 +137,15 @@
|
|||
DSTU2 servers now indicate support for conditional create/update/delete in their
|
||||
conformance statement.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Support for the Prefer header has been added to the server, client, and
|
||||
JPA modules.
|
||||
</action>
|
||||
<action type="fix" issue="196">
|
||||
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!
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.0" date="2015-May-8">
|
||||
<action type="add">
|
||||
|
|
|
@ -157,6 +157,10 @@ DIV.main-body DIV.row DIV.span8 DIV.body-content {
|
|||
background-color: #F8F8F8 !important;
|
||||
}
|
||||
|
||||
.syntaxhighlighter .code .container:before {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.table th, .table td {
|
||||
padding: 2px;
|
||||
}
|
||||
|
|
|
@ -127,8 +127,8 @@
|
|||
</menu>
|
||||
|
||||
<menu name="Get Help" inherit="top">
|
||||
<item name="Google Group" href="https://groups.google.com/d/forum/hapi-fhir" />
|
||||
<item name="Issue Tracker" href="https://github.com/jamesagnew/hapi-fhir/issues" />
|
||||
<item name="Google Group (Ask Questions)" href="https://groups.google.com/d/forum/hapi-fhir" />
|
||||
<item name="Issue Tracker (Report Bugs/Request Features)" href="https://github.com/jamesagnew/hapi-fhir/issues" />
|
||||
</menu>
|
||||
|
||||
<menu name="Test Server">
|
||||
|
|
|
@ -195,6 +195,29 @@
|
|||
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<a name="prefer"/>
|
||||
<h4>Prefer Header / Returning the resource body</h4>
|
||||
<p>
|
||||
If you want to allow clients to request that the server return
|
||||
the resource body as a result of the transaction, you may wish to
|
||||
return the updated resource in the returned MethodOutcome.
|
||||
</p>
|
||||
<p>
|
||||
In this type of request, the client adds a header containing
|
||||
<code>Prefer: return=representation</code> which indicates to the server
|
||||
that the client would like the resource returned in the response.
|
||||
</p>
|
||||
<p>
|
||||
In order for the server to be able to honour this request, the
|
||||
server method should add the updated resource to the MethodOutcome object
|
||||
being returned, as shown in the example below.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="updatePrefer" />
|
||||
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<a name="instance_delete" />
|
||||
</section>
|
||||
|
||||
|
@ -357,6 +380,13 @@
|
|||
<code>http://fhir.example.com/Patient<br/>If-None-Exist: Patient?identifier=system%7C0001</code>
|
||||
</p>
|
||||
|
||||
<h4>Prefer Header / Returning the resource body</h4>
|
||||
<p>
|
||||
If you wish to allow your server to honour the <code>Prefer</code>
|
||||
header, the same mechanism shown above for
|
||||
<a href="#prefer">Prefer Header for Updates</a> should be used.
|
||||
</p>
|
||||
|
||||
<h4>Accessing The Raw Resource Payload</h4>
|
||||
<p>
|
||||
The create operation also supports access to the raw payload,
|
||||
|
|
Loading…
Reference in New Issue