Handle sort by number, uti and token
This commit is contained in:
parent
1361e69177
commit
51a046ea26
|
@ -240,22 +240,55 @@ public class RestfulServerUtils {
|
||||||
EncodingEnum retVal = null;
|
EncodingEnum retVal = null;
|
||||||
while (acceptValues.hasMoreElements()) {
|
while (acceptValues.hasMoreElements()) {
|
||||||
String nextAcceptHeaderValue = acceptValues.nextElement();
|
String nextAcceptHeaderValue = acceptValues.nextElement();
|
||||||
Matcher m = ACCEPT_HEADER_PATTERN.matcher(nextAcceptHeaderValue);
|
StringTokenizer tok = new StringTokenizer(nextAcceptHeaderValue, ",");
|
||||||
float q = 1.0f;
|
while (tok.hasMoreTokens()) {
|
||||||
while (m.find()) {
|
String nextToken = tok.nextToken();
|
||||||
String contentTypeGroup = m.group(1);
|
int startSpaceIndex = -1;
|
||||||
EncodingEnum encoding = Constants.FORMAT_VAL_TO_ENCODING.get(contentTypeGroup);
|
for (int i = 0; i < nextToken.length(); i++) {
|
||||||
if (encoding != null) {
|
if (nextToken.charAt(i) != ' ') {
|
||||||
|
startSpaceIndex = i;
|
||||||
String name = m.group(3);
|
break;
|
||||||
String value = m.group(4);
|
}
|
||||||
if (name != null && value != null) {
|
}
|
||||||
if ("q".equals(name)) {
|
|
||||||
try {
|
if (startSpaceIndex == -1) {
|
||||||
q = Float.parseFloat(value);
|
continue;
|
||||||
q = Math.max(q, 0.0f);
|
}
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
ourLog.debug("Invalid Accept header q value: {}", value);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,12 +300,46 @@ public class RestfulServerUtils {
|
||||||
bestQ = q;
|
bestQ = q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!",".equals(m.group(5))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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;
|
return retVal;
|
||||||
|
|
|
@ -212,6 +212,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.el</groupId>
|
<groupId>javax.el</groupId>
|
||||||
<artifactId>javax.el-api</artifactId>
|
<artifactId>javax.el-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish</groupId>
|
<groupId>org.glassfish</groupId>
|
||||||
|
|
|
@ -54,7 +54,6 @@ import javax.persistence.criteria.Predicate;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
import javax.persistence.criteria.Subquery;
|
import javax.persistence.criteria.Subquery;
|
||||||
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
@ -306,7 +305,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
return retVal;
|
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;
|
boolean missingFalse = false;
|
||||||
if (nextOr.getMissing() != null) {
|
if (nextOr.getMissing() != null) {
|
||||||
if (nextOr.getMissing().booleanValue() == true) {
|
if (nextOr.getMissing().booleanValue() == true) {
|
||||||
|
@ -320,7 +320,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
return missingFalse;
|
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;
|
boolean missingFalse = false;
|
||||||
if (nextOr.getMissing() != null) {
|
if (nextOr.getMissing() != null) {
|
||||||
if (nextOr.getMissing().booleanValue() == true) {
|
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;
|
String rawSearchTerm;
|
||||||
if (theParameter instanceof TokenParam) {
|
if (theParameter instanceof TokenParam) {
|
||||||
TokenParam id = (TokenParam) theParameter;
|
TokenParam id = (TokenParam) theParameter;
|
||||||
|
@ -1129,7 +1131,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawSearchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
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);
|
String likeExpression = normalizeString(rawSearchTerm);
|
||||||
|
@ -1143,7 +1146,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
return singleCode;
|
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 code;
|
||||||
String system;
|
String system;
|
||||||
if (theParameter instanceof TokenParam) {
|
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) {
|
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) {
|
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>());
|
ArrayList<Predicate> singleCodePredicates = (new ArrayList<Predicate>());
|
||||||
|
@ -1220,23 +1226,39 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
}
|
}
|
||||||
|
|
||||||
String joinAttrName;
|
String joinAttrName;
|
||||||
String sortAttrName;
|
String[] sortAttrName;
|
||||||
|
|
||||||
switch (param.getParamType()) {
|
switch (param.getParamType()) {
|
||||||
case STRING:
|
case STRING:
|
||||||
joinAttrName = "myParamsString";
|
joinAttrName = "myParamsString";
|
||||||
sortAttrName = "myValueExact";
|
sortAttrName = new String[] { "myValueExact" };
|
||||||
break;
|
break;
|
||||||
case DATE:
|
case DATE:
|
||||||
joinAttrName = "myParamsDate";
|
joinAttrName = "myParamsDate";
|
||||||
sortAttrName = "myValueLow";
|
sortAttrName = new String[] { "myValueLow" };
|
||||||
break;
|
break;
|
||||||
case REFERENCE:
|
case REFERENCE:
|
||||||
joinAttrName = "myResourceLinks";
|
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;
|
break;
|
||||||
default:
|
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);
|
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"));
|
// Predicate pn = theBuilder.isNull(stringJoin.get("myParamName"));
|
||||||
// thePredicates.add(theBuilder.or(p, pn));
|
// thePredicates.add(theBuilder.or(p, pn));
|
||||||
|
|
||||||
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
for (String next : sortAttrName) {
|
||||||
theOrders.add(theBuilder.asc(stringJoin.get(sortAttrName)));
|
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
||||||
} else {
|
theOrders.add(theBuilder.asc(stringJoin.get(next)));
|
||||||
theOrders.add(theBuilder.desc(stringJoin.get(sortAttrName)));
|
} else {
|
||||||
|
theOrders.add(theBuilder.desc(stringJoin.get(next)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createSort(theBuilder, theFrom, theSort.getChain(), theOrders, thePredicates);
|
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 (isNotBlank(theResource.getId().getIdPart())) {
|
||||||
if (isValidPid(theResource.getId())) {
|
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());
|
createForcedIdIfNeeded(entity, theResource.getId());
|
||||||
|
|
||||||
|
@ -1869,7 +1894,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
|
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
if (theId.hasVersionIdPart()) {
|
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("RID", pid);
|
||||||
q.setParameter("RTYP", myResourceName);
|
q.setParameter("RTYP", myResourceName);
|
||||||
q.setParameter("RVER", Long.parseLong(theId.getVersionIdPart()));
|
q.setParameter("RVER", Long.parseLong(theId.getVersionIdPart()));
|
||||||
|
@ -2047,7 +2073,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
revIncludedPids = new HashSet<Long>();
|
revIncludedPids = new HashSet<Long>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Search returned PIDs: {}", pids);
|
ourLog.debug("Search returned PIDs: {}", pids);
|
||||||
|
|
||||||
final int totalCount = pids.size();
|
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
|
* 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.
|
||||||
* share the same value.
|
|
||||||
*/
|
*/
|
||||||
public void setSecondaryPrimaryKeyParamName(String theSecondaryPrimaryKeyParamName) {
|
public void setSecondaryPrimaryKeyParamName(String theSecondaryPrimaryKeyParamName) {
|
||||||
mySecondaryPrimaryKeyParamName = theSecondaryPrimaryKeyParamName;
|
mySecondaryPrimaryKeyParamName = theSecondaryPrimaryKeyParamName;
|
||||||
|
@ -2397,7 +2422,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceId.hasResourceType() && !resourceId.getResourceType().equals(getResourceName())) {
|
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
|
// Notify interceptors
|
||||||
|
@ -2444,12 +2470,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
||||||
String sourceId = link.getSourceResource().getIdDt().toUnqualifiedVersionless().getValue();
|
String sourceId = link.getSourceResource().getIdDt().toUnqualifiedVersionless().getValue();
|
||||||
String sourcePath = link.getSourcePath();
|
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) {
|
private void validateResourceType(BaseHasResource entity) {
|
||||||
if (!myResourceName.equals(entity.getResourceType())) {
|
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.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@SequenceGenerator(name = "RES_HISTORY_PID", sequenceName = "RES_HISTORY_PID")
|
||||||
@Column(name = "PID")
|
@Column(name = "PID")
|
||||||
private Long myId;
|
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.QuantityDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
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.Device;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
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.QuantityParam;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
import ca.uhn.fhir.rest.param.StringParam;
|
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.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
|
@ -149,6 +151,38 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
return retVal;
|
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
|
@Test
|
||||||
public void testChoiceParamConcept() {
|
public void testChoiceParamConcept() {
|
||||||
Observation o1 = new Observation();
|
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
|
@Test
|
||||||
public void testChoiceParamDate() {
|
public void testChoiceParamDate() {
|
||||||
Observation o2 = new Observation();
|
Observation o2 = new Observation();
|
||||||
|
@ -305,8 +274,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void testCreateOperationOutcome() {
|
public void testCreateOperationOutcome() {
|
||||||
/*
|
/*
|
||||||
* If any of this ever fails, it means that one of the OperationOutcome issue severity codes has changed code
|
* 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
|
||||||
* value across versions. We store the string as a constant, so something will need to be fixed.
|
* be fixed.
|
||||||
*/
|
*/
|
||||||
assertEquals(org.hl7.fhir.instance.model.OperationOutcome.IssueSeverity.ERROR.toCode(), BaseHapiFhirResourceDao.OO_SEVERITY_ERROR);
|
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);
|
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
|
@Test
|
||||||
public void testCreateWithInvalidReferenceFailsGracefully() {
|
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||||
Patient patient = new Patient();
|
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
|
@Test
|
||||||
public void testDeleteResource() {
|
public void testDeleteResource() {
|
||||||
int initialHistory = myPatientDao.history(null).size();
|
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
|
@Test
|
||||||
public void testDeleteThenUndelete() {
|
public void testDeleteThenUndelete() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -1033,7 +1036,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(0)));
|
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(0)));
|
||||||
assertEquals(BundleEntryTransactionMethodEnum.PUT, ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.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)));
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(1)));
|
||||||
assertEquals(BundleEntryTransactionMethodEnum.DELETE, ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.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)));
|
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
|
@Test
|
||||||
public void testSortByDate() {
|
public void testSortByDate() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
@ -1976,6 +1991,78 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertThat(actual, contains(id4, id3, id2, id1, idMethodName));
|
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
|
@Test
|
||||||
public void testSortByReference() {
|
public void testSortByReference() {
|
||||||
String methodName = "testSortByReference";
|
String methodName = "testSortByReference";
|
||||||
|
@ -2149,6 +2236,88 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertThat(names.subList(2, 4), contains("Giv2 Fam1", "Giv1 Fam1"));
|
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
|
@Test
|
||||||
public void testStoreUnversionedResources() {
|
public void testStoreUnversionedResources() {
|
||||||
Organization o1 = new Organization();
|
Organization o1 = new Organization();
|
||||||
|
|
|
@ -92,7 +92,6 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
|
||||||
|
|
||||||
|
|
||||||
// private static JpaConformanceProvider ourConfProvider;
|
// private static JpaConformanceProvider ourConfProvider;
|
||||||
|
|
||||||
|
@ -154,7 +153,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
|
|
||||||
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
|
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBundleCreate() throws Exception {
|
public void testBundleCreate() throws Exception {
|
||||||
IGenericClient client = ourClient;
|
IGenericClient client = ourClient;
|
||||||
|
@ -209,16 +208,16 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithForcedId() throws IOException {
|
public void testCreateWithForcedId() throws IOException {
|
||||||
String methodName = "testCreateWithForcedId";
|
String methodName = "testCreateWithForcedId";
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().addFamily(methodName);
|
p.addName().addFamily(methodName);
|
||||||
p.setId(methodName);
|
p.setId(methodName);
|
||||||
|
|
||||||
IIdType optId = ourClient.update().resource(p).execute().getId();
|
IIdType optId = ourClient.update().resource(p).execute().getId();
|
||||||
assertEquals(methodName, optId.getIdPart());
|
assertEquals(methodName, optId.getIdPart());
|
||||||
assertEquals("1", optId.getVersionIdPart());
|
assertEquals("1", optId.getVersionIdPart());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
||||||
ValueSet options = new ValueSet();
|
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
|
* 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..
|
||||||
* make sure that works too..
|
|
||||||
*/
|
*/
|
||||||
Socket sock = new Socket();
|
Socket sock = new Socket();
|
||||||
sock.setSoTimeout(3000);
|
sock.setSoTimeout(3000);
|
||||||
|
@ -701,7 +699,8 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
patient.setId(id);
|
patient.setId(id);
|
||||||
ourClient.update().resource(patient).execute();
|
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(3, history.getEntry().size());
|
||||||
assertEquals(id.withVersion("3"), history.getEntry().get(0).getResource().getId());
|
assertEquals(id.withVersion("3"), history.getEntry().get(0).getResource().getId());
|
||||||
assertEquals(1, ((Patient) history.getEntry().get(0).getResource()).getName().size());
|
assertEquals(1, ((Patient) history.getEntry().get(0).getResource()).getName().size());
|
||||||
|
@ -752,7 +751,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().addFamily("testMetaAddInvalid");
|
p.addName().addFamily("testMetaAddInvalid");
|
||||||
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
String input = "<Parameters>\n" +
|
String input = "<Parameters>\n" +
|
||||||
" <meta>\n" +
|
" <meta>\n" +
|
||||||
|
@ -764,7 +763,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
" </meta>\n" +
|
" </meta>\n" +
|
||||||
"</Parameters>";
|
"</Parameters>";
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
HttpPost post = new HttpPost(ourServerBase + "/Patient/" + id.getIdPart() + "/$meta-add");
|
HttpPost post = new HttpPost(ourServerBase + "/Patient/" + id.getIdPart() + "/$meta-add");
|
||||||
post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||||
|
@ -790,7 +789,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMetaOperations() throws Exception {
|
public void testMetaOperations() throws Exception {
|
||||||
String methodName = "testMetaOperations";
|
String methodName = "testMetaOperations";
|
||||||
|
@ -948,7 +947,8 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||||
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
|
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(1, actual.size());
|
||||||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getResource().getId().getIdPart());
|
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));
|
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
|
@Test
|
||||||
public void testSearchWithMissing() throws Exception {
|
public void testSearchWithMissing() throws Exception {
|
||||||
ourLog.info("Starting testSearchWithMissing");
|
ourLog.info("Starting testSearchWithMissing");
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
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.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -11,7 +13,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
@ -198,11 +199,31 @@ public class ServerFeaturesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAcceptHeaderWithPrettyPrint() throws Exception {
|
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");
|
httpGet.addHeader("Accept", Constants.CT_FHIR_XML + "; pretty=true");
|
||||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
status = ourClient.execute(httpGet);
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
assertThat(responseContent, StringContains.containsString("<identifier>\n "));
|
assertThat(responseContent, StringContains.containsString("<identifier>\n "));
|
||||||
|
@ -216,13 +237,12 @@ public class ServerFeaturesTest {
|
||||||
assertThat(responseContent, StringContains.containsString("\",\n"));
|
assertThat(responseContent, StringContains.containsString("\",\n"));
|
||||||
|
|
||||||
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" + ", " + 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);
|
status = ourClient.execute(httpGet);
|
||||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
assertThat(responseContent, (containsString("\"identifier\":")));
|
||||||
assertThat(responseContent, StringContains.containsString("\"identifier\":"));
|
assertThat(responseContent, (containsString(",\n")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -70,6 +70,11 @@
|
||||||
In server, if a client request is received and it has an Accept header indicating
|
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.
|
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>
|
||||||
|
<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>
|
||||||
<release version="1.2" date="2015-09-18">
|
<release version="1.2" date="2015-09-18">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue