Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
f818a3b478
|
@ -245,7 +245,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest());
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest(), theServer.getDefaultResponseEncoding());
|
||||
|
||||
// Is this request coming from a browser
|
||||
String uaHeader = theRequest.getServletRequest().getHeader("user-agent");
|
||||
|
|
|
@ -54,7 +54,7 @@ public class Constants {
|
|||
public static final String FORMAT_XML = "xml";
|
||||
public static final String HEADER_ACCEPT = "Accept";
|
||||
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
||||
public static final String HEADER_ACCEPT_VALUE_ALL = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_XML + ";q=1.0";
|
||||
public static final String HEADER_ACCEPT_VALUE_ALL = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
||||
public static final String HEADER_ALLOW = "Allow";
|
||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
||||
|
|
|
@ -491,7 +491,7 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
int start = Math.min(offsetI, resultList.size() - 1);
|
||||
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest());
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest(), getDefaultResponseEncoding());
|
||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(this, theRequest);
|
||||
boolean requestIsBrowser = requestIsBrowser(theRequest.getServletRequest());
|
||||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
|
||||
|
|
|
@ -214,7 +214,11 @@ public class RestfulServerUtils {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static EncodingEnum determineResponseEncodingNoDefault(HttpServletRequest theReq) {
|
||||
/**
|
||||
* Returns null if the request doesn't express that it wants FHIR. If it expresses that it wants
|
||||
* XML and JSON equally, returns thePrefer.
|
||||
*/
|
||||
public static EncodingEnum determineResponseEncodingNoDefault(HttpServletRequest theReq, EncodingEnum thePrefer) {
|
||||
String[] format = theReq.getParameterValues(Constants.PARAM_FORMAT);
|
||||
if (format != null) {
|
||||
for (String nextFormat : format) {
|
||||
|
@ -236,37 +240,106 @@ public class RestfulServerUtils {
|
|||
EncodingEnum retVal = null;
|
||||
while (acceptValues.hasMoreElements()) {
|
||||
String nextAcceptHeaderValue = acceptValues.nextElement();
|
||||
Matcher m = ACCEPT_HEADER_PATTERN.matcher(nextAcceptHeaderValue);
|
||||
float q = 1.0f;
|
||||
while (m.find()) {
|
||||
String contentTypeGroup = m.group(1);
|
||||
EncodingEnum encoding = Constants.FORMAT_VAL_TO_ENCODING.get(contentTypeGroup);
|
||||
if (encoding != null) {
|
||||
|
||||
String name = m.group(3);
|
||||
String value = m.group(4);
|
||||
if (name != null && value != null) {
|
||||
if ("q".equals(name)) {
|
||||
try {
|
||||
q = Float.parseFloat(value);
|
||||
q = Math.max(q, 0.0f);
|
||||
} catch (NumberFormatException e) {
|
||||
ourLog.debug("Invalid Accept header q value: {}", value);
|
||||
StringTokenizer tok = new StringTokenizer(nextAcceptHeaderValue, ",");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String nextToken = tok.nextToken();
|
||||
int startSpaceIndex = -1;
|
||||
for (int i = 0; i < nextToken.length(); i++) {
|
||||
if (nextToken.charAt(i) != ' ') {
|
||||
startSpaceIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (startSpaceIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int endSpaceIndex = -1;
|
||||
for (int i = startSpaceIndex; i < nextToken.length(); i++) {
|
||||
if (nextToken.charAt(i) == ' ' || nextToken.charAt(i) == ';') {
|
||||
endSpaceIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float q = 1.0f;
|
||||
EncodingEnum encoding;
|
||||
boolean pretty = false;
|
||||
if (endSpaceIndex == -1) {
|
||||
if (startSpaceIndex == 0) {
|
||||
encoding = Constants.FORMAT_VAL_TO_ENCODING.get(nextToken);
|
||||
} else {
|
||||
encoding = Constants.FORMAT_VAL_TO_ENCODING.get(nextToken.substring(startSpaceIndex));
|
||||
}
|
||||
} else {
|
||||
encoding = Constants.FORMAT_VAL_TO_ENCODING.get(nextToken.substring(startSpaceIndex, endSpaceIndex));
|
||||
String remaining = nextToken.substring(endSpaceIndex + 1);
|
||||
StringTokenizer qualifierTok = new StringTokenizer(remaining, ";");
|
||||
while (qualifierTok.hasMoreTokens()) {
|
||||
String nextQualifier = qualifierTok.nextToken();
|
||||
int equalsIndex = nextQualifier.indexOf('=');
|
||||
if (equalsIndex != -1) {
|
||||
String nextQualifierKey = nextQualifier.substring(0, equalsIndex).trim();
|
||||
String nextQualifierValue = nextQualifier.substring(equalsIndex+1, nextQualifier.length()).trim();
|
||||
if (nextQualifierKey.equals("q")) {
|
||||
try {
|
||||
q = Float.parseFloat(nextQualifierValue);
|
||||
q = Math.max(q, 0.0f);
|
||||
} catch (NumberFormatException e) {
|
||||
ourLog.debug("Invalid Accept header q value: {}", nextQualifierValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (q > bestQ && encoding != null) {
|
||||
retVal = encoding;
|
||||
bestQ = q;
|
||||
}
|
||||
|
||||
if (!",".equals(m.group(5))) {
|
||||
break;
|
||||
if (encoding != null) {
|
||||
if (q > bestQ || (q == bestQ && encoding == thePrefer)) {
|
||||
retVal = encoding;
|
||||
bestQ = q;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// Matcher m = ACCEPT_HEADER_PATTERN.matcher(nextAcceptHeaderValue);
|
||||
// float q = 1.0f;
|
||||
// while (m.find()) {
|
||||
// String contentTypeGroup = m.group(1);
|
||||
// EncodingEnum encoding = Constants.FORMAT_VAL_TO_ENCODING.get(contentTypeGroup);
|
||||
// if (encoding != null) {
|
||||
//
|
||||
// String name = m.group(3);
|
||||
// String value = m.group(4);
|
||||
// if (name != null && value != null) {
|
||||
// if ("q".equals(name)) {
|
||||
// try {
|
||||
// q = Float.parseFloat(value);
|
||||
// q = Math.max(q, 0.0f);
|
||||
// } catch (NumberFormatException e) {
|
||||
// ourLog.debug("Invalid Accept header q value: {}", value);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (encoding != null) {
|
||||
// if (q > bestQ || (q == bestQ && encoding == thePrefer)) {
|
||||
// retVal = encoding;
|
||||
// bestQ = q;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!",".equals(m.group(5))) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
@ -278,7 +351,7 @@ public class RestfulServerUtils {
|
|||
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
|
||||
*/
|
||||
public static EncodingEnum determineResponseEncodingWithDefault(RestfulServer theServer, HttpServletRequest theReq) {
|
||||
EncodingEnum retVal = determineResponseEncodingNoDefault(theReq);
|
||||
EncodingEnum retVal = determineResponseEncodingNoDefault(theReq, theServer.getDefaultResponseEncoding());
|
||||
if (retVal == null) {
|
||||
retVal = theServer.getDefaultResponseEncoding();
|
||||
}
|
||||
|
@ -328,10 +401,7 @@ public class RestfulServerUtils {
|
|||
public static IParser getNewParser(FhirContext theContext, RequestDetails theRequestDetails) {
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
if (responseEncoding == null) {
|
||||
responseEncoding = theRequestDetails.getServer().getDefaultResponseEncoding();
|
||||
}
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingWithDefault(theRequestDetails.getServer(), theRequestDetails.getServletRequest());
|
||||
IParser parser;
|
||||
switch (responseEncoding) {
|
||||
case JSON:
|
||||
|
@ -472,8 +542,7 @@ public class RestfulServerUtils {
|
|||
theHttpResponse.setStatus(200);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
responseEncoding = responseEncoding != null ? responseEncoding : theServer.getDefaultResponseEncoding();
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingWithDefault(theServer, theRequestDetails.getServletRequest());
|
||||
|
||||
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
|
||||
theHttpResponse.setContentType(responseEncoding.getBrowserFriendlyBundleContentType());
|
||||
|
@ -502,7 +571,7 @@ public class RestfulServerUtils {
|
|||
theHttpResponse.setStatus(stausCode);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest(), theServer.getDefaultResponseEncoding());
|
||||
|
||||
String serverBase = theRequestDetails.getFhirServerBase();
|
||||
if (theAddContentLocationHeader && theResource.getIdElement() != null && theResource.getIdElement().hasIdPart() && isNotBlank(serverBase)) {
|
||||
|
|
|
@ -198,7 +198,7 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
} else if (theKey.startsWith("remoteAddr")) {
|
||||
return StringUtils.defaultString(myRequest.getRemoteAddr());
|
||||
} else if (theKey.equals("responseEncodingNoDefault")) {
|
||||
EncodingEnum encoding = RestfulServerUtils.determineResponseEncodingNoDefault(myRequest);
|
||||
EncodingEnum encoding = RestfulServerUtils.determineResponseEncodingNoDefault(myRequest, myRequestDetails.getServer().getDefaultResponseEncoding());
|
||||
if (encoding != null) {
|
||||
return encoding.name();
|
||||
} else {
|
||||
|
|
|
@ -224,6 +224,7 @@
|
|||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>javax.el-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
|
|
|
@ -54,7 +54,6 @@ import javax.persistence.criteria.Predicate;
|
|||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.Subquery;
|
||||
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -306,7 +305,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
return retVal;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -320,7 +320,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
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) {
|
||||
|
@ -1110,7 +1111,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
}
|
||||
|
||||
private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder, From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
|
||||
private Predicate createPredicateString(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
|
||||
From<ResourceIndexedSearchParamString, ResourceIndexedSearchParamString> theFrom) {
|
||||
String rawSearchTerm;
|
||||
if (theParameter instanceof TokenParam) {
|
||||
TokenParam id = (TokenParam) theParameter;
|
||||
|
@ -1129,7 +1131,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has length (" + rawSearchTerm.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
|
||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has length (" + rawSearchTerm.length() + ") that is longer than maximum allowed ("
|
||||
+ ResourceIndexedSearchParamString.MAX_LENGTH + "): " + rawSearchTerm);
|
||||
}
|
||||
|
||||
String likeExpression = normalizeString(rawSearchTerm);
|
||||
|
@ -1143,7 +1146,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
return singleCode;
|
||||
}
|
||||
|
||||
private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder, From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> theFrom) {
|
||||
private Predicate createPredicateToken(IQueryParameterType theParameter, String theParamName, CriteriaBuilder theBuilder,
|
||||
From<ResourceIndexedSearchParamToken, ResourceIndexedSearchParamToken> theFrom) {
|
||||
String code;
|
||||
String system;
|
||||
if (theParameter instanceof TokenParam) {
|
||||
|
@ -1163,10 +1167,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
if (system != null && system.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
|
||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has system (" + system.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + system);
|
||||
throw new InvalidRequestException(
|
||||
"Parameter[" + theParamName + "] has system (" + system.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + system);
|
||||
}
|
||||
if (code != null && code.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
|
||||
throw new InvalidRequestException("Parameter[" + theParamName + "] has code (" + code.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + code);
|
||||
throw new InvalidRequestException(
|
||||
"Parameter[" + theParamName + "] has code (" + code.length() + ") that is longer than maximum allowed (" + ResourceIndexedSearchParamToken.MAX_LENGTH + "): " + code);
|
||||
}
|
||||
|
||||
ArrayList<Predicate> singleCodePredicates = (new ArrayList<Predicate>());
|
||||
|
@ -1220,23 +1226,39 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
String joinAttrName;
|
||||
String sortAttrName;
|
||||
String[] sortAttrName;
|
||||
|
||||
switch (param.getParamType()) {
|
||||
case STRING:
|
||||
joinAttrName = "myParamsString";
|
||||
sortAttrName = "myValueExact";
|
||||
sortAttrName = new String[] { "myValueExact" };
|
||||
break;
|
||||
case DATE:
|
||||
joinAttrName = "myParamsDate";
|
||||
sortAttrName = "myValueLow";
|
||||
sortAttrName = new String[] { "myValueLow" };
|
||||
break;
|
||||
case REFERENCE:
|
||||
joinAttrName = "myResourceLinks";
|
||||
sortAttrName = "myTargetResourcePid";
|
||||
sortAttrName = new String[] { "myTargetResourcePid" };
|
||||
break;
|
||||
case TOKEN:
|
||||
joinAttrName = "myParamsToken";
|
||||
sortAttrName = new String[] { "mySystem", "myValue" };
|
||||
break;
|
||||
case NUMBER:
|
||||
joinAttrName = "myParamsNumber";
|
||||
sortAttrName = new String[] { "myValue" };
|
||||
break;
|
||||
case URI:
|
||||
joinAttrName = "myParamsUri";
|
||||
sortAttrName = new String[] { "myUri" };
|
||||
break;
|
||||
case QUANTITY:
|
||||
joinAttrName = "myParamsQuantity";
|
||||
sortAttrName = new String[] { "myValue" };
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException("This server does not support _sort specifications of type " + param.getParamType() + " - Can't serve _sort=" + theSort.getParamName());
|
||||
throw new InvalidRequestException("This server does not support _sort specifications of type " + param.getParamType() + " - Can't serve _sort=" + theSort.getParamName());
|
||||
}
|
||||
|
||||
From<?, ?> stringJoin = theFrom.join(joinAttrName, JoinType.INNER);
|
||||
|
@ -1251,10 +1273,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
// Predicate pn = theBuilder.isNull(stringJoin.get("myParamName"));
|
||||
// thePredicates.add(theBuilder.or(p, pn));
|
||||
|
||||
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
||||
theOrders.add(theBuilder.asc(stringJoin.get(sortAttrName)));
|
||||
} else {
|
||||
theOrders.add(theBuilder.desc(stringJoin.get(sortAttrName)));
|
||||
for (String next : sortAttrName) {
|
||||
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
||||
theOrders.add(theBuilder.asc(stringJoin.get(next)));
|
||||
} else {
|
||||
theOrders.add(theBuilder.desc(stringJoin.get(next)));
|
||||
}
|
||||
}
|
||||
|
||||
createSort(theBuilder, theFrom, theSort.getChain(), theOrders, thePredicates);
|
||||
|
@ -1335,7 +1359,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
|
||||
if (isNotBlank(theResource.getId().getIdPart())) {
|
||||
if (isValidPid(theResource.getId())) {
|
||||
throw new UnprocessableEntityException("This server cannot create an entity with a user-specified numeric ID - Client should not specify an ID when creating a new resource, or should include at least one letter in the ID to force a client-defined ID");
|
||||
throw new UnprocessableEntityException(
|
||||
"This server cannot create an entity with a user-specified numeric ID - Client should not specify an ID when creating a new resource, or should include at least one letter in the ID to force a client-defined ID");
|
||||
}
|
||||
createForcedIdIfNeeded(entity, theResource.getId());
|
||||
|
||||
|
@ -1869,7 +1894,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
|
||||
if (entity == null) {
|
||||
if (theId.hasVersionIdPart()) {
|
||||
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery("SELECT t from ResourceHistoryTable t WHERE t.myResourceId = :RID AND t.myResourceType = :RTYP AND t.myResourceVersion = :RVER", ResourceHistoryTable.class);
|
||||
TypedQuery<ResourceHistoryTable> q = myEntityManager
|
||||
.createQuery("SELECT t from ResourceHistoryTable t WHERE t.myResourceId = :RID AND t.myResourceType = :RTYP AND t.myResourceVersion = :RVER", ResourceHistoryTable.class);
|
||||
q.setParameter("RID", pid);
|
||||
q.setParameter("RTYP", myResourceName);
|
||||
q.setParameter("RVER", Long.parseLong(theId.getVersionIdPart()));
|
||||
|
@ -2047,7 +2073,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
revIncludedPids = new HashSet<Long>();
|
||||
}
|
||||
|
||||
ourLog.info("Search returned PIDs: {}", pids);
|
||||
ourLog.debug("Search returned PIDs: {}", pids);
|
||||
|
||||
final int totalCount = pids.size();
|
||||
|
||||
|
@ -2263,8 +2289,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
/**
|
||||
* If set, the given param will be treated as a secondary primary key, and multiple resources will not be able to
|
||||
* share the same value.
|
||||
* If set, the given param will be treated as a secondary primary key, and multiple resources will not be able to share the same value.
|
||||
*/
|
||||
public void setSecondaryPrimaryKeyParamName(String theSecondaryPrimaryKeyParamName) {
|
||||
mySecondaryPrimaryKeyParamName = theSecondaryPrimaryKeyParamName;
|
||||
|
@ -2397,7 +2422,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
if (resourceId.hasResourceType() && !resourceId.getResourceType().equals(getResourceName())) {
|
||||
throw new UnprocessableEntityException("Invalid resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] of type[" + entity.getResourceType() + "] - Does not match expected [" + getResourceName() + "]");
|
||||
throw new UnprocessableEntityException(
|
||||
"Invalid resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] of type[" + entity.getResourceType() + "] - Does not match expected [" + getResourceName() + "]");
|
||||
}
|
||||
|
||||
// Notify interceptors
|
||||
|
@ -2444,12 +2470,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
String sourceId = link.getSourceResource().getIdDt().toUnqualifiedVersionless().getValue();
|
||||
String sourcePath = link.getSourcePath();
|
||||
|
||||
throw new PreconditionFailedException("Unable to delete " + targetId + " because at least one resource has a reference to this resource. First reference found was resource " + sourceId + " in path " + sourcePath);
|
||||
throw new PreconditionFailedException(
|
||||
"Unable to delete " + targetId + " because at least one resource has a reference to this resource. First reference found was resource " + sourceId + " in path " + sourcePath);
|
||||
}
|
||||
|
||||
private void validateResourceType(BaseHasResource entity) {
|
||||
if (!myResourceName.equals(entity.getResourceType())) {
|
||||
throw new ResourceNotFoundException("Resource with ID " + entity.getIdDt().getIdPart() + " exists but it is not of type " + myResourceName + ", found resource of type " + entity.getResourceType());
|
||||
throw new ResourceNotFoundException(
|
||||
"Resource with ID " + entity.getIdDt().getIdPart() + " exists but it is not of type " + myResourceName + ", found resource of type " + entity.getResourceType());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.persistence.GeneratedValue;
|
|||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
|
@ -49,6 +50,7 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
|||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@SequenceGenerator(name = "RES_HISTORY_PID", sequenceName = "RES_HISTORY_PID")
|
||||
@Column(name = "PID")
|
||||
private Long myId;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
|||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ConceptMap;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Device;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
|
@ -87,6 +88,7 @@ import ca.uhn.fhir.rest.param.DateRangeParam;
|
|||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
@ -149,6 +151,38 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantSearchForDeletedResourceByLanguageOrTag() {
|
||||
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
|
||||
Organization org = new Organization();
|
||||
org.setLanguage(new CodeDt("EN_ca"));
|
||||
org.setName(methodName);
|
||||
|
||||
TagList tl = new TagList();
|
||||
tl.add(new Tag(methodName, methodName));
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put(org, tl);
|
||||
|
||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add("_language", new StringParam("EN_ca"));
|
||||
assertEquals(1, myOrganizationDao.search(map).size());
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_tag", new TokenParam(methodName, methodName));
|
||||
assertEquals(1, myOrganizationDao.search(map).size());
|
||||
|
||||
myOrganizationDao.delete(orgId);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_language", new StringParam("EN_ca"));
|
||||
assertEquals(0, myOrganizationDao.search(map).size());
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_tag", new TokenParam(methodName, methodName));
|
||||
assertEquals(0, myOrganizationDao.search(map).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChoiceParamConcept() {
|
||||
Observation o1 = new Observation();
|
||||
|
@ -163,71 +197,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithInvalid() {
|
||||
Observation o1 = new Observation();
|
||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||
o1.setValue(new CodeableConceptDt("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
||||
IIdType id1 = myObservationDao.create(o1).getId();
|
||||
|
||||
{
|
||||
IBundleProvider found = myObservationDao.search(Observation.SP_VALUE_CONCEPT, new TokenParam("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(id1, found.getResources(0, 1).get(0).getIdElement());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithIllegalReference() {
|
||||
Observation o1 = new Observation();
|
||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||
IIdType id1 = myObservationDao.create(o1).getId().toUnqualifiedVersionless();
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(id1);
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Invalid reference found at path 'Patient.managingOrganization'. Resource type 'Observation' is not valid for this path", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(new IdDt("Organization", id1.getIdPart()));
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Resource contains reference to Organization/" + id1.getIdPart() + " but resource with ID "+ id1.getIdPart()+" is actually of type Observation", e.getMessage());
|
||||
}
|
||||
|
||||
// Now with a forced ID
|
||||
|
||||
o1 = new Observation();
|
||||
o1.setId("testCreateWithIllegalReference");
|
||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||
id1 = myObservationDao.update(o1).getId().toUnqualifiedVersionless();
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(id1);
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Invalid reference found at path 'Patient.managingOrganization'. Resource type 'Observation' is not valid for this path", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(new IdDt("Organization", id1.getIdPart()));
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Resource contains reference to Organization/testCreateWithIllegalReference but resource with ID testCreateWithIllegalReference is actually of type Observation", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChoiceParamDate() {
|
||||
Observation o2 = new Observation();
|
||||
|
@ -305,8 +274,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
@Test
|
||||
public void testCreateOperationOutcome() {
|
||||
/*
|
||||
* If any of this ever fails, it means that one of the OperationOutcome issue severity codes has changed code
|
||||
* value across versions. We store the string as a constant, so something will need to be fixed.
|
||||
* If any of this ever fails, it means that one of the OperationOutcome issue severity codes has changed code value across versions. We store the string as a constant, so something will need to
|
||||
* be fixed.
|
||||
*/
|
||||
assertEquals(org.hl7.fhir.instance.model.OperationOutcome.IssueSeverity.ERROR.toCode(), BaseHapiFhirResourceDao.OO_SEVERITY_ERROR);
|
||||
assertEquals(ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum.ERROR.getCode(), BaseHapiFhirResourceDao.OO_SEVERITY_ERROR);
|
||||
|
@ -433,6 +402,71 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithIllegalReference() {
|
||||
Observation o1 = new Observation();
|
||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||
IIdType id1 = myObservationDao.create(o1).getId().toUnqualifiedVersionless();
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(id1);
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Invalid reference found at path 'Patient.managingOrganization'. Resource type 'Observation' is not valid for this path", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(new IdDt("Organization", id1.getIdPart()));
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Resource contains reference to Organization/" + id1.getIdPart() + " but resource with ID " + id1.getIdPart() + " is actually of type Observation", e.getMessage());
|
||||
}
|
||||
|
||||
// Now with a forced ID
|
||||
|
||||
o1 = new Observation();
|
||||
o1.setId("testCreateWithIllegalReference");
|
||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||
id1 = myObservationDao.update(o1).getId().toUnqualifiedVersionless();
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(id1);
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Invalid reference found at path 'Patient.managingOrganization'. Resource type 'Observation' is not valid for this path", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Patient p = new Patient();
|
||||
p.getManagingOrganization().setReference(new IdDt("Organization", id1.getIdPart()));
|
||||
myPatientDao.create(p);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Resource contains reference to Organization/testCreateWithIllegalReference but resource with ID testCreateWithIllegalReference is actually of type Observation", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithInvalid() {
|
||||
Observation o1 = new Observation();
|
||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||
o1.setValue(new CodeableConceptDt("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
||||
IIdType id1 = myObservationDao.create(o1).getId();
|
||||
|
||||
{
|
||||
IBundleProvider found = myObservationDao.search(Observation.SP_VALUE_CONCEPT, new TokenParam("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(id1, found.getResources(0, 1).get(0).getIdElement());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||
Patient patient = new Patient();
|
||||
|
@ -627,6 +661,50 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFailsIfIncomingLinks() {
|
||||
String methodName = "testDeleteFailsIfIncomingLinks";
|
||||
Organization org = new Organization();
|
||||
org.setName(methodName);
|
||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily(methodName);
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
IIdType patId = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add("_id", new StringParam(orgId.getIdPart()));
|
||||
map.addRevInclude(new Include("*"));
|
||||
List<IIdType> found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
|
||||
assertThat(found, contains(orgId, patId));
|
||||
|
||||
try {
|
||||
myOrganizationDao.delete(orgId);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
assertThat(e.getMessage(), containsString("Unable to delete Organization/" + orgId.getIdPart()
|
||||
+ " because at least one resource has a reference to this resource. First reference found was resource Patient/" + patId.getIdPart() + " in path Patient.managingOrganization"));
|
||||
}
|
||||
|
||||
myPatientDao.delete(patId);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_id", new StringParam(orgId.getIdPart()));
|
||||
map.addRevInclude(new Include("*"));
|
||||
found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
|
||||
assertThat(found, contains(orgId));
|
||||
|
||||
myOrganizationDao.delete(orgId);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_id", new StringParam(orgId.getIdPart()));
|
||||
map.addRevInclude(new Include("*"));
|
||||
found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
|
||||
assertThat(found, empty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteResource() {
|
||||
int initialHistory = myPatientDao.history(null).size();
|
||||
|
@ -690,81 +768,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantSearchForDeletedResourceByLanguageOrTag() {
|
||||
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
|
||||
Organization org = new Organization();
|
||||
org.setLanguage(new CodeDt("EN_ca"));
|
||||
org.setName(methodName);
|
||||
|
||||
TagList tl = new TagList();
|
||||
tl.add(new Tag(methodName, methodName));
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put(org, tl);
|
||||
|
||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add("_language", new StringParam("EN_ca"));
|
||||
assertEquals(1, myOrganizationDao.search(map).size());
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_tag", new TokenParam(methodName, methodName));
|
||||
assertEquals(1, myOrganizationDao.search(map).size());
|
||||
|
||||
myOrganizationDao.delete(orgId);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_language", new StringParam("EN_ca"));
|
||||
assertEquals(0, myOrganizationDao.search(map).size());
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_tag", new TokenParam(methodName, methodName));
|
||||
assertEquals(0, myOrganizationDao.search(map).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFailsIfIncomingLinks() {
|
||||
String methodName = "testDeleteFailsIfIncomingLinks";
|
||||
Organization org = new Organization();
|
||||
org.setName(methodName);
|
||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily(methodName);
|
||||
patient.getManagingOrganization().setReference(orgId);
|
||||
IIdType patId = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add("_id", new StringParam(orgId.getIdPart()));
|
||||
map.addRevInclude(new Include("*"));
|
||||
List<IIdType> found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
|
||||
assertThat(found, contains(orgId, patId));
|
||||
|
||||
try {
|
||||
myOrganizationDao.delete(orgId);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
assertThat(e.getMessage(), containsString("Unable to delete Organization/" + orgId.getIdPart() + " because at least one resource has a reference to this resource. First reference found was resource Patient/" + patId.getIdPart() + " in path Patient.managingOrganization"));
|
||||
}
|
||||
|
||||
myPatientDao.delete(patId);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_id", new StringParam(orgId.getIdPart()));
|
||||
map.addRevInclude(new Include("*"));
|
||||
found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
|
||||
assertThat(found, contains(orgId));
|
||||
|
||||
myOrganizationDao.delete(orgId);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.add("_id", new StringParam(orgId.getIdPart()));
|
||||
map.addRevInclude(new Include("*"));
|
||||
found = toUnqualifiedVersionlessIds(myOrganizationDao.search(map));
|
||||
assertThat(found, empty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteThenUndelete() {
|
||||
Patient patient = new Patient();
|
||||
|
@ -1033,7 +1036,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(0)));
|
||||
assertEquals(BundleEntryTransactionMethodEnum.PUT, ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get((IResource) entries.get(0)));
|
||||
|
||||
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(1)));
|
||||
assertEquals(BundleEntryTransactionMethodEnum.DELETE, ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get((IResource) entries.get(1)));
|
||||
|
||||
|
@ -1874,6 +1877,18 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
assertEquals(BundleEntrySearchModeEnum.INCLUDE, ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get((IResource) results.get(1)));
|
||||
}
|
||||
|
||||
@Test()
|
||||
public void testSortByComposite() {
|
||||
SearchParameterMap pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
|
||||
try {
|
||||
myObservationDao.search(pm);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("This server does not support _sort specifications of type COMPOSITE - Can't serve _sort=code-value-concept", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByDate() {
|
||||
Patient p = new Patient();
|
||||
|
@ -1976,6 +1991,78 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
assertThat(actual, contains(id4, id3, id2, id1, idMethodName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByNumber() {
|
||||
String methodName = "testSortByNumber";
|
||||
|
||||
Encounter e1 = new Encounter();
|
||||
e1.addIdentifier().setSystem("foo").setValue(methodName);
|
||||
e1.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("min").setValue(4.0 * 24 * 60);
|
||||
IIdType id1 = myEncounterDao.create(e1).getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter e3 = new Encounter();
|
||||
e3.addIdentifier().setSystem("foo").setValue(methodName);
|
||||
e3.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("year").setValue(3.0);
|
||||
IIdType id3 = myEncounterDao.create(e3).getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter e2 = new Encounter();
|
||||
e2.addIdentifier().setSystem("foo").setValue(methodName);
|
||||
e2.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("year").setValue(2.0);
|
||||
IIdType id2 = myEncounterDao.create(e2).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm;
|
||||
List<IIdType> actual;
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Encounter.SP_LENGTH));
|
||||
actual = toUnqualifiedVersionlessIds(myEncounterDao.search(pm));
|
||||
assertThat(actual, contains(id1, id2, id3));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Encounter.SP_LENGTH, SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(myEncounterDao.search(pm));
|
||||
assertThat(actual, contains(id3, id2, id1));
|
||||
}
|
||||
|
||||
public void testSortByQuantity() {
|
||||
Observation res;
|
||||
|
||||
res = new Observation();
|
||||
res.setValue(new QuantityDt().setSystem("sys1").setCode("code1").setValue(2L));
|
||||
IIdType id2 = myObservationDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
res = new Observation();
|
||||
res.setValue(new QuantityDt().setSystem("sys1").setCode("code1").setValue(1L));
|
||||
IIdType id1 = myObservationDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
res = new Observation();
|
||||
res.setValue(new QuantityDt().setSystem("sys1").setCode("code1").setValue(3L));
|
||||
IIdType id3 = myObservationDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
res = new Observation();
|
||||
res.setValue(new QuantityDt().setSystem("sys1").setCode("code1").setValue(4L));
|
||||
IIdType id4 = myObservationDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Observation.SP_VALUE_QUANTITY));
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myConceptMapDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Observation.SP_VALUE_QUANTITY, SortOrderEnum.ASC));
|
||||
actual = toUnqualifiedVersionlessIds(myConceptMapDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Observation.SP_VALUE_QUANTITY, SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(myObservationDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id4, id3, id2, id1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByReference() {
|
||||
String methodName = "testSortByReference";
|
||||
|
@ -2149,6 +2236,88 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
assertThat(names.subList(2, 4), contains("Giv2 Fam1", "Giv1 Fam1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByToken() {
|
||||
String methodName = "testSortByToken";
|
||||
|
||||
Patient p;
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system2").setValue(methodName + "1");
|
||||
IIdType id3 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system1").setValue(methodName + "2");
|
||||
IIdType id2 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system1").setValue(methodName + "1");
|
||||
IIdType id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system2").setValue(methodName + "2");
|
||||
IIdType id4 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm;
|
||||
List<IIdType> actual;
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
TokenOrListParam sp = new TokenOrListParam();
|
||||
sp.addOr(new TokenParam("urn:system1", methodName + "1"));
|
||||
sp.addOr(new TokenParam("urn:system1", methodName + "2"));
|
||||
sp.addOr(new TokenParam("urn:system2", methodName + "1"));
|
||||
sp.addOr(new TokenParam("urn:system2", methodName + "2"));
|
||||
pm.add(Patient.SP_IDENTIFIER, sp);
|
||||
pm.setSort(new SortSpec(Patient.SP_IDENTIFIER));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
sp = new TokenOrListParam();
|
||||
sp.addOr(new TokenParam("urn:system1", methodName + "1"));
|
||||
sp.addOr(new TokenParam("urn:system1", methodName + "2"));
|
||||
sp.addOr(new TokenParam("urn:system2", methodName + "1"));
|
||||
sp.addOr(new TokenParam("urn:system2", methodName + "2"));
|
||||
pm.add(Patient.SP_IDENTIFIER, sp);
|
||||
pm.setSort(new SortSpec(Patient.SP_IDENTIFIER, SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id4, id3, id2, id1));
|
||||
|
||||
}
|
||||
|
||||
public void testSortByUri() {
|
||||
ConceptMap res = new ConceptMap();
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://foo2");
|
||||
IIdType id2 = myConceptMapDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
res = new ConceptMap();
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://foo1");
|
||||
IIdType id1 = myConceptMapDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
res = new ConceptMap();
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://bar3");
|
||||
IIdType id3 = myConceptMapDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
res = new ConceptMap();
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://bar4");
|
||||
IIdType id4 = myConceptMapDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(ConceptMap.SP_DEPENDSON));
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myConceptMapDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Encounter.SP_LENGTH, SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(myConceptMapDao.search(pm));
|
||||
assertEquals(4, actual.size());
|
||||
assertThat(actual, contains(id4, id3, id2, id1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreUnversionedResources() {
|
||||
Organization o1 = new Organization();
|
||||
|
|
|
@ -92,7 +92,6 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
|||
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
|
||||
|
||||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
|
@ -154,7 +153,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBundleCreate() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
@ -209,16 +208,16 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
@Test
|
||||
public void testCreateWithForcedId() throws IOException {
|
||||
String methodName = "testCreateWithForcedId";
|
||||
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.setId(methodName);
|
||||
|
||||
|
||||
IIdType optId = ourClient.update().resource(p).execute().getId();
|
||||
assertEquals(methodName, optId.getIdPart());
|
||||
assertEquals("1", optId.getVersionIdPart());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
||||
ValueSet options = new ValueSet();
|
||||
|
@ -428,8 +427,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
|
||||
/*
|
||||
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to
|
||||
* make sure that works too..
|
||||
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too..
|
||||
*/
|
||||
Socket sock = new Socket();
|
||||
sock.setSoTimeout(3000);
|
||||
|
@ -701,7 +699,8 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
patient.setId(id);
|
||||
ourClient.update().resource(patient).execute();
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle history = ourClient.history().onInstance(id).andReturnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle history = ourClient.history().onInstance(id).andReturnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA)
|
||||
.execute();
|
||||
assertEquals(3, history.getEntry().size());
|
||||
assertEquals(id.withVersion("3"), history.getEntry().get(0).getResource().getId());
|
||||
assertEquals(1, ((Patient) history.getEntry().get(0).getResource()).getName().size());
|
||||
|
@ -752,7 +751,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
Patient p = new Patient();
|
||||
p.addName().addFamily("testMetaAddInvalid");
|
||||
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
|
||||
//@formatter:off
|
||||
String input = "<Parameters>\n" +
|
||||
" <meta>\n" +
|
||||
|
@ -764,7 +763,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
" </meta>\n" +
|
||||
"</Parameters>";
|
||||
//@formatter:on
|
||||
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient/" + id.getIdPart() + "/$meta-add");
|
||||
post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
|
@ -790,7 +789,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMetaOperations() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
@ -948,7 +947,8 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
|
||||
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
|
||||
.execute();
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getResource().getId().getIdPart());
|
||||
|
||||
|
@ -1152,6 +1152,18 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
assertEquals(BundleEntrySearchModeEnum.INCLUDE, found.getEntries().get(1).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE));
|
||||
}
|
||||
|
||||
@Test(expected = InvalidRequestException.class)
|
||||
public void testSearchWithInvalidSort() throws Exception {
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Observation.class)
|
||||
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
|
||||
.prettyPrint()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissing() throws Exception {
|
||||
ourLog.info("Starting testSearchWithMissing");
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package ca.uhn.fhirtest;
|
||||
|
||||
import java.sql.DriverManager;
|
||||
|
||||
import org.apache.derby.drda.NetworkServerControl;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<util:list id="myServerInterceptors">
|
||||
<ref bean="myLoggingInterceptor"/>
|
||||
<ref bean="mySubscriptionSecurityInterceptor"/>
|
||||
<!-- <ref bean="mySubscriptionSecurityInterceptor"/> -->
|
||||
</util:list>
|
||||
|
||||
<!--
|
||||
|
@ -44,7 +44,9 @@
|
|||
<bean id="dbServer" class="ca.uhn.fhirtest.DerbyNetworkServer">
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
<bean id="mySubscriptionSecurityInterceptor" class="ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptor"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Do some fancy logging to create a nice access log that has details
|
||||
|
|
|
@ -36,9 +36,6 @@ import ca.uhn.fhir.rest.annotation.IdParam;
|
|||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class DefaultEncodingTest {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
@ -47,6 +44,59 @@ public class DefaultEncodingTest {
|
|||
private static final FhirContext ourCtx = FhirContext.forDstu1();
|
||||
private static RestfulServer ourRestfulServer;
|
||||
|
||||
@Test
|
||||
public void testHonoursAcceptHeader() throws Exception {
|
||||
ourRestfulServer.setDefaultPrettyPrint(false);
|
||||
ourRestfulServer.setDefaultResponseEncoding(EncodingEnum.JSON);
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
String responseContent;
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/json");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/json+fhir");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/json+fhir, application/xml+fhir");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/xml+fhir, application/json+fhir");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/xml+fhir; q=0.9, application/json+fhir; q=1.0");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/xml+fhir; q=1.0, application/json+fhir; q=0.9");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, not(containsString("\"identifier\":")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithDefaultJsonPretty() throws Exception {
|
||||
ourRestfulServer.setDefaultPrettyPrint(true);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -11,7 +13,6 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
@ -198,11 +199,31 @@ public class ServerFeaturesTest {
|
|||
|
||||
@Test
|
||||
public void testAcceptHeaderWithPrettyPrint() throws Exception {
|
||||
HttpGet httpGet;
|
||||
CloseableHttpResponse status;
|
||||
String responseContent;
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", Constants.CT_FHIR_JSON + "; pretty=true; q=1.0, " + Constants.CT_FHIR_XML + "; pretty=true; q=0.9");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, (containsString("\"identifier\":")));
|
||||
assertThat(responseContent, (containsString(",\n")));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", Constants.CT_FHIR_JSON + "; pretty=true" + ", " + Constants.CT_FHIR_XML + "; pretty=true");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, not(containsString("\"identifier\":")));
|
||||
assertThat(responseContent, (containsString(">\n")));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", Constants.CT_FHIR_XML + "; pretty=true");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertThat(responseContent, StringContains.containsString("<identifier>\n "));
|
||||
|
@ -216,13 +237,12 @@ public class ServerFeaturesTest {
|
|||
assertThat(responseContent, StringContains.containsString("\",\n"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", Constants.CT_FHIR_JSON + "; pretty=true" + ", " + Constants.CT_FHIR_XML + "; pretty=true");
|
||||
httpGet.addHeader("Accept", Constants.CT_FHIR_JSON + "; pretty=true; q=1.0" + ", " + Constants.CT_FHIR_XML + "; pretty=true; q=0.9");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertThat(responseContent, StringContains.containsString("\"identifier\":"));
|
||||
|
||||
assertThat(responseContent, (containsString("\"identifier\":")));
|
||||
assertThat(responseContent, (containsString(",\n")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -220,9 +220,11 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("http://"+methodName+".example.com/fhir/metadata?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
assertEquals("http://"+methodName+".example.com/fhir/Patient/123?_format=json", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -259,9 +261,13 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("http://"+methodName+".example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertEquals("http://"+methodName+".example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
public class ServerWithResponseHighlightingInterceptorExceptionTest {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerWithResponseHighlightingInterceptorExceptionTest.class);
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||
private static RestfulServer ourServlet;
|
||||
|
||||
@Test
|
||||
public void testExpectedException() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
|
||||
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("<diagnostics value=\"AAABBB\"/>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnexpectedException() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
|
||||
assertEquals(500, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("<diagnostics value=\"Failed to call access method\"/>"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
ourServlet = new RestfulServer(ourCtx);
|
||||
ourServlet.setFhirContext(ourCtx);
|
||||
ourServlet.setResourceProviders(patientProvider);
|
||||
ourServlet.registerInterceptor(new ResponseHighlighterInterceptor());
|
||||
ServletHolder servletHolder = new ServletHolder(ourServlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourClient = builder.build();
|
||||
|
||||
}
|
||||
|
||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
@Read
|
||||
public Patient read(@IdParam IdDt theId) {
|
||||
throw new InvalidRequestException("AAABBB");
|
||||
}
|
||||
|
||||
@Search
|
||||
public Patient search(@RequiredParam(name="identifier") TokenParam theToken) {
|
||||
throw new Error("AAABBB");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -66,6 +66,15 @@
|
|||
to a resource that is not valid in the location it is found in (e.g. points to Patient/123 but
|
||||
the field supposed to reference an Organization). Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
In server, if a client request is received and it has an Accept header indicating
|
||||
that it supports both XML and JSON with equal weight, the server's default is used instead of the first entry in the list.
|
||||
</action>
|
||||
<action type="add">
|
||||
JPA server now supports searching with sort by token, quantity,
|
||||
number and URI (previously only string, date, _id and _lastUpdated
|
||||
were supported)
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue