Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
3c6299a157
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -18,22 +18,22 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<!--
|
||||
<exclusion>
|
||||
|
@ -39,13 +39,13 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
|
@ -60,7 +60,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
|
@ -55,7 +55,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
|
@ -66,7 +66,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.model.api;
|
||||
|
||||
import net.sourceforge.cobertura.CoverageIgnore;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -31,6 +33,7 @@ package ca.uhn.fhir.model.api;
|
|||
*
|
||||
* @deprecated {@link Include} should be used instead
|
||||
*/
|
||||
@CoverageIgnore
|
||||
@Deprecated
|
||||
public class PathSpecification extends Include {
|
||||
|
||||
|
|
|
@ -1014,7 +1014,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
if ("resourceType".equals(nextName)) {
|
||||
continue;
|
||||
} else if ("entry".equals(nextName)) {
|
||||
JsonArray entries = theObject.getJsonArray(nextName);
|
||||
JsonArray entries = grabJsonArray(theObject, nextName, "entry");
|
||||
for (JsonValue jsonValue : entries) {
|
||||
theState.enteringNewElement(null, "entry");
|
||||
parseBundleChildren((JsonObject) jsonValue, theState);
|
||||
|
@ -1023,7 +1023,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
continue;
|
||||
} else if (myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
|
||||
if ("link".equals(nextName)) {
|
||||
JsonArray entries = theObject.getJsonArray(nextName);
|
||||
JsonArray entries = grabJsonArray(theObject, nextName, "link");
|
||||
for (JsonValue jsonValue : entries) {
|
||||
theState.enteringNewElement(null, "link");
|
||||
JsonObject linkObj = (JsonObject) jsonValue;
|
||||
|
@ -1042,7 +1042,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
}
|
||||
} else {
|
||||
if ("link".equals(nextName)) {
|
||||
JsonArray entries = theObject.getJsonArray(nextName);
|
||||
JsonArray entries = grabJsonArray(theObject, nextName, "link");
|
||||
for (JsonValue jsonValue : entries) {
|
||||
theState.enteringNewElement(null, "link");
|
||||
JsonObject linkObj = (JsonObject) jsonValue;
|
||||
|
@ -1106,11 +1106,11 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
}
|
||||
continue;
|
||||
} else if ("extension".equals(nextName)) {
|
||||
JsonArray array = theObject.getJsonArray(nextName);
|
||||
JsonArray array = grabJsonArray(theObject, nextName, "extension");
|
||||
parseExtension(theState, array, false);
|
||||
continue;
|
||||
} else if ("modifierExtension".equals(nextName)) {
|
||||
JsonArray array = theObject.getJsonArray(nextName);
|
||||
JsonArray array = grabJsonArray(theObject, nextName, "modifierExtension");
|
||||
parseExtension(theState, array, true);
|
||||
continue;
|
||||
} else if (nextName.charAt(0) == '_') {
|
||||
|
@ -1135,6 +1135,17 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
}
|
||||
}
|
||||
|
||||
private JsonArray grabJsonArray(JsonObject theObject, String nextName, String thePosition) {
|
||||
JsonValue object = theObject.get(nextName);
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (object.getValueType() != ValueType.ARRAY) {
|
||||
throw new DataFormatException("Syntax error parsing JSON FHIR structure: Expected ARRAY at element '" + thePosition + "', found '" + object.getValueType().name() + "'");
|
||||
}
|
||||
return (JsonArray) object;
|
||||
}
|
||||
|
||||
private void parseChildren(ParserState<?> theState, String theName, JsonValue theJsonVal, JsonValue theAlternateVal, String theAlternateName) {
|
||||
switch (theJsonVal.getValueType()) {
|
||||
case ARRAY: {
|
||||
|
|
|
@ -24,8 +24,11 @@ import java.util.Collections;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
|
@ -35,8 +38,8 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
|
||||
public class DateParam extends DateTimeDt implements IQueryParameterType, IQueryParameterOr<DateParam> {
|
||||
|
||||
private QuantityCompararatorEnum myComparator;
|
||||
private BaseParam myBase=new BaseParam.ComposableBaseParam();
|
||||
private QuantityCompararatorEnum myComparator;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -55,17 +58,26 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DateParam(QuantityCompararatorEnum theComparator, String theDate) {
|
||||
public DateParam(QuantityCompararatorEnum theComparator, DateTimeDt theDate) {
|
||||
myComparator = theComparator;
|
||||
setValueAsString(theDate);
|
||||
setValueAsString(theDate != null ? theDate.getValueAsString() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DateParam(QuantityCompararatorEnum theComparator, DateTimeDt theDate) {
|
||||
public DateParam(QuantityCompararatorEnum theComparator, long theDate) {
|
||||
Validate.inclusiveBetween(1, Long.MAX_VALUE, theDate, "theDate must not be 0 or negative");
|
||||
myComparator = theComparator;
|
||||
setValueAsString(theDate != null ? theDate.getValueAsString() : null);
|
||||
setValue(new Date(theDate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DateParam(QuantityCompararatorEnum theComparator, String theDate) {
|
||||
myComparator = theComparator;
|
||||
setValueAsString(theDate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,6 +97,11 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
return myComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getMissing() {
|
||||
return myBase.getMissing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryParameterQualifier() {
|
||||
if (myBase.getMissing()!=null) {
|
||||
|
@ -93,6 +110,14 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
return null;
|
||||
}
|
||||
|
||||
public DateTimeDt getValueAsDateTimeDt() {
|
||||
return new DateTimeDt(getValueAsString());
|
||||
}
|
||||
|
||||
public InstantDt getValueAsInstantDt() {
|
||||
return new InstantDt(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueAsQueryToken() {
|
||||
if (myBase.getMissing()!=null) {
|
||||
|
@ -125,6 +150,17 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
myComparator = theComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMissing(Boolean theMissing) {
|
||||
myBase.setMissing(theMissing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateParam setValue(Date theValue) {
|
||||
super.setValue(theValue, TemporalPrecisionEnum.MILLI);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theValue) {
|
||||
myBase.setValueAsQueryToken(theQualifier, theValue);
|
||||
|
@ -191,22 +227,4 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
public InstantDt getValueAsInstantDt() {
|
||||
return new InstantDt(getValue());
|
||||
}
|
||||
|
||||
public DateTimeDt getValueAsDateTimeDt() {
|
||||
return new DateTimeDt(getValueAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getMissing() {
|
||||
return myBase.getMissing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMissing(Boolean theMissing) {
|
||||
myBase.setMissing(theMissing);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -214,8 +214,16 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
|||
* "2011-02-22" or "2011-02-22T13:12:00Z". Will be treated inclusively. Either theLowerBound or theUpperBound may both be populated, or one may be null, but it is not valid for both to be null.
|
||||
*/
|
||||
public void setRangeFromDatesInclusive(DateTimeDt theLowerBound, DateTimeDt theUpperBound) {
|
||||
myLowerBound = theLowerBound != null ? new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound) : null;
|
||||
myUpperBound = theUpperBound != null ? new DateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound) : null;
|
||||
if (theLowerBound instanceof DateParam) {
|
||||
myLowerBound = (DateParam) theLowerBound;
|
||||
} else {
|
||||
myLowerBound = theLowerBound != null ? new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound) : null;
|
||||
}
|
||||
if (theUpperBound instanceof DateParam) {
|
||||
myUpperBound = (DateParam) theUpperBound;
|
||||
} else {
|
||||
myUpperBound = theUpperBound != null ? new DateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound) : null;
|
||||
}
|
||||
validateAndThrowDataFormatExceptionIfInvalid();
|
||||
}
|
||||
|
||||
|
@ -304,8 +312,13 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
|||
boolean haveLowerBound = haveLowerBound();
|
||||
boolean haveUpperBound = haveUpperBound();
|
||||
if (haveLowerBound && haveUpperBound) {
|
||||
if (myLowerBound.getValue().after(myUpperBound.getValue())) {
|
||||
throw new DataFormatException("Lower bound of " + myLowerBound.getValueAsString() + " is after upper bound of " + myUpperBound.getValueAsString());
|
||||
if (myLowerBound.getValue().getTime() > myUpperBound.getValue().getTime()) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("Lower bound of ");
|
||||
b.append(myLowerBound.getValueAsString());
|
||||
b.append(" is after upper bound of ");
|
||||
b.append(myUpperBound.getValueAsString());
|
||||
throw new DataFormatException(b.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,13 @@ package ca.uhn.fhir.rest.param;
|
|||
import java.util.Date;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import net.sourceforge.cobertura.CoverageIgnore;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link DateParam} instead (this class is identical, but was renamed to be less confusing)
|
||||
*/
|
||||
@Deprecated
|
||||
@CoverageIgnore
|
||||
public class QualifiedDateParam extends DateParam {
|
||||
/**
|
||||
* Constructor
|
||||
|
|
|
@ -46,6 +46,7 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.IParameter;
|
||||
import ca.uhn.fhir.rest.method.MethodUtil;
|
||||
|
@ -145,12 +146,15 @@ public class ResourceParameter implements IParameter {
|
|||
return charset;
|
||||
}
|
||||
|
||||
public static IBaseResource loadResourceFromRequest(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding, Class<? extends IBaseResource> theResourceType) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends IBaseResource> T loadResourceFromRequest(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding, Class<T> theResourceType) {
|
||||
FhirContext ctx = theRequest.getServer().getFhirContext();
|
||||
|
||||
final Charset charset = determineRequestCharset(theRequest);
|
||||
Reader requestReader = createRequestReader(theRequest.getRawRequest(), charset);
|
||||
|
||||
RestOperationTypeEnum restOperationType = theMethodBinding != null ? theMethodBinding.getRestOperationType() : null;
|
||||
|
||||
EncodingEnum encoding = RestfulServerUtils.determineRequestEncodingNoDefault(theRequest);
|
||||
if (encoding == null) {
|
||||
String ctValue = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
|
||||
|
@ -173,24 +177,24 @@ public class ResourceParameter implements IParameter {
|
|||
}
|
||||
encoding = MethodUtil.detectEncodingNoDefault(body);
|
||||
if (encoding == null) {
|
||||
String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "noContentTypeInRequest", theMethodBinding.getRestOperationType());
|
||||
String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "noContentTypeInRequest", restOperationType);
|
||||
throw new InvalidRequestException(msg);
|
||||
} else {
|
||||
requestReader = new InputStreamReader(new ByteArrayInputStream(theRequest.getRawRequest()), charset);
|
||||
}
|
||||
} else {
|
||||
String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "invalidContentTypeInRequest", ctValue, theMethodBinding.getRestOperationType());
|
||||
String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "invalidContentTypeInRequest", ctValue, restOperationType);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
IParser parser = encoding.newParser(ctx);
|
||||
|
||||
IBaseResource retVal;
|
||||
T retVal;
|
||||
if (theResourceType != null) {
|
||||
retVal = parser.parseResource(theResourceType, requestReader);
|
||||
} else {
|
||||
retVal = parser.parseResource(requestReader);
|
||||
retVal = (T) parser.parseResource(requestReader);
|
||||
}
|
||||
|
||||
if (theRequest.getId() != null && theRequest.getId().hasIdPart()) {
|
||||
|
|
|
@ -106,10 +106,11 @@ public interface IServerInterceptor {
|
|||
* The incoming servlet request as provided by the servlet container
|
||||
* @param theOperation
|
||||
* The type of operation that the FHIR server has determined that the client is trying to invoke
|
||||
* @param theRequestDetails
|
||||
* An object which will be populated with any relevant details about the incoming request (this includes the HttpServletRequest)
|
||||
* @param theProcessedRequest
|
||||
* An object which will be populated with the details which were extracted from the raw request by the server,
|
||||
* e.g. the FHIR operation type and the parsed resource body (if any).
|
||||
*/
|
||||
void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theRequestDetails);
|
||||
void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theProcessedRequest);
|
||||
|
||||
/**
|
||||
* This method is called before any other processing takes place for each incoming request. It may be used to provide alternate handling for some requests, or to screen requests before they are
|
||||
|
|
|
@ -42,7 +42,8 @@ import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
|||
public class InterceptorAdapter implements IServerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean incomingRequestPreProcessed(HttpServletRequest theRequest, HttpServletResponse theResponse) {
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws ServletException,
|
||||
IOException {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,12 @@ public class InterceptorAdapter implements IServerInterceptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, TagList theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theProcessedRequest) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean incomingRequestPreProcessed(HttpServletRequest theRequest, HttpServletResponse theResponse) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,12 +68,17 @@ public class InterceptorAdapter implements IServerInterceptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, TagList theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -75,16 +86,5 @@ public class InterceptorAdapter implements IServerInterceptor {
|
|||
public BaseServerResponseException preProcessOutgoingException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theServletRequest) throws ServletException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws ServletException,
|
||||
IOException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theRequestDetails) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ import java.net.URL;
|
|||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -158,5 +161,92 @@ public class UrlUtil {
|
|||
throw new Error("UTF-8 not supported on this platform");
|
||||
}
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
/**
|
||||
* Parse a URL in one of the following forms:
|
||||
* <ul>
|
||||
* <li>[Resource Type]?[Search Params]
|
||||
* <li>[Resource Type]/[Resource ID]
|
||||
* <li>[Resource Type]/[Resource ID]/_history/[Version ID]
|
||||
* </ul>
|
||||
*/
|
||||
//@formatter:on
|
||||
public static UrlParts parseUrl(String theUrl) {
|
||||
UrlParts retVal = new UrlParts();
|
||||
|
||||
int nextStart = 0;
|
||||
boolean nextIsHistory = false;
|
||||
|
||||
for (int idx = 0; idx < theUrl.length(); idx++) {
|
||||
char nextChar = theUrl.charAt(idx);
|
||||
boolean atEnd = (idx + 1) == theUrl.length();
|
||||
if (nextChar == '?' || nextChar == '/' || atEnd) {
|
||||
int endIdx = atEnd ? idx + 1 : idx;
|
||||
String nextSubstring = theUrl.substring(nextStart, endIdx);
|
||||
if (retVal.getResourceType() == null) {
|
||||
retVal.setResourceType(nextSubstring);
|
||||
} else if (retVal.getResourceId() == null) {
|
||||
retVal.setResourceId(nextSubstring);
|
||||
} else if (nextIsHistory) {
|
||||
retVal.setVersionId(nextSubstring);
|
||||
} else {
|
||||
if (nextSubstring.equals(Constants.URL_TOKEN_HISTORY)) {
|
||||
nextIsHistory = true;
|
||||
} else {
|
||||
throw new InvalidRequestException("Invalid FHIR resource URL: " + theUrl);
|
||||
}
|
||||
}
|
||||
if (nextChar == '?') {
|
||||
if (theUrl.length() > idx + 1) {
|
||||
retVal.setParams(theUrl.substring(idx + 1, theUrl.length()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
nextStart = idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static class UrlParts {
|
||||
private String myParams;
|
||||
private String myResourceId;
|
||||
private String myResourceType;
|
||||
private String myVersionId;
|
||||
|
||||
public String getParams() {
|
||||
return myParams;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return myResourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
}
|
||||
|
||||
public String getVersionId() {
|
||||
return myVersionId;
|
||||
}
|
||||
|
||||
public void setParams(String theParams) {
|
||||
myParams = theParams;
|
||||
}
|
||||
|
||||
public void setResourceId(String theResourceId) {
|
||||
myResourceId = theResourceId;
|
||||
}
|
||||
|
||||
public void setResourceType(String theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
}
|
||||
|
||||
public void setVersionId(String theVersionId) {
|
||||
myVersionId = theVersionId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<tr th:each="issue : ${resource.issue}">
|
||||
<td th:text="${issue.severityElement.value}" style="font-weight: bold;"></td>
|
||||
<td th:text="${issue.location}"></td>
|
||||
<td><pre th:text="${issue.details}"/></td>
|
||||
<td><pre th:text="${issue.diagnostics}"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -22,33 +22,33 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-example</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -143,7 +143,7 @@
|
|||
<artifactItem>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-example</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>target/classes</outputDirectory>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -19,32 +19,32 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -18,17 +18,17 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -31,7 +30,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
|
@ -42,22 +41,22 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -93,18 +92,13 @@
|
|||
<artifactId>jscience</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- FHIR RI is pulled in for UCUM support, but we don't want any of its
|
||||
dependencies. -->
|
||||
<!-- <dependency> <groupId>me.fhir</groupId> <artifactId>fhir-dstu1</artifactId>
|
||||
<version>0.0.81.2489</version> <exclusions> <exclusion> <artifactId>Saxon-HE</artifactId>
|
||||
<groupId>net.sf.saxon</groupId> </exclusion> <exclusion> <artifactId>commons-discovery</artifactId>
|
||||
<groupId>commons-discovery</groupId> </exclusion> <exclusion> <artifactId>commons-codec</artifactId>
|
||||
<groupId>commons-codec</groupId> </exclusion> <exclusion> <artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId> </exclusion> <exclusion> <artifactId>xpp3</artifactId>
|
||||
<groupId>xpp3</groupId> </exclusion> <exclusion> <artifactId>junit</artifactId>
|
||||
<groupId>junit</groupId> </exclusion> <exclusion> <artifactId>jdom</artifactId>
|
||||
<groupId>org.jdom</groupId> </exclusion> <exclusion> <artifactId>gson</artifactId>
|
||||
<groupId>com.google.code.gson</groupId> </exclusion> </exclusions> </dependency> -->
|
||||
<!-- FHIR RI is pulled in for UCUM support, but we don't want any of its dependencies. -->
|
||||
<!-- <dependency> <groupId>me.fhir</groupId> <artifactId>fhir-dstu1</artifactId> <version>0.0.81.2489</version> <exclusions> <exclusion> <artifactId>Saxon-HE</artifactId>
|
||||
<groupId>net.sf.saxon</groupId> </exclusion> <exclusion> <artifactId>commons-discovery</artifactId> <groupId>commons-discovery</groupId> </exclusion> <exclusion>
|
||||
<artifactId>commons-codec</artifactId> <groupId>commons-codec</groupId> </exclusion> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId>
|
||||
</exclusion> <exclusion> <artifactId>xpp3</artifactId> <groupId>xpp3</groupId> </exclusion> <exclusion> <artifactId>junit</artifactId> <groupId>junit</groupId> </exclusion>
|
||||
<exclusion> <artifactId>jdom</artifactId> <groupId>org.jdom</groupId> </exclusion> <exclusion> <artifactId>gson</artifactId> <groupId>com.google.code.gson</groupId>
|
||||
</exclusion> </exclusions> </dependency> -->
|
||||
|
||||
|
||||
<!-- Test Database -->
|
||||
|
@ -126,8 +120,7 @@
|
|||
</dependency>
|
||||
|
||||
|
||||
<!-- <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId>
|
||||
<version>2.3.2</version> </dependency> -->
|
||||
<!-- <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.3.2</version> </dependency> -->
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
|
@ -162,6 +155,10 @@
|
|||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
|
@ -226,7 +223,7 @@
|
|||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
|
@ -252,7 +249,7 @@
|
|||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
@ -277,84 +274,14 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--
|
||||
These tests all use a shared database, so it's easier if
|
||||
they run in a predictable order
|
||||
-->
|
||||
<!-- These tests all use a shared database, so it's easier if they run in a predictable order -->
|
||||
<runOrder>alphabetical</runOrder>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>de.juplo</groupId>
|
||||
<artifactId>hibernate4-maven-plugin</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<configuration>
|
||||
<force>true</force>
|
||||
<target>SCRIPT</target>
|
||||
<skip>${skip-hib4}</skip>
|
||||
</configuration>
|
||||
<!--
|
||||
This needs to be uncommented in order for this plugin to work with
|
||||
Hibernate 4.3+ (as of hibernate4-maven-plugin version 1.0.5)
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${hibernate_version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
-->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>o10g</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.Oracle10gDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_oracle_10g.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>derby</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.DerbyTenSevenDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_derby.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>hsql</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.HSQLDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_hsql.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>mysql5</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.MySQL5Dialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_mysql_5.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-tinder-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>build_dstu1</id>
|
||||
|
@ -389,12 +316,12 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
|
@ -413,11 +340,10 @@
|
|||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<version>${maven_jxr_plugin_version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
@ -429,6 +355,70 @@
|
|||
<skip-hib4>true</skip-hib4>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>DIST</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>de.juplo</groupId>
|
||||
<artifactId>hibernate4-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<force>true</force>
|
||||
<target>SCRIPT</target>
|
||||
<skip>${skip-hib4}</skip>
|
||||
</configuration>
|
||||
<!-- This needs to be uncommented in order for this plugin to work with Hibernate 4.3+ (as of hibernate4-maven-plugin version 1.0.5) <dependencies> <dependency>
|
||||
<groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate_version}</version> </dependency> </dependencies> -->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>o10g</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.Oracle10gDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_oracle_10g.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>derby</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.DerbyTenSevenDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_derby.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>hsql</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.HSQLDialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_hsql.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>mysql5</id>
|
||||
<goals>
|
||||
<goal>export</goal>
|
||||
</goals>
|
||||
<phase>test</phase>
|
||||
<configuration>
|
||||
<hibernateDialect>org.hibernate.dialect.MySQL5Dialect</hibernateDialect>
|
||||
<outputFile>${project.build.directory}/schema_mysql_5.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -166,8 +166,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
return InstantDt.withCurrentTime();
|
||||
}
|
||||
|
||||
protected List<ResourceLink> extractResourceLinks(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceLink> retVal = new ArrayList<ResourceLink>();
|
||||
protected Set<ResourceLink> extractResourceLinks(ResourceTable theEntity, IResource theResource) {
|
||||
Set<ResourceLink> retVal = new HashSet<ResourceLink>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -185,73 +185,76 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
multiType = true;
|
||||
}
|
||||
|
||||
for (Object nextObject : extractValues(nextPathsUnsplit, theResource)) {
|
||||
if (nextObject == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ResourceLink nextEntity;
|
||||
if (nextObject instanceof BaseResourceReferenceDt) {
|
||||
BaseResourceReferenceDt nextValue = (BaseResourceReferenceDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (nextValue.getReference().isEmpty() || nextValue.getReference().getValue().startsWith("#")) {
|
||||
// This is a blank or contained resource reference
|
||||
String[] nextPathsSplit = nextPathsUnsplit.split("\\|");
|
||||
for (String nextPath : nextPathsSplit) {
|
||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String typeString = nextValue.getReference().getResourceType();
|
||||
if (isBlank(typeString)) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue());
|
||||
}
|
||||
RuntimeResourceDefinition resourceDefinition;
|
||||
try {
|
||||
resourceDefinition = getContext().getResourceDefinition(typeString);
|
||||
} catch (DataFormatException e) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Resource type is unknown or not supported on this server - " + nextValue.getReference().getValue());
|
||||
}
|
||||
ResourceLink nextEntity;
|
||||
if (nextObject instanceof BaseResourceReferenceDt) {
|
||||
BaseResourceReferenceDt nextValue = (BaseResourceReferenceDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (nextValue.getReference().isEmpty() || nextValue.getReference().getValue().startsWith("#")) {
|
||||
// This is a blank or contained resource reference
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<? extends IBaseResource> type = resourceDefinition.getImplementingClass();
|
||||
String id = nextValue.getReference().getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource ID - " + nextValue.getReference().getValue());
|
||||
}
|
||||
String typeString = nextValue.getReference().getResourceType();
|
||||
if (isBlank(typeString)) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue());
|
||||
}
|
||||
RuntimeResourceDefinition resourceDefinition;
|
||||
try {
|
||||
resourceDefinition = getContext().getResourceDefinition(typeString);
|
||||
} catch (DataFormatException e) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Resource type is unknown or not supported on this server - " + nextValue.getReference().getValue());
|
||||
}
|
||||
|
||||
IFhirResourceDao<?> dao = getDao(type);
|
||||
if (dao == null) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("This server (version ");
|
||||
b.append(myContext.getVersion().getVersion());
|
||||
b.append(") is not able to handle resources of type[");
|
||||
b.append(nextValue.getReference().getResourceType());
|
||||
b.append("] - Valid resource types for this server: ");
|
||||
b.append(myResourceTypeToDao.keySet().toString());
|
||||
Class<? extends IBaseResource> type = resourceDefinition.getImplementingClass();
|
||||
String id = nextValue.getReference().getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource ID - " + nextValue.getReference().getValue());
|
||||
}
|
||||
|
||||
throw new InvalidRequestException(b.toString());
|
||||
}
|
||||
Long valueOf;
|
||||
try {
|
||||
valueOf = translateForcedIdToPid(nextValue.getReference());
|
||||
} catch (ResourceNotFoundException e) {
|
||||
String resName = getContext().getResourceDefinition(type).getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf);
|
||||
if (target == null) {
|
||||
String resName = getContext().getResourceDefinition(type).getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
nextEntity = new ResourceLink(nextPathsUnsplit, theEntity, target);
|
||||
} else {
|
||||
if (!multiType) {
|
||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||
IFhirResourceDao<?> dao = getDao(type);
|
||||
if (dao == null) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("This server (version ");
|
||||
b.append(myContext.getVersion().getVersion());
|
||||
b.append(") is not able to handle resources of type[");
|
||||
b.append(nextValue.getReference().getResourceType());
|
||||
b.append("] - Valid resource types for this server: ");
|
||||
b.append(myResourceTypeToDao.keySet().toString());
|
||||
|
||||
throw new InvalidRequestException(b.toString());
|
||||
}
|
||||
Long valueOf;
|
||||
try {
|
||||
valueOf = translateForcedIdToPid(nextValue.getReference());
|
||||
} catch (ResourceNotFoundException e) {
|
||||
String resName = getContext().getResourceDefinition(type).getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf);
|
||||
if (target == null) {
|
||||
String resName = getContext().getResourceDefinition(type).getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
nextEntity = new ResourceLink(nextPath, theEntity, target);
|
||||
} else {
|
||||
continue;
|
||||
if (!multiType) {
|
||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (nextEntity != null) {
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
}
|
||||
if (nextEntity != null) {
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,46 +264,43 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
protected List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamDates(theEntity, theResource);
|
||||
}
|
||||
|
||||
protected List<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamNumber(theEntity, theResource);
|
||||
}
|
||||
|
||||
protected List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamUri(theEntity, theResource);
|
||||
}
|
||||
|
||||
protected List<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource);
|
||||
}
|
||||
|
||||
protected List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamQuantity(theEntity, theResource);
|
||||
}
|
||||
|
||||
protected List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamStrings(theEntity, theResource);
|
||||
}
|
||||
|
||||
protected List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
protected Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
return mySearchParamExtractor.extractSearchParamTokens(theEntity, theResource);
|
||||
}
|
||||
|
||||
private List<Object> extractValues(String thePaths, IResource theResource) {
|
||||
private List<Object> extractValues(String thePath, IResource theResource) {
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
String[] nextPathsSplit = thePaths.split("\\|");
|
||||
FhirTerser t = getContext().newTerser();
|
||||
for (String nextPath : nextPathsSplit) {
|
||||
String nextPathTrimmed = nextPath.trim();
|
||||
try {
|
||||
values.addAll(t.getValues(theResource, nextPathTrimmed));
|
||||
} catch (Exception e) {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() });
|
||||
}
|
||||
String nextPathTrimmed = thePath.trim();
|
||||
try {
|
||||
values.addAll(t.getValues(theResource, nextPathTrimmed));
|
||||
} catch (Exception e) {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() });
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
@ -520,7 +520,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
throw e;
|
||||
}
|
||||
IResource resource = (IResource) toResource(type.getImplementingClass(), next);
|
||||
IResource resource = (IResource) toResource(type.getImplementingClass(), next, true);
|
||||
retVal.add(resource);
|
||||
}
|
||||
return retVal;
|
||||
|
@ -558,12 +558,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
protected void populateResourceIntoEntity(IResource theResource, ResourceTable theEntity) {
|
||||
|
||||
if (theEntity.getPublished().isEmpty()) {
|
||||
theEntity.setPublished(new Date());
|
||||
}
|
||||
theEntity.setUpdated(new Date());
|
||||
|
||||
theEntity.setResourceType(toResourceName(theResource));
|
||||
|
||||
List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class);
|
||||
|
@ -936,13 +930,13 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
protected IBaseResource toResource(BaseHasResource theEntity) {
|
||||
protected IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation) {
|
||||
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
|
||||
return toResource(type.getImplementingClass(), theEntity);
|
||||
return toResource(type.getImplementingClass(), theEntity, theForHistoryOperation);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity) {
|
||||
protected <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation) {
|
||||
String resourceText = null;
|
||||
switch (theEntity.getEncoding()) {
|
||||
case JSON:
|
||||
|
@ -983,14 +977,29 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
res = (IResource) myContext.getResourceDefinition(theResourceType).newInstance();
|
||||
retVal = (R) res;
|
||||
ResourceMetadataKeyEnum.DELETED_AT.put(res, new InstantDt(theEntity.getDeleted()));
|
||||
ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(res, BundleEntryTransactionMethodEnum.DELETE);
|
||||
if (theForHistoryOperation) {
|
||||
ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(res, BundleEntryTransactionMethodEnum.DELETE);
|
||||
}
|
||||
} else if (theForHistoryOperation) {
|
||||
/*
|
||||
* If the create and update times match, this was when the resource was created
|
||||
* so we should mark it as a POST. Otherwise, it's a PUT.
|
||||
*/
|
||||
Date published = theEntity.getPublished().getValue();
|
||||
Date updated = theEntity.getUpdated().getValue();
|
||||
if (published.equals(updated)) {
|
||||
ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(res, BundleEntryTransactionMethodEnum.POST);
|
||||
} else {
|
||||
ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(res, BundleEntryTransactionMethodEnum.PUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
res.setId(theEntity.getIdDt());
|
||||
|
||||
ResourceMetadataKeyEnum.VERSION.put(res, Long.toString(theEntity.getVersion()));
|
||||
ResourceMetadataKeyEnum.PUBLISHED.put(res, theEntity.getPublished());
|
||||
ResourceMetadataKeyEnum.UPDATED.put(res, theEntity.getUpdated());
|
||||
IDao.RESOURCE_PID.put(res, theEntity.getId());
|
||||
|
||||
if (theEntity.getTitle() != null) {
|
||||
ResourceMetadataKeyEnum.TITLE.put(res, theEntity.getTitle());
|
||||
|
@ -1063,25 +1072,28 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
}
|
||||
|
||||
protected ResourceTable updateEntity(final IResource theResource, ResourceTable entity, boolean theUpdateHistory, Date theDeletedTimestampOrNull) {
|
||||
return updateEntity(theResource, entity, theUpdateHistory, theDeletedTimestampOrNull, true, true);
|
||||
protected ResourceTable updateEntity(final IResource theResource, ResourceTable entity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, Date theUpdateTime) {
|
||||
return updateEntity(theResource, entity, theUpdateHistory, theDeletedTimestampOrNull, true, true, theUpdateTime);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ResourceTable updateEntity(final IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion) {
|
||||
|
||||
if (theEntity.getPublished() == null) {
|
||||
theEntity.setPublished(new Date());
|
||||
}
|
||||
|
||||
protected ResourceTable updateEntity(final IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion, Date theUpdateTime) {
|
||||
|
||||
/*
|
||||
* This should be the very first thing..
|
||||
*/
|
||||
if (theResource != null) {
|
||||
validateResourceForStorage((T) theResource);
|
||||
validateResourceForStorage((T) theResource, theEntity);
|
||||
String resourceType = myContext.getResourceDefinition(theResource).getName();
|
||||
if (isNotBlank(theEntity.getResourceType()) && !theEntity.getResourceType().equals(resourceType)) {
|
||||
throw new UnprocessableEntityException("Existing resource ID[" + theEntity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + theEntity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
|
||||
}
|
||||
}
|
||||
|
||||
if (theEntity.getPublished() == null) {
|
||||
theEntity.setPublished(theUpdateTime);
|
||||
}
|
||||
|
||||
if (theUpdateHistory) {
|
||||
final ResourceHistoryTable historyEntry = theEntity.toHistory();
|
||||
myEntityManager.persist(historyEntry);
|
||||
|
@ -1109,25 +1121,25 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
Collection<ResourceIndexedSearchParamCoords> paramsCoords = new ArrayList<ResourceIndexedSearchParamCoords>(theEntity.getParamsCoords());
|
||||
Collection<ResourceLink> resourceLinks = new ArrayList<ResourceLink>(theEntity.getResourceLinks());
|
||||
|
||||
List<ResourceIndexedSearchParamString> stringParams = null;
|
||||
List<ResourceIndexedSearchParamToken> tokenParams = null;
|
||||
List<ResourceIndexedSearchParamNumber> numberParams = null;
|
||||
List<ResourceIndexedSearchParamQuantity> quantityParams = null;
|
||||
List<ResourceIndexedSearchParamDate> dateParams = null;
|
||||
List<ResourceIndexedSearchParamUri> uriParams = null;
|
||||
List<ResourceIndexedSearchParamCoords> coordsParams = null;
|
||||
List<ResourceLink> links = null;
|
||||
Set<ResourceIndexedSearchParamString> stringParams = null;
|
||||
Set<ResourceIndexedSearchParamToken> tokenParams = null;
|
||||
Set<ResourceIndexedSearchParamNumber> numberParams = null;
|
||||
Set<ResourceIndexedSearchParamQuantity> quantityParams = null;
|
||||
Set<ResourceIndexedSearchParamDate> dateParams = null;
|
||||
Set<ResourceIndexedSearchParamUri> uriParams = null;
|
||||
Set<ResourceIndexedSearchParamCoords> coordsParams = null;
|
||||
Set<ResourceLink> links = null;
|
||||
|
||||
if (theDeletedTimestampOrNull != null) {
|
||||
|
||||
stringParams = Collections.emptyList();
|
||||
tokenParams = Collections.emptyList();
|
||||
numberParams = Collections.emptyList();
|
||||
quantityParams = Collections.emptyList();
|
||||
dateParams = Collections.emptyList();
|
||||
uriParams = Collections.emptyList();
|
||||
coordsParams = Collections.emptyList();
|
||||
links = Collections.emptyList();
|
||||
stringParams = Collections.emptySet();
|
||||
tokenParams = Collections.emptySet();
|
||||
numberParams = Collections.emptySet();
|
||||
quantityParams = Collections.emptySet();
|
||||
dateParams = Collections.emptySet();
|
||||
uriParams = Collections.emptySet();
|
||||
coordsParams = Collections.emptySet();
|
||||
links = Collections.emptySet();
|
||||
theEntity.setDeleted(theDeletedTimestampOrNull);
|
||||
theEntity.setUpdated(theDeletedTimestampOrNull);
|
||||
|
||||
|
@ -1147,7 +1159,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
// ourLog.info("Indexing resource: {}", entity.getId());
|
||||
ourLog.trace("Storing string indexes: {}", stringParams);
|
||||
|
||||
tokenParams = new ArrayList<ResourceIndexedSearchParamToken>();
|
||||
tokenParams = new HashSet<ResourceIndexedSearchParamToken>();
|
||||
for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(theEntity, theResource)) {
|
||||
if (next instanceof ResourceIndexedSearchParamToken) {
|
||||
tokenParams.add((ResourceIndexedSearchParamToken) next);
|
||||
|
@ -1159,7 +1171,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
links = extractResourceLinks(theEntity, theResource);
|
||||
populateResourceIntoEntity(theResource, theEntity);
|
||||
|
||||
theEntity.setUpdated(new Date());
|
||||
theEntity.setUpdated(theUpdateTime);
|
||||
theEntity.setLanguage(theResource.getLanguage().getValue());
|
||||
theEntity.setParamsString(stringParams);
|
||||
theEntity.setParamsStringPopulated(stringParams.isEmpty() == false);
|
||||
|
@ -1178,11 +1190,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
theEntity.setResourceLinks(links);
|
||||
theEntity.setHasLinks(links.isEmpty() == false);
|
||||
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
populateResourceIntoEntity(theResource, theEntity);
|
||||
theEntity.setUpdated(new Date());
|
||||
theEntity.setUpdated(theUpdateTime);
|
||||
theEntity.setLanguage(theResource.getLanguage().getValue());
|
||||
theEntity.setIndexStatus(null);
|
||||
|
||||
|
@ -1197,8 +1209,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
myEntityManager.persist(theEntity.getForcedId());
|
||||
}
|
||||
|
||||
postPersist(theEntity, (T) theResource);
|
||||
|
||||
} else {
|
||||
theEntity = myEntityManager.merge(theEntity);
|
||||
|
||||
postUpdate(theEntity, (T) theResource);
|
||||
}
|
||||
|
||||
if (thePerformIndexing) {
|
||||
|
@ -1289,6 +1305,30 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
return theEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override to provide behaviour. Called when a resource has been inserved into the database for the
|
||||
* first time.
|
||||
*
|
||||
* @param theEntity
|
||||
* The resource
|
||||
* @param theResource The resource being persisted
|
||||
*/
|
||||
protected void postUpdate(ResourceTable theEntity, T theResource) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override to provide behaviour. Called when a resource has been inserved into the database for the
|
||||
* first time.
|
||||
*
|
||||
* @param theEntity
|
||||
* The resource
|
||||
* @param theResource The resource being persisted
|
||||
*/
|
||||
protected void postPersist(ResourceTable theEntity, T theResource) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked immediately before storing a new resource, or an update to an existing resource to allow
|
||||
* the DAO to ensure that it is valid for persistence. By default, checks for the "subsetted" tag and rejects
|
||||
|
@ -1296,8 +1336,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
*
|
||||
* @param theResource
|
||||
* The resource that is about to be persisted
|
||||
* @param theEntityToSave TODO
|
||||
*/
|
||||
protected void validateResourceForStorage(T theResource) {
|
||||
protected void validateResourceForStorage(T theResource, ResourceTable theEntityToSave) {
|
||||
IResource res = (IResource) theResource;
|
||||
TagList tagList = ResourceMetadataKeyEnum.TAG_LIST.get(res);
|
||||
if (tagList != null) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.INDEX_NOT_FOUND;
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
|
@ -143,7 +142,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirResourceDao.class);
|
||||
|
||||
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
||||
private EntityManager myEntityManager;
|
||||
protected EntityManager myEntityManager;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager myPlatformTransactionManager;
|
||||
|
@ -246,9 +245,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
HashSet<Long> found = new HashSet<Long>(q.getResultList());
|
||||
if (!theExistingPids.isEmpty()) {
|
||||
theExistingPids.retainAll(found);
|
||||
return theExistingPids;
|
||||
} else {
|
||||
return found;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// private Set<Long> addPredicateComposite(String theParamName, Set<Long> thePids, List<? extends
|
||||
|
@ -256,49 +256,54 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
// }
|
||||
|
||||
private Set<Long> addPredicateLanguage(Set<Long> thePids, List<List<? extends IQueryParameterType>> theList) {
|
||||
Set<Long> retVal = thePids;
|
||||
if (theList == null || theList.isEmpty()) {
|
||||
return thePids;
|
||||
}
|
||||
if (theList.size() > 1) {
|
||||
throw new InvalidRequestException("Language parameter can not have more than one AND value, found " + theList.size());
|
||||
return retVal;
|
||||
}
|
||||
for (List<? extends IQueryParameterType> nextList : theList) {
|
||||
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
cq.select(from.get("myId").as(Long.class));
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
cq.select(from.get("myId").as(Long.class));
|
||||
|
||||
Set<String> values = new HashSet<String>();
|
||||
for (IQueryParameterType next : theList.get(0)) {
|
||||
if (next instanceof StringParam) {
|
||||
String nextValue = ((StringParam) next).getValue();
|
||||
if (isBlank(nextValue)) {
|
||||
continue;
|
||||
Set<String> values = new HashSet<String>();
|
||||
for (IQueryParameterType next : nextList) {
|
||||
if (next instanceof StringParam) {
|
||||
String nextValue = ((StringParam) next).getValue();
|
||||
if (isBlank(nextValue)) {
|
||||
continue;
|
||||
}
|
||||
values.add(nextValue);
|
||||
} else {
|
||||
throw new InternalErrorException("Lanugage parameter must be of type " + StringParam.class.getCanonicalName() + " - Got " + next.getClass().getCanonicalName());
|
||||
}
|
||||
values.add(nextValue);
|
||||
}
|
||||
|
||||
if (values.isEmpty()) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Predicate typePredicate = builder.equal(from.get("myResourceType"), myResourceName);
|
||||
Predicate langPredicate = from.get("myLanguage").as(String.class).in(values);
|
||||
Predicate masterCodePredicate = builder.and(typePredicate, langPredicate);
|
||||
Predicate notDeletedPredicate = builder.isNull(from.get("myDeleted"));
|
||||
|
||||
if (retVal.size() > 0) {
|
||||
Predicate inPids = (from.get("myId").in(retVal));
|
||||
cq.where(builder.and(masterCodePredicate, inPids, notDeletedPredicate));
|
||||
} else {
|
||||
throw new InternalErrorException("Lanugage parameter must be of type " + StringParam.class.getCanonicalName() + " - Got " + next.getClass().getCanonicalName());
|
||||
cq.where(builder.and(masterCodePredicate, notDeletedPredicate));
|
||||
}
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
retVal = new HashSet<Long>(q.getResultList());
|
||||
if (retVal.isEmpty()) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
if (values.isEmpty()) {
|
||||
return thePids;
|
||||
}
|
||||
|
||||
Predicate typePredicate = builder.equal(from.get("myResourceType"), myResourceName);
|
||||
Predicate langPredicate = from.get("myLanguage").as(String.class).in(values);
|
||||
Predicate masterCodePredicate = builder.and(typePredicate, langPredicate);
|
||||
Predicate notDeletedPredicate = builder.isNull(from.get("myDeleted"));
|
||||
|
||||
if (thePids.size() > 0) {
|
||||
Predicate inPids = (from.get("myId").in(thePids));
|
||||
cq.where(builder.and(masterCodePredicate, inPids, notDeletedPredicate));
|
||||
} else {
|
||||
cq.where(builder.and(masterCodePredicate, notDeletedPredicate));
|
||||
}
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
return new HashSet<Long>(q.getResultList());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private boolean addPredicateMissingFalseIfPresent(CriteriaBuilder theBuilder, String theParamName, Root<? extends BaseResourceIndexedSearchParam> from, List<Predicate> codePredicates, IQueryParameterType nextOr) {
|
||||
|
@ -1005,7 +1010,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
}
|
||||
|
||||
return doCreate(theResource, theIfNoneExist, thePerformIndexing);
|
||||
return doCreate(theResource, theIfNoneExist, thePerformIndexing, new Date());
|
||||
}
|
||||
|
||||
private Predicate createCompositeParamPart(CriteriaBuilder builder, Root<ResourceTable> from, RuntimeSearchParam left, IQueryParameterType leftValue) {
|
||||
|
@ -1269,7 +1274,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
ActionRequestDetails requestDetails = new ActionRequestDetails(theId, theId.getResourceType());
|
||||
notifyInterceptors(RestOperationTypeEnum.DELETE, requestDetails);
|
||||
|
||||
ResourceTable savedEntity = updateEntity(null, entity, true, new Date());
|
||||
Date updateTime = new Date();
|
||||
ResourceTable savedEntity = updateEntity(null, entity, true, updateTime, updateTime);
|
||||
|
||||
notifyWriteCompleted();
|
||||
|
||||
|
@ -1299,14 +1305,15 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
notifyInterceptors(RestOperationTypeEnum.DELETE, requestDetails);
|
||||
|
||||
// Perform delete
|
||||
ResourceTable savedEntity = updateEntity(null, entity, true, new Date());
|
||||
Date updateTime = new Date();
|
||||
ResourceTable savedEntity = updateEntity(null, entity, true, updateTime, updateTime);
|
||||
notifyWriteCompleted();
|
||||
|
||||
ourLog.info("Processed delete on {} in {}ms", theUrl, w.getMillisAndRestart());
|
||||
return toMethodOutcome(savedEntity, null);
|
||||
}
|
||||
|
||||
private DaoMethodOutcome doCreate(T theResource, String theIfNoneExist, boolean thePerformIndexing) {
|
||||
private DaoMethodOutcome doCreate(T theResource, String theIfNoneExist, boolean thePerformIndexing, Date theUpdateTime) {
|
||||
StopWatch w = new StopWatch();
|
||||
|
||||
preProcessResourceForStorage(theResource);
|
||||
|
@ -1347,7 +1354,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
ActionRequestDetails requestDetails = new ActionRequestDetails(theResource.getId(), toResourceName(theResource), theResource);
|
||||
notifyInterceptors(RestOperationTypeEnum.CREATE, requestDetails);
|
||||
|
||||
updateEntity(theResource, entity, false, null, thePerformIndexing, true);
|
||||
updateEntity(theResource, entity, false, null, thePerformIndexing, true, theUpdateTime);
|
||||
|
||||
DaoMethodOutcome outcome = toMethodOutcome(entity, theResource).setCreated(true);
|
||||
|
||||
|
@ -1420,7 +1427,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
try {
|
||||
BaseHasResource entity = readEntity(theId.toVersionless(), false);
|
||||
validateResourceType(entity);
|
||||
currentTmp = toResource(myResourceType, entity);
|
||||
currentTmp = toResource(myResourceType, entity, true);
|
||||
if (ResourceMetadataKeyEnum.UPDATED.get(currentTmp).after(end.getValue())) {
|
||||
currentTmp = null;
|
||||
}
|
||||
|
@ -1497,7 +1504,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
if (retVal.size() == maxResults) {
|
||||
break;
|
||||
}
|
||||
retVal.add(toResource(myResourceType, next));
|
||||
retVal.add(toResource(myResourceType, next, true));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
@ -1528,7 +1535,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids) {
|
||||
private void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation) {
|
||||
if (theIncludePids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1547,7 +1554,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
|
||||
for (ResourceTable next : q.getResultList()) {
|
||||
Class<? extends IBaseResource> resourceType = getContext().getResourceDefinition(next.getResourceType()).getImplementingClass();
|
||||
IResource resource = (IResource) toResource(resourceType, next);
|
||||
IResource resource = (IResource) toResource(resourceType, next, theForHistoryOperation);
|
||||
Integer index = position.get(next.getId());
|
||||
if (index == null) {
|
||||
ourLog.warn("Got back unexpected resource PID {}", next.getId());
|
||||
|
@ -1828,7 +1835,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
BaseHasResource entity = readEntity(theId);
|
||||
validateResourceType(entity);
|
||||
|
||||
T retVal = toResource(myResourceType, entity);
|
||||
T retVal = toResource(myResourceType, entity, false);
|
||||
|
||||
InstantDt deleted = ResourceMetadataKeyEnum.DELETED_AT.get(retVal);
|
||||
if (deleted != null && !deleted.isEmpty()) {
|
||||
|
@ -2066,7 +2073,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
|
||||
// Execute the query and make sure we return distinct results
|
||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
loadResourcesByPid(pidsSubList, retVal, revIncludedPids);
|
||||
loadResourcesByPid(pidsSubList, retVal, revIncludedPids, false);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
@ -2126,42 +2133,41 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
|
||||
if (nextParamEntry.getValue().isEmpty()) {
|
||||
continue;
|
||||
} else if (nextParamEntry.getValue().size() > 1) {
|
||||
throw new InvalidRequestException("AND queries not supported for _id (Multiple instances of this param found)");
|
||||
} else {
|
||||
Set<Long> joinPids = new HashSet<Long>();
|
||||
List<? extends IQueryParameterType> nextValue = nextParamEntry.getValue().get(0);
|
||||
if (nextValue == null || nextValue.size() == 0) {
|
||||
continue;
|
||||
} else {
|
||||
for (IQueryParameterType next : nextValue) {
|
||||
String value = next.getValueAsQueryToken();
|
||||
IIdType valueId = new IdDt(value);
|
||||
for (List<? extends IQueryParameterType> nextValue : nextParamEntry.getValue()) {
|
||||
Set<Long> joinPids = new HashSet<Long>();
|
||||
if (nextValue == null || nextValue.size() == 0) {
|
||||
continue;
|
||||
} else {
|
||||
for (IQueryParameterType next : nextValue) {
|
||||
String value = next.getValueAsQueryToken();
|
||||
IIdType valueId = new IdDt(value);
|
||||
|
||||
try {
|
||||
BaseHasResource entity = readEntity(valueId);
|
||||
if (entity.getDeleted() != null) {
|
||||
continue;
|
||||
try {
|
||||
BaseHasResource entity = readEntity(valueId);
|
||||
if (entity.getDeleted() != null) {
|
||||
continue;
|
||||
}
|
||||
joinPids.add(entity.getId());
|
||||
} catch (ResourceNotFoundException e) {
|
||||
// This isn't an error, just means no result found
|
||||
}
|
||||
joinPids.add(entity.getId());
|
||||
} catch (ResourceNotFoundException e) {
|
||||
// This isn't an error, just means no result found
|
||||
}
|
||||
if (joinPids.isEmpty()) {
|
||||
return new HashSet<Long>();
|
||||
}
|
||||
}
|
||||
if (joinPids.isEmpty()) {
|
||||
|
||||
pids = addPredicateId(pids, joinPids);
|
||||
if (pids.isEmpty()) {
|
||||
return new HashSet<Long>();
|
||||
}
|
||||
}
|
||||
|
||||
pids = addPredicateId(pids, joinPids);
|
||||
if (pids.isEmpty()) {
|
||||
return new HashSet<Long>();
|
||||
}
|
||||
|
||||
if (pids.isEmpty()) {
|
||||
pids.addAll(joinPids);
|
||||
} else {
|
||||
pids.retainAll(joinPids);
|
||||
if (pids.isEmpty()) {
|
||||
pids.addAll(joinPids);
|
||||
} else {
|
||||
pids.retainAll(joinPids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2382,7 +2388,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
if (resourceId.isIdPartValidLong()) {
|
||||
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "failedToCreateWithClientAssignedNumericId", theResource.getId().getIdPart()));
|
||||
}
|
||||
return doCreate(theResource, null, thePerformIndexing);
|
||||
return doCreate(theResource, null, thePerformIndexing, new Date());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2399,7 +2405,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
notifyInterceptors(RestOperationTypeEnum.UPDATE, requestDetails);
|
||||
|
||||
// Perform update
|
||||
ResourceTable savedEntity = updateEntity(theResource, entity, true, null, thePerformIndexing, true);
|
||||
ResourceTable savedEntity = updateEntity(theResource, entity, true, null, thePerformIndexing, true, new Date());
|
||||
|
||||
notifyWriteCompleted();
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public abstract class BaseHapiFhirSystemDao<T> extends BaseHapiFhirDao<IBaseReso
|
|||
for (ResourceTable resourceTable : resources) {
|
||||
final IBaseResource resource;
|
||||
try {
|
||||
resource = toResource(resourceTable);
|
||||
resource = toResource(resourceTable, false);
|
||||
} catch (DataFormatException e) {
|
||||
ourLog.warn("Failure parsing resource: {}", e.toString());
|
||||
throw new UnprocessableEntityException(Long.toString(resourceTable.getId()));
|
||||
|
|
|
@ -35,6 +35,8 @@ public class DaoConfig {
|
|||
private int myIncludeLimit = 2000;
|
||||
private List<IServerInterceptor> myInterceptors;
|
||||
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
||||
private boolean mySubscriptionEnabled;
|
||||
private long mySubscriptionPollDelay = 1000;
|
||||
|
||||
/**
|
||||
* See {@link #setIncludeLimit(int)}
|
||||
|
@ -64,6 +66,17 @@ public class DaoConfig {
|
|||
return myResourceEncoding;
|
||||
}
|
||||
|
||||
public long getSubscriptionPollDelay() {
|
||||
return mySubscriptionPollDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #setSubscriptionEnabled(boolean)}
|
||||
*/
|
||||
public boolean isSubscriptionEnabled() {
|
||||
return mySubscriptionEnabled;
|
||||
}
|
||||
|
||||
public void setHardSearchLimit(int theHardSearchLimit) {
|
||||
myHardSearchLimit = theHardSearchLimit;
|
||||
}
|
||||
|
@ -90,12 +103,11 @@ public class DaoConfig {
|
|||
* ID).
|
||||
* </p>
|
||||
*/
|
||||
public void setInterceptors(List<IServerInterceptor> theInterceptors) {
|
||||
myInterceptors = theInterceptors;
|
||||
}
|
||||
|
||||
public void setResourceEncoding(ResourceEncodingEnum theResourceEncoding) {
|
||||
myResourceEncoding = theResourceEncoding;
|
||||
public void setInterceptors(IServerInterceptor... theInterceptor) {
|
||||
setInterceptors(new ArrayList<IServerInterceptor>());
|
||||
if (theInterceptor != null && theInterceptor.length != 0) {
|
||||
getInterceptors().addAll(Arrays.asList(theInterceptor));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,12 +119,27 @@ public class DaoConfig {
|
|||
* ID).
|
||||
* </p>
|
||||
*/
|
||||
public void setInterceptors(IServerInterceptor... theInterceptor) {
|
||||
if (theInterceptor == null || theInterceptor.length==0){
|
||||
setInterceptors(new ArrayList<IServerInterceptor>());
|
||||
} else {
|
||||
setInterceptors(Arrays.asList(theInterceptor));
|
||||
}
|
||||
public void setInterceptors(List<IServerInterceptor> theInterceptors) {
|
||||
myInterceptors = theInterceptors;
|
||||
}
|
||||
|
||||
public void setResourceEncoding(ResourceEncodingEnum theResourceEncoding) {
|
||||
myResourceEncoding = theResourceEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this server support subscription? If set to true, the server
|
||||
* will enable the subscription monitoring mode, which adds a bit of
|
||||
* overhead. Note that if this is enabled, you must also include
|
||||
* Spring task scanning to your XML config for the scheduled tasks
|
||||
* used by the subscription module.
|
||||
*/
|
||||
public void setSubscriptionEnabled(boolean theSubscriptionEnabled) {
|
||||
mySubscriptionEnabled = theSubscriptionEnabled;
|
||||
}
|
||||
|
||||
public void setSubscriptionPollDelay(long theSubscriptionPollDelay) {
|
||||
mySubscriptionPollDelay = theSubscriptionPollDelay;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
||||
|
@ -58,8 +59,8 @@ public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDs
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void validateResourceForStorage(QuestionnaireResponse theResource) {
|
||||
super.validateResourceForStorage(theResource);
|
||||
protected void validateResourceForStorage(QuestionnaireResponse theResource, ResourceTable theEntityToSave) {
|
||||
super.validateResourceForStorage(theResource, theEntityToSave);
|
||||
if (!myValidateResponses) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISubscriptionFlaggedResourceDataDao;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subscription>implements IFhirResourceDaoSubscription<Subscription> {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoSubscriptionDstu2.class);
|
||||
|
||||
@Autowired
|
||||
private ISubscriptionFlaggedResourceDataDao mySubscriptionFlaggedResourceDataDao;
|
||||
|
||||
private void createSubscriptionTable(ResourceTable theEntity, Subscription theSubscription) {
|
||||
SubscriptionTable subscriptionEntity = new SubscriptionTable();
|
||||
subscriptionEntity.setSubscriptionResource(theEntity);
|
||||
subscriptionEntity.setNextCheck(theEntity.getPublished().getValue());
|
||||
subscriptionEntity.setMostRecentMatch(theEntity.getPublished().getValue());
|
||||
subscriptionEntity.setStatus(theSubscription.getStatusElement().getValueAsEnum());
|
||||
myEntityManager.persist(subscriptionEntity);
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 10 * DateUtils.MILLIS_PER_SECOND)
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
@Override
|
||||
public void pollForNewUndeliveredResources() {
|
||||
if (getConfig().isSubscriptionEnabled() == false) {
|
||||
return;
|
||||
}
|
||||
ourLog.trace("Beginning pollForNewUndeliveredResources()");
|
||||
|
||||
// SubscriptionCandidateResource
|
||||
|
||||
TypedQuery<SubscriptionTable> q = myEntityManager.createNamedQuery("Q_HFJ_SUBSCRIPTION_NEXT_CHECK", SubscriptionTable.class);
|
||||
q.setParameter("next_check", new Date());
|
||||
q.setParameter("status", SubscriptionStatusEnum.ACTIVE);
|
||||
List<SubscriptionTable> subscriptions = q.getResultList();
|
||||
|
||||
for (SubscriptionTable nextSubscriptionTable : subscriptions) {
|
||||
pollForNewUndeliveredResources(nextSubscriptionTable);
|
||||
}
|
||||
}
|
||||
|
||||
private void pollForNewUndeliveredResources(SubscriptionTable theSubscriptionTable) {
|
||||
Subscription subscription = toResource(Subscription.class, theSubscriptionTable.getSubscriptionResource(), false);
|
||||
RuntimeResourceDefinition resourceDef = validateCriteriaAndReturnResourceDefinition(subscription);
|
||||
SearchParameterMap criteriaUrl = translateMatchUrl(subscription.getCriteria(), resourceDef);
|
||||
|
||||
criteriaUrl = new SearchParameterMap();//TODO:remove
|
||||
long start = theSubscriptionTable.getMostRecentMatch().getTime();
|
||||
long end = System.currentTimeMillis() - getConfig().getSubscriptionPollDelay();
|
||||
if (end <= start) {
|
||||
ourLog.trace("Skipping search for subscription");
|
||||
return;
|
||||
}
|
||||
ourLog.info("Subscription search from {} to {}", start, end);
|
||||
|
||||
DateRangeParam range = new DateRangeParam();
|
||||
range.setLowerBound(new DateParam(QuantityCompararatorEnum.GREATERTHAN, start));
|
||||
range.setUpperBound(new DateParam(QuantityCompararatorEnum.LESSTHAN, end));
|
||||
criteriaUrl.setLastUpdated(range);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> dao = getDao(resourceDef.getImplementingClass());
|
||||
IBundleProvider results = dao.search(criteriaUrl);
|
||||
if (results.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ourLog.info("Found {} new results for Subscription {}", results.size(), subscription.getId().getIdPart());
|
||||
|
||||
List<SubscriptionFlaggedResource> flags = new ArrayList<SubscriptionFlaggedResource>();
|
||||
for (IBaseResource next : results.getResources(0, results.size())) {
|
||||
SubscriptionFlaggedResource nextFlag = new SubscriptionFlaggedResource();
|
||||
// nextFlag.setResource();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postPersist(ResourceTable theEntity, Subscription theSubscription) {
|
||||
super.postPersist(theEntity, theSubscription);
|
||||
|
||||
createSubscriptionTable(theEntity, theSubscription);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceTable updateEntity(IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion, Date theUpdateTime) {
|
||||
ResourceTable retVal = super.updateEntity(theResource, theEntity, theUpdateHistory, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime);
|
||||
|
||||
Subscription resource = (Subscription) theResource;
|
||||
Long resourceId = theEntity.getId();
|
||||
if (theDeletedTimestampOrNull != null) {
|
||||
Query q = myEntityManager.createNamedQuery("Q_HFJ_SUBSCRIPTION_DELETE");
|
||||
q.setParameter("res_id", resourceId);
|
||||
q.executeUpdate();
|
||||
} else {
|
||||
Query q = myEntityManager.createNamedQuery("Q_HFJ_SUBSCRIPTION_SET_STATUS");
|
||||
q.setParameter("res_id", resourceId);
|
||||
q.setParameter("status", resource.getStatusElement().getValueAsEnum());
|
||||
if (q.executeUpdate() > 0) {
|
||||
ourLog.info("Updated subscription status for subscription {} to {}", resourceId, resource.getStatusElement().getValueAsEnum());
|
||||
} else {
|
||||
createSubscriptionTable(retVal, resource);
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResourceForStorage(Subscription theResource, ResourceTable theEntityToSave) {
|
||||
super.validateResourceForStorage(theResource, theEntityToSave);
|
||||
|
||||
RuntimeResourceDefinition resDef = validateCriteriaAndReturnResourceDefinition(theResource);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> dao = getDao(resDef.getImplementingClass());
|
||||
if (dao == null) {
|
||||
throw new UnprocessableEntityException("Subscription.criteria contains invalid/unsupported resource type: " + resDef);
|
||||
}
|
||||
|
||||
if (theResource.getChannel().getType() == null) {
|
||||
throw new UnprocessableEntityException("Subscription.channel.type must be populated on this server");
|
||||
}
|
||||
|
||||
SubscriptionStatusEnum status = theResource.getStatusElement().getValueAsEnum();
|
||||
if (status == null) {
|
||||
throw new UnprocessableEntityException("Subscription.status must be populated on this server");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private RuntimeResourceDefinition validateCriteriaAndReturnResourceDefinition(Subscription theResource) {
|
||||
String query = theResource.getCriteria();
|
||||
if (isBlank(query)) {
|
||||
throw new UnprocessableEntityException("Subscription.criteria must be populated");
|
||||
}
|
||||
|
||||
int sep = query.indexOf('?');
|
||||
if (sep <= 1) {
|
||||
throw new UnprocessableEntityException("Subscription.criteria must be in the form \"{Resource Type}?[params]\"");
|
||||
}
|
||||
|
||||
String resType = query.substring(0, sep);
|
||||
if (resType.contains("/")) {
|
||||
throw new UnprocessableEntityException("Subscription.criteria must be in the form \"{Resource Type}?[params]\"");
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition resDef;
|
||||
try {
|
||||
resDef = getContext().getResourceDefinition(resType);
|
||||
} catch (DataFormatException e) {
|
||||
throw new UnprocessableEntityException("Subscription.criteria contains invalid/unsupported resource type: " + resType);
|
||||
}
|
||||
return resDef;
|
||||
}
|
||||
|
||||
}
|
|
@ -60,7 +60,7 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
|
|||
if (sourceEntity == null) {
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
ValueSet source = (ValueSet) toResource(sourceEntity);
|
||||
ValueSet source = (ValueSet) toResource(sourceEntity, false);
|
||||
|
||||
/*
|
||||
* Add composed concepts
|
||||
|
|
|
@ -104,6 +104,7 @@ public class FhirSystemDaoDstu1 extends BaseHapiFhirSystemDao<List<IResource>> {
|
|||
OperationOutcome oo = new OperationOutcome();
|
||||
retVal.add(oo);
|
||||
|
||||
Date updateTime = new Date();
|
||||
for (int resourceIdx = 0; resourceIdx < theResources.size(); resourceIdx++) {
|
||||
IResource nextResource = theResources.get(resourceIdx);
|
||||
|
||||
|
@ -160,6 +161,8 @@ public class FhirSystemDaoDstu1 extends BaseHapiFhirSystemDao<List<IResource>> {
|
|||
if (entity == null) {
|
||||
nextResouceOperationOut = BundleEntryTransactionMethodEnum.POST;
|
||||
entity = toEntity(nextResource);
|
||||
entity.setUpdated(updateTime);
|
||||
entity.setPublished(updateTime);
|
||||
if (nextId.isEmpty() == false && "cid:".equals(nextId.getBaseUrl())) {
|
||||
ourLog.debug("Resource in transaction has ID[{}], will replace with server assigned ID", nextId.getIdPart());
|
||||
} else if (nextResouceOperationIn == BundleEntryTransactionMethodEnum.POST) {
|
||||
|
@ -170,7 +173,7 @@ public class FhirSystemDaoDstu1 extends BaseHapiFhirSystemDao<List<IResource>> {
|
|||
if (candidateMatches.size() == 1) {
|
||||
ourLog.debug("Resource with match URL [{}] already exists, will be NOOP", matchUrl);
|
||||
BaseHasResource existingEntity = loadFirstEntityFromCandidateMatches(candidateMatches);
|
||||
IResource existing = (IResource) toResource(existingEntity);
|
||||
IResource existing = (IResource) toResource(existingEntity, false);
|
||||
persistedResources.add(null);
|
||||
retVal.add(existing);
|
||||
continue;
|
||||
|
@ -262,11 +265,11 @@ public class FhirSystemDaoDstu1 extends BaseHapiFhirSystemDao<List<IResource>> {
|
|||
InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(resource);
|
||||
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
|
||||
if (deletedInstantOrNull == null && ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get(resource) == BundleEntryTransactionMethodEnum.DELETE) {
|
||||
deletedTimestampOrNull = new Date();
|
||||
deletedTimestampOrNull = updateTime;
|
||||
ResourceMetadataKeyEnum.DELETED_AT.put(resource, new InstantDt(deletedTimestampOrNull));
|
||||
}
|
||||
|
||||
updateEntity(resource, table, table.getId() != null, deletedTimestampOrNull);
|
||||
updateEntity(resource, table, table.getId() != null, deletedTimestampOrNull, updateTime);
|
||||
}
|
||||
|
||||
long delay = System.currentTimeMillis() - start;
|
||||
|
|
|
@ -19,7 +19,9 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -64,6 +66,8 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil.UrlParts;
|
||||
|
||||
public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2.class);
|
||||
|
@ -92,10 +96,10 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
resp.addEntry().setResource(ooResp);
|
||||
|
||||
/*
|
||||
* For batch, we handle each entry as a mini-transaction in its own
|
||||
* database transaction so that if one fails, it doesn't prevent others
|
||||
* For batch, we handle each entry as a mini-transaction in its own database transaction so that if one fails, it
|
||||
* doesn't prevent others
|
||||
*/
|
||||
|
||||
|
||||
for (final Entry nextRequestEntry : theRequest.getEntry()) {
|
||||
|
||||
TransactionCallback<Bundle> callback = new TransactionCallback<Bundle>() {
|
||||
|
@ -118,13 +122,13 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
Entry subResponseEntry = nextResponseBundle.getEntry().get(0);
|
||||
resp.addEntry(subResponseEntry);
|
||||
/*
|
||||
* If the individual entry didn't have a resource in its response, bring the
|
||||
* sub-transaction's OperationOutcome across so the client can see it
|
||||
* If the individual entry didn't have a resource in its response, bring the sub-transaction's
|
||||
* OperationOutcome across so the client can see it
|
||||
*/
|
||||
if (subResponseEntry.getResource() == null) {
|
||||
subResponseEntry.setResource(nextResponseBundle.getEntry().get(0).getResource());
|
||||
}
|
||||
|
||||
|
||||
} catch (BaseServerResponseException e) {
|
||||
caughtEx = e;
|
||||
} catch (Throwable t) {
|
||||
|
@ -167,75 +171,6 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private UrlParts parseUrl(String theAction, String theUrl) {
|
||||
UrlParts retVal = new UrlParts();
|
||||
|
||||
//@formatter:off
|
||||
/*
|
||||
* We assume that the URL passed in is in one of the following forms:
|
||||
* [Resource Type]?[Search Params]
|
||||
* [Resource Type]/[Resource ID]
|
||||
* [Resource Type]/[Resource ID]/_history/[Version ID]
|
||||
*/
|
||||
//@formatter:on
|
||||
int nextStart = 0;
|
||||
boolean nextIsHistory = false;
|
||||
|
||||
for (int idx = 0; idx < theUrl.length(); idx++) {
|
||||
char nextChar = theUrl.charAt(idx);
|
||||
boolean atEnd = (idx + 1) == theUrl.length();
|
||||
if (nextChar == '?' || nextChar == '/' || atEnd) {
|
||||
int endIdx = atEnd ? idx + 1 : idx;
|
||||
String nextSubstring = theUrl.substring(nextStart, endIdx);
|
||||
if (retVal.getResourceType() == null) {
|
||||
retVal.setResourceType(nextSubstring);
|
||||
} else if (retVal.getResourceId() == null) {
|
||||
retVal.setResourceId(nextSubstring);
|
||||
} else if (nextIsHistory) {
|
||||
retVal.setVersionId(nextSubstring);
|
||||
} else {
|
||||
if (nextSubstring.equals(Constants.URL_TOKEN_HISTORY)) {
|
||||
nextIsHistory = true;
|
||||
} else {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theAction, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
}
|
||||
if (nextChar == '?') {
|
||||
if (theUrl.length() > idx + 1) {
|
||||
retVal.setParams(theUrl.substring(idx + 1, theUrl.length()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
nextStart = idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition resType;
|
||||
try {
|
||||
resType = getContext().getResourceDefinition(retVal.getResourceType());
|
||||
} catch (DataFormatException e) {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theAction, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
IFhirResourceDao<? extends IBaseResource> dao = null;
|
||||
if (resType != null) {
|
||||
dao = getDao(resType.getImplementingClass());
|
||||
}
|
||||
if (dao == null) {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theAction, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
retVal.setDao(dao);
|
||||
|
||||
if (retVal.getResourceId() == null && retVal.getParams() == null) {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theAction, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
@Override
|
||||
public Bundle transaction(Bundle theRequest) {
|
||||
|
@ -265,6 +200,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
ourLog.info("Beginning {} with {} resources", theActionName, theRequest.getEntry().size());
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
Date updateTime = new Date();
|
||||
|
||||
Set<IdDt> allIds = new LinkedHashSet<IdDt>();
|
||||
Map<IdDt, IdDt> idSubstitutions = new HashMap<IdDt, IdDt>();
|
||||
|
@ -275,11 +211,11 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
// TODO: process verbs in the correct order
|
||||
|
||||
for (int i = 0; i < theRequest.getEntry().size(); i++) {
|
||||
|
||||
|
||||
if (i % 100 == 0) {
|
||||
ourLog.info("Processed {} entries out of {}", i, theRequest.getEntry().size());
|
||||
}
|
||||
|
||||
|
||||
Entry nextEntry = theRequest.getEntry().get(i);
|
||||
IResource res = nextEntry.getResource();
|
||||
IdDt nextResourceId = null;
|
||||
|
@ -330,11 +266,12 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
// DELETE
|
||||
Entry newEntry = response.addEntry();
|
||||
String url = extractTransactionUrlOrThrowException(nextEntry, verb);
|
||||
UrlParts parts = parseUrl(verb.getCode(), url);
|
||||
UrlParts parts = UrlUtil.parseUrl(url);
|
||||
ca.uhn.fhir.jpa.dao.IFhirResourceDao<? extends IBaseResource> dao = toDao(parts, verb.getCode(), url);
|
||||
if (parts.getResourceId() != null) {
|
||||
parts.getDao().delete(new IdDt(parts.getResourceType(), parts.getResourceId()));
|
||||
dao.delete(new IdDt(parts.getResourceType(), parts.getResourceId()));
|
||||
} else {
|
||||
parts.getDao().deleteByUrl(parts.getResourceType() + '?' + parts.getParams());
|
||||
dao.deleteByUrl(parts.getResourceType() + '?' + parts.getParams());
|
||||
}
|
||||
|
||||
newEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_204_NO_CONTENT));
|
||||
|
@ -350,7 +287,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
|
||||
String url = extractTransactionUrlOrThrowException(nextEntry, verb);
|
||||
|
||||
UrlParts parts = parseUrl(verb.getCode(), url);
|
||||
UrlParts parts = UrlUtil.parseUrl(url);
|
||||
if (isNotBlank(parts.getResourceId())) {
|
||||
res.setId(new IdDt(parts.getResourceType(), parts.getResourceId()));
|
||||
outcome = resourceDao.update(res, null, false);
|
||||
|
@ -365,10 +302,10 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
case GET: {
|
||||
// SEARCH/READ/VREAD
|
||||
String url = extractTransactionUrlOrThrowException(nextEntry, verb);
|
||||
UrlParts parts = parseUrl(verb.getCode(), url);
|
||||
UrlParts parts = UrlUtil.parseUrl(url);
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
IFhirResourceDao resourceDao = parts.getDao();
|
||||
IFhirResourceDao dao = toDao(parts, verb.getCode(), url);
|
||||
|
||||
String ifNoneMatch = nextEntry.getRequest().getIfNoneMatch();
|
||||
if (isNotBlank(ifNoneMatch)) {
|
||||
|
@ -382,9 +319,9 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
if (isNotBlank(ifNoneMatch)) {
|
||||
throw new InvalidRequestException("Unable to perform vread on '" + url + "' with ifNoneMatch also set. Do not include a version in the URL to perform a conditional read.");
|
||||
}
|
||||
found = (IResource) resourceDao.read(new IdDt(parts.getResourceType(), parts.getResourceId(), parts.getVersionId()));
|
||||
found = (IResource) dao.read(new IdDt(parts.getResourceType(), parts.getResourceId(), parts.getVersionId()));
|
||||
} else {
|
||||
found = (IResource) resourceDao.read(new IdDt(parts.getResourceType(), parts.getResourceId()));
|
||||
found = (IResource) dao.read(new IdDt(parts.getResourceType(), parts.getResourceId()));
|
||||
if (isNotBlank(ifNoneMatch) && ifNoneMatch.equals(found.getId().getVersionIdPart())) {
|
||||
notChanged = true;
|
||||
}
|
||||
|
@ -402,9 +339,9 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
resp.setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED));
|
||||
}
|
||||
} else if (parts.getParams() != null) {
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(parts.getDao().getResourceType());
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(dao.getResourceType());
|
||||
SearchParameterMap params = translateMatchUrl(url, def);
|
||||
IBundleProvider bundle = parts.getDao().search(params);
|
||||
IBundleProvider bundle = dao.search(params);
|
||||
|
||||
Bundle searchBundle = new Bundle();
|
||||
searchBundle.setTotal(bundle.size());
|
||||
|
@ -453,7 +390,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
|
||||
InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(nextResource);
|
||||
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
|
||||
updateEntity(nextResource, nextOutcome.getEntity(), false, deletedTimestampOrNull, true, false);
|
||||
updateEntity(nextResource, nextOutcome.getEntity(), false, deletedTimestampOrNull, true, false, updateTime);
|
||||
}
|
||||
|
||||
myEntityManager.flush();
|
||||
|
@ -468,8 +405,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
IFhirResourceDao<?> resourceDao = getDao(nextEntry.getResource().getClass());
|
||||
Set<Long> val = resourceDao.processMatchUrl(matchUrl);
|
||||
if (val.size() > 1) {
|
||||
throw new InvalidRequestException(
|
||||
"Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
|
||||
throw new InvalidRequestException("Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,13 +424,38 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
|
||||
long delay = System.currentTimeMillis() - start;
|
||||
ourLog.info(theActionName + " completed in {}ms", new Object[] { delay });
|
||||
|
||||
|
||||
notifyWriteCompleted();
|
||||
|
||||
response.setType(BundleTypeEnum.TRANSACTION_RESPONSE);
|
||||
return response;
|
||||
}
|
||||
|
||||
private ca.uhn.fhir.jpa.dao.IFhirResourceDao<? extends IBaseResource> toDao(UrlParts theParts, String theVerb, String theUrl) {
|
||||
RuntimeResourceDefinition resType;
|
||||
try {
|
||||
resType = getContext().getResourceDefinition(theParts.getResourceType());
|
||||
} catch (DataFormatException e) {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theVerb, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
IFhirResourceDao<? extends IBaseResource> dao = null;
|
||||
if (resType != null) {
|
||||
dao = getDao(resType.getImplementingClass());
|
||||
}
|
||||
if (dao == null) {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theVerb, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
|
||||
if (theParts.getResourceId() == null && theParts.getParams() == null) {
|
||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theVerb, theUrl);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
|
||||
return dao;
|
||||
}
|
||||
|
||||
private IFhirResourceDao<?> getDaoOrThrowException(Class<? extends IResource> theClass) {
|
||||
IFhirResourceDao<? extends IResource> retVal = getDao(theClass);
|
||||
if (retVal == null) {
|
||||
|
@ -503,15 +464,15 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
|
||||
Entry newEntry, String theResourceType, IResource theRes) {
|
||||
private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome, Entry newEntry, String theResourceType, IResource theRes) {
|
||||
IdDt newId = (IdDt) outcome.getId().toUnqualifiedVersionless();
|
||||
IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
|
||||
if (newId.equals(resourceId) == false) {
|
||||
idSubstitutions.put(resourceId, newId);
|
||||
if (isPlaceholder(resourceId)) {
|
||||
/*
|
||||
* The correct way for substitution IDs to be is to be with no resource type, but we'll accept the qualified kind too just to be lenient.
|
||||
* The correct way for substitution IDs to be is to be with no resource type, but we'll accept the qualified
|
||||
* kind too just to be lenient.
|
||||
*/
|
||||
idSubstitutions.put(new IdDt(theResourceType + '/' + resourceId.getValue()), newId);
|
||||
}
|
||||
|
@ -538,52 +499,4 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
|
||||
}
|
||||
|
||||
private static class UrlParts {
|
||||
private IFhirResourceDao<? extends IBaseResource> myDao;
|
||||
private String myParams;
|
||||
private String myResourceId;
|
||||
private String myResourceType;
|
||||
private String myVersionId;
|
||||
|
||||
public IFhirResourceDao<? extends IBaseResource> getDao() {
|
||||
return myDao;
|
||||
}
|
||||
|
||||
public String getParams() {
|
||||
return myParams;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return myResourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
}
|
||||
|
||||
public String getVersionId() {
|
||||
return myVersionId;
|
||||
}
|
||||
|
||||
public void setDao(IFhirResourceDao<? extends IBaseResource> theDao) {
|
||||
myDao = theDao;
|
||||
}
|
||||
|
||||
public void setParams(String theParams) {
|
||||
myParams = theParams;
|
||||
}
|
||||
|
||||
public void setResourceId(String theResourceId) {
|
||||
myResourceId = theResourceId;
|
||||
}
|
||||
|
||||
public void setResourceType(String theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
}
|
||||
|
||||
public void setVersionId(String theVersionId) {
|
||||
myVersionId = theVersionId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
|
@ -22,6 +25,21 @@ package ca.uhn.fhir.jpa.dao;
|
|||
|
||||
public interface IDao {
|
||||
|
||||
void registerDaoListener(IDaoListener theListener);
|
||||
public static final ResourceMetadataKeyEnum<Long> RESOURCE_PID = new ResourceMetadataKeyEnum<Long>("RESOURCE_PID") {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Long get(IResource theResource) {
|
||||
return (Long) theResource.getResourceMetadata().get(RESOURCE_PID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(IResource theResource, Long theObject) {
|
||||
theResource.getResourceMetadata().put(RESOURCE_PID, theObject);
|
||||
}
|
||||
};
|
||||
|
||||
void registerDaoListener(IDaoListener theListener);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
public interface IFhirResourceDaoSubscription<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
void pollForNewUndeliveredResources();
|
||||
|
||||
}
|
|
@ -1,27 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords;
|
||||
|
@ -35,18 +14,18 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
|
||||
interface ISearchParamExtractor {
|
||||
|
||||
public abstract List<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
public abstract List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
public abstract ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
public abstract List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
public abstract List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
public abstract List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
public abstract List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource);
|
||||
public abstract Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource);
|
||||
|
||||
}
|
||||
|
|
|
@ -75,13 +75,13 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
|
||||
return Collections.emptyList();
|
||||
public Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamDate> retVal = new ArrayList<ResourceIndexedSearchParamDate>();
|
||||
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamDate> retVal = new HashSet<ResourceIndexedSearchParamDate>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -135,8 +135,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamNumber> retVal = new ArrayList<ResourceIndexedSearchParamNumber>();
|
||||
public HashSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamNumber> retVal = new HashSet<ResourceIndexedSearchParamNumber>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -230,8 +230,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamQuantity> retVal = new ArrayList<ResourceIndexedSearchParamQuantity>();
|
||||
public Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamQuantity> retVal = new HashSet<ResourceIndexedSearchParamQuantity>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -278,8 +278,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
|
||||
public Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamString> retVal = new HashSet<ResourceIndexedSearchParamString>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -364,8 +364,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<BaseResourceIndexedSearchParam> retVal = new ArrayList<BaseResourceIndexedSearchParam>();
|
||||
public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<BaseResourceIndexedSearchParam> retVal = new HashSet<BaseResourceIndexedSearchParam>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -472,8 +472,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
|
||||
return Collections.emptyList();
|
||||
public Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
super(theContext);
|
||||
}
|
||||
|
||||
private void addSearchTerm(ResourceTable theEntity, ArrayList<ResourceIndexedSearchParamString> retVal, String resourceName, String searchTerm) {
|
||||
private void addSearchTerm(ResourceTable theEntity, Set<ResourceIndexedSearchParamString> retVal, String resourceName, String searchTerm) {
|
||||
if (isBlank(searchTerm)) {
|
||||
return;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
retVal.add(nextEntity);
|
||||
}
|
||||
|
||||
private void addStringParam(ResourceTable theEntity, ArrayList<BaseResourceIndexedSearchParam> retVal, RuntimeSearchParam nextSpDef, String value) {
|
||||
private void addStringParam(ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> retVal, RuntimeSearchParam nextSpDef, String value) {
|
||||
if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
||||
value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
|
||||
}
|
||||
|
@ -107,9 +107,9 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
|
||||
public Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
|
||||
// TODO: implement
|
||||
return Collections.emptyList();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -118,8 +118,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamDate> retVal = new ArrayList<ResourceIndexedSearchParamDate>();
|
||||
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamDate> retVal = new HashSet<ResourceIndexedSearchParamDate>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -178,8 +178,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamNumber> retVal = new ArrayList<ResourceIndexedSearchParamNumber>();
|
||||
public HashSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamNumber> retVal = new HashSet<ResourceIndexedSearchParamNumber>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -272,8 +272,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamQuantity> retVal = new ArrayList<ResourceIndexedSearchParamQuantity>();
|
||||
public Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamQuantity> retVal = new HashSet<ResourceIndexedSearchParamQuantity>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -326,8 +326,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
|
||||
public Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamString> retVal = new HashSet<ResourceIndexedSearchParamString>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -407,8 +407,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<BaseResourceIndexedSearchParam> retVal = new ArrayList<BaseResourceIndexedSearchParam>();
|
||||
public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<BaseResourceIndexedSearchParam> retVal = new HashSet<BaseResourceIndexedSearchParam>();
|
||||
|
||||
String useSystem = null;
|
||||
if (theResource instanceof ValueSet) {
|
||||
|
@ -556,8 +556,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
|
||||
ArrayList<ResourceIndexedSearchParamUri> retVal = new ArrayList<ResourceIndexedSearchParamUri>();
|
||||
public Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
|
||||
HashSet<ResourceIndexedSearchParamUri> retVal = new HashSet<ResourceIndexedSearchParamUri>();
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
@ -608,13 +608,13 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
|
||||
|
||||
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConceptDt theCodeableConcept, ResourceTable theEntity,
|
||||
ArrayList<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
for (CodingDt nextCoding : theCodeableConcept.getCoding()) {
|
||||
extractTokensFromCoding(theSystems, theCodes, theEntity, theListToPopulate, theParameterDef, nextCoding);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, ArrayList<BaseResourceIndexedSearchParam> theListToPopulate,
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate,
|
||||
RuntimeSearchParam theParameterDef, CodingDt nextCoding) {
|
||||
if (nextCoding != null && !nextCoding.isEmpty()) {
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ package ca.uhn.fhir.jpa.dao;
|
|||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -36,7 +36,7 @@ import ca.uhn.fhir.model.api.Include;
|
|||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
|
||||
public class SearchParameterMap extends HashMap<String, List<List<? extends IQueryParameterType>>> {
|
||||
public class SearchParameterMap extends LinkedHashMap<String, List<List<? extends IQueryParameterType>>> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.dao.data;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource;
|
||||
|
||||
public interface ISubscriptionFlaggedResourceDataDao extends CrudRepository<SubscriptionFlaggedResource, Long> {
|
||||
|
||||
}
|
|
@ -98,7 +98,11 @@ public abstract class BaseHasResource {
|
|||
public abstract IdDt getIdDt();
|
||||
|
||||
public InstantDt getPublished() {
|
||||
return new InstantDt(myPublished);
|
||||
if (myPublished != null) {
|
||||
return new InstantDt(myPublished);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getResource() {
|
||||
|
|
|
@ -24,6 +24,11 @@ import javax.persistence.Column;
|
|||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
//@formatter:off
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_COORDS" /* , indexes = { @Index(name = "IDX_SP_TOKEN", columnList = "SP_SYSTEM,SP_VALUE") } */)
|
||||
|
@ -52,20 +57,59 @@ public class ResourceIndexedSearchParamCoords extends BaseResourceIndexedSearchP
|
|||
setLongitude(theLongitude);
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return myLatitude;
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamCoords)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamCoords obj = (ResourceIndexedSearchParamCoords) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getLatitude(), obj.getLatitude());
|
||||
b.append(getLongitude(), obj.getLongitude());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public void setLatitude(double theLatitude) {
|
||||
myLatitude = theLatitude;
|
||||
public double getLatitude() {
|
||||
return myLatitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return myLongitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getLatitude());
|
||||
b.append(getLongitude());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setLatitude(double theLatitude) {
|
||||
myLatitude = theLatitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double theLongitude) {
|
||||
myLongitude = theLongitude;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("paramName", getParamName());
|
||||
b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this
|
||||
b.append("lat", getLatitude());
|
||||
b.append("lon", getLongitude());
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ import javax.persistence.Table;
|
|||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
//@formatter:off
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_DATE" /*, indexes= {@Index(name="IDX_SP_DATE", columnList= "SP_VALUE_LOW,SP_VALUE_HIGH")}*/)
|
||||
|
@ -47,18 +52,34 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
@Temporal(TemporalType.TIMESTAMP)
|
||||
public Date myValueLow;
|
||||
|
||||
|
||||
|
||||
public ResourceIndexedSearchParamDate() {
|
||||
}
|
||||
|
||||
|
||||
public ResourceIndexedSearchParamDate(String theName, Date theLow, Date theHigh) {
|
||||
setParamName(theName);
|
||||
setValueLow(theLow);
|
||||
setValueHigh(theHigh);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamDate)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamDate obj = (ResourceIndexedSearchParamDate) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getValueHigh(), obj.getValueHigh());
|
||||
b.append(getValueLow(), obj.getValueLow());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public Date getValueHigh() {
|
||||
return myValueHigh;
|
||||
|
@ -68,6 +89,16 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
return myValueLow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getValueHigh());
|
||||
b.append(getValueLow());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setValueHigh(Date theValueHigh) {
|
||||
myValueHigh = theValueHigh;
|
||||
}
|
||||
|
@ -76,6 +107,13 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
myValueLow = theValueLow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("paramName", getParamName());
|
||||
b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this
|
||||
b.append("valueLow", getValueLow());
|
||||
b.append("valueHigh", getValueHigh());
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@ import javax.persistence.Column;
|
|||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
//@formatter:off
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_NUMBER" /*, indexes= {@Index(name="IDX_SP_NUMBER", columnList="SP_VALUE")}*/ )
|
||||
|
@ -39,21 +44,57 @@ public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchP
|
|||
|
||||
@Column(name = "SP_VALUE", nullable = true)
|
||||
public BigDecimal myValue;
|
||||
|
||||
|
||||
public ResourceIndexedSearchParamNumber() {
|
||||
}
|
||||
|
||||
|
||||
public ResourceIndexedSearchParamNumber(String theParamName, BigDecimal theValue) {
|
||||
setParamName(theParamName);
|
||||
setValue(theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamNumber)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamNumber obj = (ResourceIndexedSearchParamNumber) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getValue(), obj.getValue());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public BigDecimal getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getValue());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setValue(BigDecimal theValue) {
|
||||
myValue = theValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("paramName", getParamName());
|
||||
b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this
|
||||
b.append("value", getValue());
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@ import javax.persistence.Column;
|
|||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
//@formatter:off
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_QUANTITY" /*, indexes= {@Index(name="IDX_SP_NUMBER", columnList="SP_VALUE")}*/ )
|
||||
|
@ -47,9 +52,9 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc
|
|||
public BigDecimal myValue;
|
||||
|
||||
public ResourceIndexedSearchParamQuantity() {
|
||||
//nothing
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
public ResourceIndexedSearchParamQuantity(String theParamName, BigDecimal theValue, String theSystem, String theUnits) {
|
||||
setParamName(theParamName);
|
||||
setSystem(theSystem);
|
||||
|
@ -57,6 +62,27 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc
|
|||
setUnits(theUnits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamQuantity)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamQuantity obj = (ResourceIndexedSearchParamQuantity) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getSystem(), obj.getSystem());
|
||||
b.append(getUnits(), obj.getUnits());
|
||||
b.append(getValue(), obj.getValue());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public String getSystem() {
|
||||
return mySystem;
|
||||
}
|
||||
|
@ -69,6 +95,16 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc
|
|||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getSystem());
|
||||
b.append(getUnits());
|
||||
b.append(getValue());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setSystem(String theSystem) {
|
||||
mySystem = theSystem;
|
||||
|
@ -82,4 +118,15 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc
|
|||
myValue = theValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("paramName", getParamName());
|
||||
b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this
|
||||
b.append("system", getSystem());
|
||||
b.append("units", getUnits());
|
||||
b.append("value", getValue());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,25 +25,26 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_STRING"/*, indexes= {@Index(name="IDX_SP_STRING", columnList="SP_VALUE_NORMALIZED")}*/)
|
||||
@org.hibernate.annotations.Table(appliesTo="HFJ_SPIDX_STRING",indexes= {
|
||||
@org.hibernate.annotations.Index(name="IDX_SP_STRING", columnNames= {"RES_TYPE", "SP_NAME", "SP_VALUE_NORMALIZED"})})
|
||||
@Table(name = "HFJ_SPIDX_STRING"/* , indexes= {@Index(name="IDX_SP_STRING", columnList="SP_VALUE_NORMALIZED")} */)
|
||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_STRING", indexes = { @org.hibernate.annotations.Index(name = "IDX_SP_STRING", columnNames = { "RES_TYPE", "SP_NAME", "SP_VALUE_NORMALIZED" }) })
|
||||
public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchParam {
|
||||
|
||||
public static final int MAX_LENGTH = 100;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "SP_VALUE_EXACT", length = 100, nullable = true)
|
||||
public String myValueExact;
|
||||
|
||||
@Column(name = "SP_VALUE_NORMALIZED", length = MAX_LENGTH, nullable = true)
|
||||
public String myValueNormalized;
|
||||
|
||||
@Column(name="SP_VALUE_EXACT",length=100,nullable=true)
|
||||
public String myValueExact;
|
||||
|
||||
public ResourceIndexedSearchParamString() {
|
||||
}
|
||||
|
||||
|
@ -53,21 +54,42 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
|||
setValueExact(theValueExact);
|
||||
}
|
||||
|
||||
public String getValueNormalized() {
|
||||
return myValueNormalized;
|
||||
}
|
||||
|
||||
public void setValueNormalized(String theValueNormalized) {
|
||||
if (StringUtils.defaultString(theValueNormalized).length() > MAX_LENGTH) {
|
||||
throw new IllegalArgumentException("Value is too long: " + theValueNormalized.length());
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
myValueNormalized = theValueNormalized;
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamString)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamString obj = (ResourceIndexedSearchParamString) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getValueExact(), obj.getValueExact());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public String getValueExact() {
|
||||
return myValueExact;
|
||||
}
|
||||
|
||||
public String getValueNormalized() {
|
||||
return myValueNormalized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getValueExact());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setValueExact(String theValueExact) {
|
||||
if (StringUtils.defaultString(theValueExact).length() > MAX_LENGTH) {
|
||||
throw new IllegalArgumentException("Value is too long: " + theValueExact.length());
|
||||
|
@ -75,6 +97,13 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
|||
myValueExact = theValueExact;
|
||||
}
|
||||
|
||||
public void setValueNormalized(String theValueNormalized) {
|
||||
if (StringUtils.defaultString(theValueNormalized).length() > MAX_LENGTH) {
|
||||
throw new IllegalArgumentException("Value is too long: " + theValueNormalized.length());
|
||||
}
|
||||
myValueNormalized = theValueNormalized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
|
@ -83,5 +112,4 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
|||
b.append("value", getValueNormalized());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,13 +25,15 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_SPIDX_TOKEN" /* , indexes = { @Index(name = "IDX_SP_TOKEN", columnList = "SP_SYSTEM,SP_VALUE") } */)
|
||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_TOKEN", indexes = {
|
||||
@org.hibernate.annotations.Index(name = "IDX_SP_TOKEN", columnNames = { "RES_TYPE", "SP_NAME", "SP_SYSTEM", "SP_VALUE" }),
|
||||
@org.hibernate.annotations.Index(name = "IDX_SP_TOKEN_UNQUAL", columnNames = { "RES_TYPE", "SP_NAME", "SP_VALUE" })
|
||||
})
|
||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_TOKEN", indexes = { @org.hibernate.annotations.Index(name = "IDX_SP_TOKEN", columnNames = { "RES_TYPE", "SP_NAME", "SP_SYSTEM", "SP_VALUE" }),
|
||||
@org.hibernate.annotations.Index(name = "IDX_SP_TOKEN_UNQUAL", columnNames = { "RES_TYPE", "SP_NAME", "SP_VALUE" }) })
|
||||
public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchParam {
|
||||
|
||||
public static final int MAX_LENGTH = 100;
|
||||
|
@ -53,6 +55,26 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
|
|||
setValue(theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamToken)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamToken obj = (ResourceIndexedSearchParamToken) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getSystem(), obj.getSystem());
|
||||
b.append(getValue(), obj.getValue());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public String getSystem() {
|
||||
return mySystem;
|
||||
}
|
||||
|
@ -61,6 +83,16 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
|
|||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getSystem());
|
||||
b.append(getValue());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setSystem(String theSystem) {
|
||||
mySystem = StringUtils.defaultIfBlank(theSystem, null);
|
||||
}
|
||||
|
@ -69,4 +101,13 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
|
|||
myValue = StringUtils.defaultIfBlank(theValue, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("paramName", getParamName());
|
||||
b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this
|
||||
b.append("system", getSystem());
|
||||
b.append("value", getValue());
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
//@formatter:off
|
||||
|
@ -51,10 +53,38 @@ public class ResourceIndexedSearchParamUri extends BaseResourceIndexedSearchPara
|
|||
setUri(theUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceIndexedSearchParamUri)) {
|
||||
return false;
|
||||
}
|
||||
ResourceIndexedSearchParamUri obj = (ResourceIndexedSearchParamUri) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(getParamName(), obj.getParamName());
|
||||
b.append(getResource(), obj.getResource());
|
||||
b.append(getUri(), obj.getUri());
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return myUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(getParamName());
|
||||
b.append(getResource());
|
||||
b.append(getUri());
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setUri(String theUri) {
|
||||
myUri = StringUtils.defaultIfBlank(theUri, null);
|
||||
}
|
||||
|
|
|
@ -32,11 +32,12 @@ import javax.persistence.ManyToOne;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_RES_LINK"/*, indexes= {@Index(name="IDX_RL_TPATHRES", columnList= "SRC_PATH,TARGET_RESOURCE_ID")}*/)
|
||||
@org.hibernate.annotations.Table(appliesTo="HFJ_RES_LINK",indexes= {
|
||||
@org.hibernate.annotations.Index(name="IDX_RL_TPATHRES", columnNames= {"SRC_PATH", "TARGET_RESOURCE_ID"})})
|
||||
@Table(name = "HFJ_RES_LINK"/* , indexes= {@Index(name="IDX_RL_TPATHRES", columnList= "SRC_PATH,TARGET_RESOURCE_ID")} */)
|
||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_RES_LINK", indexes = { @org.hibernate.annotations.Index(name = "IDX_RL_TPATHRES", columnNames = { "SRC_PATH", "TARGET_RESOURCE_ID" }) })
|
||||
public class ResourceLink implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -50,33 +51,21 @@ public class ResourceLink implements Serializable {
|
|||
private String mySourcePath;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "SRC_RESOURCE_ID", referencedColumnName="RES_ID", nullable=false)
|
||||
@JoinColumn(name = "SRC_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = false)
|
||||
private ResourceTable mySourceResource;
|
||||
|
||||
@Column(name = "SRC_RESOURCE_ID", insertable = false, updatable = false, nullable=false)
|
||||
@Column(name = "SRC_RESOURCE_ID", insertable = false, updatable = false, nullable = false)
|
||||
private Long mySourceResourcePid;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "TARGET_RESOURCE_ID", referencedColumnName="RES_ID", nullable=false)
|
||||
@JoinColumn(name = "TARGET_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = false)
|
||||
private ResourceTable myTargetResource;
|
||||
|
||||
@Column(name = "TARGET_RESOURCE_ID", insertable = false, updatable = false,nullable=false)
|
||||
@Column(name = "TARGET_RESOURCE_ID", insertable = false, updatable = false, nullable = false)
|
||||
private Long myTargetResourcePid;
|
||||
|
||||
public ResourceLink() {
|
||||
//nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("ResourceLink[");
|
||||
b.append("path=").append(mySourcePath);
|
||||
b.append(", src=").append(mySourceResource.getId());
|
||||
b.append(", target=").append(myTargetResource.getId());
|
||||
|
||||
b.append("]");
|
||||
return b.toString();
|
||||
// nothing
|
||||
}
|
||||
|
||||
public ResourceLink(String theSourcePath, ResourceTable theSourceResource, ResourceTable theTargetResource) {
|
||||
|
@ -86,6 +75,25 @@ public class ResourceLink implements Serializable {
|
|||
myTargetResource = theTargetResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theObj) {
|
||||
if (this == theObj) {
|
||||
return true;
|
||||
}
|
||||
if (theObj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(theObj instanceof ResourceLink)) {
|
||||
return false;
|
||||
}
|
||||
ResourceLink obj = (ResourceLink) theObj;
|
||||
EqualsBuilder b = new EqualsBuilder();
|
||||
b.append(mySourcePath, obj.mySourcePath);
|
||||
b.append(mySourceResource, obj.mySourceResource);
|
||||
b.append(myTargetResource, obj.myTargetResource);
|
||||
return b.isEquals();
|
||||
}
|
||||
|
||||
public String getSourcePath() {
|
||||
return mySourcePath;
|
||||
}
|
||||
|
@ -106,6 +114,15 @@ public class ResourceLink implements Serializable {
|
|||
return myTargetResourcePid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
HashCodeBuilder b = new HashCodeBuilder();
|
||||
b.append(mySourcePath);
|
||||
b.append(mySourceResource);
|
||||
b.append(myTargetResource);
|
||||
return b.toHashCode();
|
||||
}
|
||||
|
||||
public void setSourcePath(String theSourcePath) {
|
||||
mySourcePath = theSourcePath;
|
||||
}
|
||||
|
@ -114,17 +131,21 @@ public class ResourceLink implements Serializable {
|
|||
mySourceResource = theSourceResource;
|
||||
}
|
||||
|
||||
public void setSourceResourcePid(Long theSourceResourcePid) {
|
||||
mySourceResourcePid = theSourceResourcePid;
|
||||
}
|
||||
|
||||
public void setTargetResource(ResourceTable theTargetResource) {
|
||||
Validate.notNull(theTargetResource);
|
||||
myTargetResource = theTargetResource;
|
||||
}
|
||||
|
||||
public void setTargetResourcePid(Long theTargetResourcePid) {
|
||||
myTargetResourcePid = theTargetResourcePid;
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("ResourceLink[");
|
||||
b.append("path=").append(mySourcePath);
|
||||
b.append(", src=").append(mySourceResource.getId());
|
||||
b.append(", target=").append(myTargetResource.getId());
|
||||
|
||||
b.append("]");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,14 +19,12 @@ package ca.uhn.fhir.jpa.entity;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
|
@ -329,7 +327,7 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
myParamsDatePopulated = theParamsDatePopulated;
|
||||
}
|
||||
|
||||
public void setParamsNumber(List<ResourceIndexedSearchParamNumber> theNumberParams) {
|
||||
public void setParamsNumber(Collection<ResourceIndexedSearchParamNumber> theNumberParams) {
|
||||
if (!isParamsNumberPopulated() && theNumberParams.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -396,7 +394,7 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
myProfile = theProfile;
|
||||
}
|
||||
|
||||
public void setResourceLinks(List<ResourceLink> theLinks) {
|
||||
public void setResourceLinks(Collection<ResourceLink> theLinks) {
|
||||
if (!isHasLinks() && theLinks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "HFJ_SUBSCRIPTION_FLAG_RES")
|
||||
public class SubscriptionFlaggedResource {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
@SequenceGenerator(name = "SEQ_SUBSCRIPTION_FLAG_ID", sequenceName = "SEQ_SUBSCRIPTION_FLAG_ID")
|
||||
@Column(name = "PID", insertable = false, updatable = false)
|
||||
private Long myId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name="RES_ID")
|
||||
private ResourceTable myResource;
|
||||
|
||||
@ManyToOne()
|
||||
@JoinColumn(name="SUBSCRIPTION_ID")
|
||||
private SubscriptionTable mySubscription;
|
||||
|
||||
public ResourceTable getResource() {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
public SubscriptionTable getSubscription() {
|
||||
return mySubscription;
|
||||
}
|
||||
|
||||
public void setResource(ResourceTable theResource) {
|
||||
myResource = theResource;
|
||||
}
|
||||
|
||||
public void setSubscription(SubscriptionTable theSubscription) {
|
||||
mySubscription = theSubscription;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
|
||||
//@formatter:off
|
||||
@Entity
|
||||
@Table(name = "HFJ_SUBSCRIPTION", uniqueConstraints= {
|
||||
@UniqueConstraint(name="IDX_SUBS_RESID", columnNames= { "RES_ID" }),
|
||||
@UniqueConstraint(name="IDX_SUBS_NEXTCHECK", columnNames= { "SUBSCRIPTION_STATUS", "NEXT_CHECK" })
|
||||
})
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="Q_HFJ_SUBSCRIPTION_SET_STATUS", query="UPDATE SubscriptionTable t SET t.myStatus = :status WHERE t.myResId = :res_id"),
|
||||
@NamedQuery(name="Q_HFJ_SUBSCRIPTION_NEXT_CHECK", query="SELECT t FROM SubscriptionTable t WHERE t.myStatus = :status AND t.myNextCheck <= :next_check"),
|
||||
@NamedQuery(name="Q_HFJ_SUBSCRIPTION_GET_BY_RES", query="SELECT t FROM SubscriptionTable t WHERE t.myResId = :res_id"),
|
||||
@NamedQuery(name="Q_HFJ_SUBSCRIPTION_DELETE", query="DELETE FROM SubscriptionTable t WHERE t.myResId = :res_id"),
|
||||
})
|
||||
//@formatter:on
|
||||
public class SubscriptionTable {
|
||||
|
||||
@Column(name = "CHECK_INTERVAL", nullable = false)
|
||||
private long myCheckInterval;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
@SequenceGenerator(name = "SEQ_SUBSCRIPTION_ID", sequenceName = "SEQ_SUBSCRIPTION_ID")
|
||||
@Column(name = "PID", insertable = false, updatable = false)
|
||||
private Long myId;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "NEXT_CHECK", nullable = false)
|
||||
private Date myNextCheck;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "MOST_RECENT_MATCH", nullable = false)
|
||||
private Date myMostRecentMatch;
|
||||
|
||||
@Column(name = "RES_ID", insertable = false, updatable = false)
|
||||
private Long myResId;
|
||||
|
||||
@Column(name = "SUBSCRIPTION_STATUS", nullable = false, length = 20)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private SubscriptionStatusEnum myStatus;
|
||||
|
||||
@OneToOne()
|
||||
@JoinColumn(name = "RES_ID", insertable = true, updatable = false, referencedColumnName = "RES_ID", foreignKey = @ForeignKey(name = "FK_SUBSCRIPTION_RESOURCE_ID") )
|
||||
private ResourceTable mySubscriptionResource;
|
||||
|
||||
@OneToMany(orphanRemoval=true, mappedBy="mySubscription")
|
||||
private Collection<SubscriptionFlaggedResource> myFlaggedResources;
|
||||
|
||||
public long getCheckInterval() {
|
||||
return myCheckInterval;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
public Date getNextCheck() {
|
||||
return myNextCheck;
|
||||
}
|
||||
|
||||
public SubscriptionStatusEnum getStatus() {
|
||||
return myStatus;
|
||||
}
|
||||
|
||||
public ResourceTable getSubscriptionResource() {
|
||||
return mySubscriptionResource;
|
||||
}
|
||||
|
||||
public void setCheckInterval(long theCheckInterval) {
|
||||
myCheckInterval = theCheckInterval;
|
||||
}
|
||||
|
||||
public void setNextCheck(Date theNextCheck) {
|
||||
myNextCheck = theNextCheck;
|
||||
}
|
||||
|
||||
public void setStatus(SubscriptionStatusEnum theStatus) {
|
||||
myStatus = theStatus;
|
||||
}
|
||||
|
||||
public void setSubscriptionResource(ResourceTable theSubscriptionResource) {
|
||||
mySubscriptionResource = theSubscriptionResource;
|
||||
}
|
||||
|
||||
public Date getMostRecentMatch() {
|
||||
return myMostRecentMatch;
|
||||
}
|
||||
|
||||
public void setMostRecentMatch(Date theMostRecentMatch) {
|
||||
myMostRecentMatch = theMostRecentMatch;
|
||||
}
|
||||
|
||||
}
|
|
@ -24,16 +24,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome.Issue;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.IParserErrorHandler;
|
||||
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.Delete;
|
||||
|
@ -46,16 +39,13 @@ import ca.uhn.fhir.rest.annotation.Validate;
|
|||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResourceProvider<T> {
|
||||
|
||||
public static final String OPERATION_NAME_META = "$meta";
|
||||
public static final String OPERATION_NAME_META_DELETE = "$meta-delete";
|
||||
public static final String OPERATION_NAME_META_ADD = "$meta-add";
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaResourceProviderDstu2.class);
|
||||
|
||||
public JpaResourceProviderDstu2() {
|
||||
// nothing
|
||||
|
@ -123,6 +113,9 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
|||
})
|
||||
//@formatter:on
|
||||
public Parameters metaAdd(@IdParam IdDt theId, @OperationParam(name = "meta") MetaDt theMeta) {
|
||||
if (theMeta == null) {
|
||||
throw new InvalidRequestException("Input contains no parameter with name 'meta'");
|
||||
}
|
||||
Parameters parameters = new Parameters();
|
||||
MetaDt metaAddOperation = getDao().metaAddOperation(theId, theMeta);
|
||||
parameters.addParameter().setName("return").setValue(metaAddOperation);
|
||||
|
@ -135,6 +128,9 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
|||
})
|
||||
//@formatter:on
|
||||
public Parameters metaDelete(@IdParam IdDt theId, @OperationParam(name = "meta") MetaDt theMeta) {
|
||||
if (theMeta == null) {
|
||||
throw new InvalidRequestException("Input contains no parameter with name 'meta'");
|
||||
}
|
||||
Parameters parameters = new Parameters();
|
||||
parameters.addParameter().setName("return").setValue(getDao().metaDeleteOperation(theId, theMeta));
|
||||
return parameters;
|
||||
|
@ -150,10 +146,6 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
|||
theResource.setId(theId);
|
||||
return getDao().update(theResource);
|
||||
}
|
||||
} catch (ResourceNotFoundException e) {
|
||||
ourLog.info("Can't update resource with ID[" + theId.getValue() + "] because it doesn't exist, going to create it instead");
|
||||
theResource.setId(theId);
|
||||
return getDao().create(theResource);
|
||||
} finally {
|
||||
endRequest(theRequest);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package ca.uhn.fhir.jpa.util;
|
||||
|
||||
import org.hibernate.dialect.DerbyTenSevenDialect;
|
||||
|
||||
/**
|
||||
* As of Hibernate 5.0.1, DerbyTenSevenDialect doesn't seem to work when updating
|
||||
* the schema, as it tries to create a duplicate schema
|
||||
*/
|
||||
public class HapiDerbyTenSevenDialect extends DerbyTenSevenDialect {
|
||||
|
||||
@Override
|
||||
public String getQuerySequencesString() {
|
||||
return "select SEQUENCENAME from sys.syssequences";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package ca.uhn.fhir.jpa.util;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.FhirResourceDaoSubscriptionDstu2;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
|
||||
import net.sourceforge.cobertura.CoverageIgnore;
|
||||
|
||||
/**
|
||||
* Interceptor which requires newly created {@link Subscription subscriptions} to be in
|
||||
* {@link SubscriptionStatusEnum#REQUESTED} state and prevents clients from changing the status.
|
||||
*/
|
||||
public class SubscriptionsRequireManualActivationInterceptor extends InterceptorAdapter {
|
||||
|
||||
public static final ResourceMetadataKeyEnum<Object> ALLOW_STATUS_CHANGE = new ResourceMetadataKeyEnum<Object>(FhirResourceDaoSubscriptionDstu2.class.getName() + "_ALLOW_STATUS_CHANGE") {
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
@CoverageIgnore
|
||||
@Override
|
||||
public Object get(IResource theResource) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
@Override
|
||||
public void put(IResource theResource, Object theObject) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoDstu2")
|
||||
private IFhirResourceDao<Subscription> myDao;
|
||||
|
||||
@Override
|
||||
public void incomingRequestPreHandled(RestOperationTypeEnum theOperation, ActionRequestDetails theProcessedRequest) {
|
||||
switch (theOperation) {
|
||||
case CREATE:
|
||||
case UPDATE:
|
||||
if (theProcessedRequest.getResourceType().equals("Subscription")) {
|
||||
verifyStatusOk(theProcessedRequest);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDao(IFhirResourceDao<Subscription> theDao) {
|
||||
myDao = theDao;
|
||||
}
|
||||
|
||||
private void verifyStatusOk(ActionRequestDetails theRequestDetails) {
|
||||
Subscription subscription = (Subscription) theRequestDetails.getResource();
|
||||
;
|
||||
SubscriptionStatusEnum newStatus = subscription.getStatusElement().getValueAsEnum();
|
||||
|
||||
if (newStatus == SubscriptionStatusEnum.REQUESTED || newStatus == SubscriptionStatusEnum.OFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
IIdType requestId = theRequestDetails.getId();
|
||||
if (requestId != null && requestId.hasIdPart()) {
|
||||
Subscription existing;
|
||||
try {
|
||||
existing = myDao.read(requestId);
|
||||
SubscriptionStatusEnum existingStatus = existing.getStatusElement().getValueAsEnum();
|
||||
if (existingStatus != newStatus) {
|
||||
throw new UnprocessableEntityException("Subscription.status can not be changed from " + describeStatus(existingStatus) + " to " + describeStatus(newStatus));
|
||||
}
|
||||
} catch (ResourceNotFoundException e) {
|
||||
if (newStatus != SubscriptionStatusEnum.REQUESTED) {
|
||||
throw new UnprocessableEntityException("Subscription.status must be '" + SubscriptionStatusEnum.REQUESTED.getCode() + "' on a newly created subscription");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (newStatus != SubscriptionStatusEnum.REQUESTED) {
|
||||
throw new UnprocessableEntityException("Subscription.status must be '" + SubscriptionStatusEnum.REQUESTED.getCode() + "' on a newly created subscription");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String describeStatus(SubscriptionStatusEnum existingStatus) {
|
||||
String existingStatusString;
|
||||
if (existingStatus != null) {
|
||||
existingStatusString = '\'' + existingStatus.getCode() + '\'';
|
||||
} else {
|
||||
existingStatusString = "null";
|
||||
}
|
||||
return existingStatusString;
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,7 @@
|
|||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" /> -->
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
@ -12,13 +12,11 @@ import javax.persistence.PersistenceContext;
|
|||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.transaction.TransactionConfiguration;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -39,12 +37,17 @@ import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri;
|
|||
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||
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.DiagnosticOrder;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Immunization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
|
@ -53,6 +56,8 @@ import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
||||
import ca.uhn.fhir.model.dstu2.resource.StructureDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Substance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.method.MethodUtil;
|
||||
|
@ -63,16 +68,21 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
@ContextConfiguration(locations={
|
||||
"classpath:hapi-fhir-server-resourceproviders-dstu2.xml",
|
||||
"classpath:fhir-jpabase-spring-test-config.xml"})
|
||||
@TransactionConfiguration(defaultRollback=false)
|
||||
//@formatter:on
|
||||
public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myConceptMapDaoDstu2")
|
||||
protected IFhirResourceDao<ConceptMap> myConceptMapDao;
|
||||
@Autowired
|
||||
protected DaoConfig myDaoConfig;
|
||||
@Autowired
|
||||
@Qualifier("myDeviceDaoDstu2")
|
||||
protected IFhirResourceDao<Device> myDeviceDao;
|
||||
@Autowired
|
||||
@Qualifier("myDiagnosticOrderDaoDstu2")
|
||||
protected IFhirResourceDao<DiagnosticOrder> myDiagnosticOrderDao;
|
||||
@Autowired
|
||||
@Qualifier("myDiagnosticReportDaoDstu2")
|
||||
protected IFhirResourceDao<DiagnosticReport> myDiagnosticReportDao;
|
||||
@Autowired
|
||||
|
@ -82,6 +92,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
protected EntityManager myEntityManager;
|
||||
@Autowired
|
||||
protected FhirContext myFhirCtx;
|
||||
@Autowired
|
||||
@Qualifier("myImmunizationDaoDstu2")
|
||||
protected IFhirResourceDao<Immunization> myImmunizationDao;
|
||||
protected IServerInterceptor myInterceptor;
|
||||
@Autowired
|
||||
@Qualifier("myLocationDaoDstu2")
|
||||
|
@ -111,6 +124,12 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
@Qualifier("myStructureDefinitionDaoDstu2")
|
||||
protected IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoDstu2")
|
||||
protected IFhirResourceDaoSubscription<Subscription> mySubscriptionDao;
|
||||
@Autowired
|
||||
@Qualifier("mySubstanceDaoDstu2")
|
||||
protected IFhirResourceDao<Substance> mySubstanceDao;
|
||||
@Autowired
|
||||
@Qualifier("mySystemDaoDstu2")
|
||||
protected IFhirSystemDao<Bundle> mySystemDao;
|
||||
@Autowired
|
||||
|
@ -145,6 +164,13 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
return newJsonParser.parseResource(type, string);
|
||||
}
|
||||
|
||||
public TransactionTemplate newTxTemplate() {
|
||||
TransactionTemplate retVal = new TransactionTemplate(myTxManager);
|
||||
retVal.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||
retVal.afterPropertiesSet();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager) {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
||||
|
@ -159,6 +185,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
entityManager.createQuery("DELETE from " + SubscriptionFlaggedResource.class.getSimpleName() + " d").executeUpdate();
|
||||
entityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
|
||||
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
|
||||
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate();
|
||||
|
@ -174,6 +201,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
entityManager.createQuery("DELETE from " + SubscriptionTable.class.getSimpleName() + " d").executeUpdate();
|
||||
entityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate();
|
||||
entityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate();
|
||||
entityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate();
|
||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao;
|
|||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
@ -24,7 +25,13 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
|
@ -38,19 +45,25 @@ import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
|||
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.ConceptMap;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Device;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticOrder;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Immunization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Substance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ContactPointSystemEnum;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.param.CompositeParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
|
@ -58,6 +71,8 @@ import ca.uhn.fhir.rest.param.DateRangeParam;
|
|||
import ca.uhn.fhir.rest.param.NumberParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
|
@ -70,6 +85,163 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
|||
public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2SearchTest.class);
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesString() {
|
||||
Patient p = new Patient();
|
||||
p.addAddress().addLine("123 Fake Street");
|
||||
p.addAddress().addLine("123 Fake Street");
|
||||
p.addAddress().addLine("123 Fake Street");
|
||||
p.addAddress().addLine("456 Fake Street");
|
||||
p.addAddress().addLine("456 Fake Street");
|
||||
p.addAddress().addLine("456 Fake Street");
|
||||
|
||||
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
Class<ResourceIndexedSearchParamString> type = ResourceIndexedSearchParamString.class;
|
||||
List<ResourceIndexedSearchParamString> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myPatientDao.search(Patient.SP_ADDRESS, new StringParam("123 Fake Street")));
|
||||
assertThat(actual, contains(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesDate() {
|
||||
DiagnosticOrder order = new DiagnosticOrder();
|
||||
order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-11T11:12:12Z"));
|
||||
order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-11T11:12:12Z"));
|
||||
order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-11T11:12:12Z"));
|
||||
order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-12T11:12:12Z"));
|
||||
order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-12T11:12:12Z"));
|
||||
order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-12T11:12:12Z"));
|
||||
|
||||
IIdType id = myDiagnosticOrderDao.create(order).getId().toUnqualifiedVersionless();
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myDiagnosticOrderDao.search(DiagnosticOrder.SP_ITEM_DATE, new DateParam("2011-12-12T11:12:12Z")));
|
||||
assertThat(actual, contains(id));
|
||||
|
||||
Class<ResourceIndexedSearchParamDate> type = ResourceIndexedSearchParamDate.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesNumber() {
|
||||
Immunization res = new Immunization();
|
||||
res.addVaccinationProtocol().setDoseSequence(1);
|
||||
res.addVaccinationProtocol().setDoseSequence(1);
|
||||
res.addVaccinationProtocol().setDoseSequence(1);
|
||||
res.addVaccinationProtocol().setDoseSequence(2);
|
||||
res.addVaccinationProtocol().setDoseSequence(2);
|
||||
res.addVaccinationProtocol().setDoseSequence(2);
|
||||
|
||||
IIdType id = myImmunizationDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myImmunizationDao.search(Immunization.SP_DOSE_SEQUENCE, new NumberParam("1")));
|
||||
assertThat(actual, contains(id));
|
||||
|
||||
Class<ResourceIndexedSearchParamNumber> type = ResourceIndexedSearchParamNumber.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesUri() {
|
||||
ConceptMap res = new ConceptMap();
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://foo");
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://foo");
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://bar");
|
||||
res.addElement().addTarget().addDependsOn().setElement("http://bar");
|
||||
|
||||
IIdType id = myConceptMapDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
Class<ResourceIndexedSearchParamUri> type = ResourceIndexedSearchParamUri.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myConceptMapDao.search(ConceptMap.SP_DEPENDSON, new UriParam("http://foo")));
|
||||
assertThat(actual, contains(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesQuantity() {
|
||||
Substance res = new Substance();
|
||||
res.addInstance().getQuantity().setSystem("http://foo").setCode("UNIT").setValue(123);
|
||||
res.addInstance().getQuantity().setSystem("http://foo").setCode("UNIT").setValue(123);
|
||||
res.addInstance().getQuantity().setSystem("http://foo2").setCode("UNIT2").setValue(1232);
|
||||
res.addInstance().getQuantity().setSystem("http://foo2").setCode("UNIT2").setValue(1232);
|
||||
|
||||
IIdType id = mySubstanceDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
Class<ResourceIndexedSearchParamQuantity> type = ResourceIndexedSearchParamQuantity.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(mySubstanceDao.search(Substance.SP_QUANTITY, new QuantityParam(null, 123, "http://foo", "UNIT")));
|
||||
assertThat(actual, contains(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesToken() {
|
||||
Patient res = new Patient();
|
||||
res.addIdentifier().setSystem("http://foo1").setValue("123");
|
||||
res.addIdentifier().setSystem("http://foo1").setValue("123");
|
||||
res.addIdentifier().setSystem("http://foo2").setValue("1234");
|
||||
res.addIdentifier().setSystem("http://foo2").setValue("1234");
|
||||
|
||||
IIdType id = myPatientDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
Class<ResourceIndexedSearchParamToken> type = ResourceIndexedSearchParamToken.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("http://foo1", "123")));
|
||||
assertThat(actual, contains(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesReference() {
|
||||
Practitioner pract =new Practitioner();
|
||||
pract.setId("Practitioner/somepract");
|
||||
pract.getName().addFamily("SOME PRACT");
|
||||
myPractitionerDao.update(pract);
|
||||
Practitioner pract2 =new Practitioner();
|
||||
pract2.setId("Practitioner/somepract2");
|
||||
pract2.getName().addFamily("SOME PRACT2");
|
||||
myPractitionerDao.update(pract2);
|
||||
|
||||
DiagnosticOrder res = new DiagnosticOrder();
|
||||
res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract"));
|
||||
res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract"));
|
||||
res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract2"));
|
||||
res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract2"));
|
||||
|
||||
IIdType id = myDiagnosticOrderDao.create(res).getId().toUnqualifiedVersionless();
|
||||
|
||||
Class<ResourceLink> type = ResourceLink.class;
|
||||
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
|
||||
ourLog.info(toStringMultiline(results));
|
||||
assertEquals(2, results.size());
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myDiagnosticOrderDao.search(DiagnosticOrder.SP_ACTOR, new ReferenceParam("Practitioner/somepract")));
|
||||
assertThat(actual, contains(id));
|
||||
}
|
||||
|
||||
private String toStringMultiline(List<?> theResults) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (Object next : theResults) {
|
||||
b.append('\n');
|
||||
b.append(" * ").append(next.toString());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchAll() {
|
||||
{
|
||||
|
@ -130,6 +302,151 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* #222
|
||||
*/
|
||||
@Test
|
||||
public void testSearchForDeleted() {
|
||||
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setId("TEST");
|
||||
patient.setLanguage(new CodeDt("TEST"));
|
||||
patient.addName().addFamily("TEST");
|
||||
patient.addIdentifier().setSystem("TEST").setValue("TEST");
|
||||
myPatientDao.update(patient);
|
||||
}
|
||||
|
||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||
params.put("_id", new StringDt("TEST"));
|
||||
assertEquals(1, toList(myPatientDao.search(params)).size());
|
||||
|
||||
params.put("_language", new StringParam("TEST"));
|
||||
assertEquals(1, toList(myPatientDao.search(params)).size());
|
||||
|
||||
params.put(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
|
||||
assertEquals(1, toList(myPatientDao.search(params)).size());
|
||||
|
||||
params.put(Patient.SP_NAME, new StringParam("TEST"));
|
||||
assertEquals(1, toList(myPatientDao.search(params)).size());
|
||||
|
||||
myPatientDao.delete(new IdDt("Patient/TEST"));
|
||||
|
||||
params = new HashMap<String, IQueryParameterType>();
|
||||
params.put("_id", new StringDt("TEST"));
|
||||
assertEquals(0, toList(myPatientDao.search(params)).size());
|
||||
|
||||
params.put("_language", new StringParam("TEST"));
|
||||
assertEquals(0, toList(myPatientDao.search(params)).size());
|
||||
|
||||
params.put(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
|
||||
assertEquals(0, toList(myPatientDao.search(params)).size());
|
||||
|
||||
params.put(Patient.SP_NAME, new StringParam("TEST"));
|
||||
assertEquals(0, toList(myPatientDao.search(params)).size());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchByIdParamWrongType() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Organization patient = new Organization();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id2 = myOrganizationDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id2.getIdPart())));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByIdParamOr() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id2.getIdPart())));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id1.getIdPart())));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add("_id", new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam("999999999999")));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByIdParamAnd() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
SearchParameterMap params;
|
||||
StringAndListParam param;
|
||||
|
||||
params = new SearchParameterMap();
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam(id1.getIdPart())).addOr(new StringParam(id2.getIdPart())));
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam(id1.getIdPart())));
|
||||
params.add("_id", param);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam(id2.getIdPart())));
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam(id1.getIdPart())));
|
||||
params.add("_id", param);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||
|
||||
params = new SearchParameterMap();
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam(id2.getIdPart())));
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("9999999999999")));
|
||||
params.add("_id", param);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||
|
||||
params = new SearchParameterMap();
|
||||
param = new StringAndListParam();
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam("9999999999999")));
|
||||
param.addAnd(new StringOrListParam().addOr(new StringParam(id2.getIdPart())));
|
||||
params.add("_id", param);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchCompositeParam() {
|
||||
Observation o1 = new Observation();
|
||||
|
@ -201,7 +518,6 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
|||
assertEquals(0, retrieved.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchLanguageParam() {
|
||||
IIdType id1;
|
||||
|
@ -240,9 +556,155 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
|||
List<Patient> patients = toList(myPatientDao.search(params));
|
||||
assertEquals(0, patients.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchLanguageParamAndOr() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.getLanguage().setValue("en_CA");
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.getLanguage().setValue("en_US");
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().addFamily("testSearchLanguageParam").addGiven("John");
|
||||
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add(Patient.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add(Patient.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
StringAndListParam and = new StringAndListParam();
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
|
||||
params.add(Patient.SP_RES_LANGUAGE, and);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
StringAndListParam and = new StringAndListParam();
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
|
||||
params.add(Patient.SP_RES_LANGUAGE, and);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
StringAndListParam and = new StringAndListParam();
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
params.add(Patient.SP_RES_LANGUAGE, and);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
StringAndListParam and = new StringAndListParam();
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
||||
params.add(Patient.SP_RES_LANGUAGE, and);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.add("_id", new StringParam(id1.getIdPart()));
|
||||
StringAndListParam and = new StringAndListParam();
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
||||
params.add(Patient.SP_RES_LANGUAGE, and);
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
}
|
||||
{
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
StringAndListParam and = new StringAndListParam();
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
||||
params.add(Patient.SP_RES_LANGUAGE, and);
|
||||
params.add("_id", new StringParam(id1.getIdPart()));
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchLastUpdatedParamWithComparator() throws InterruptedException {
|
||||
String methodName = "testSearchLastUpdatedParamWithComparator";
|
||||
|
||||
IIdType id0;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id0 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
int sleep = 100;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
Thread.sleep(sleep);
|
||||
|
||||
DateTimeDt beforeAny = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
|
||||
IIdType id1a;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1a = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id1b;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1b = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
ourLog.info("Res 1: {}", ResourceMetadataKeyEnum.PUBLISHED.get(myPatientDao.read(id0)).getValueAsString());
|
||||
ourLog.info("Res 2: {}", ResourceMetadataKeyEnum.PUBLISHED.get(myPatientDao.read(id1a)).getValueAsString());
|
||||
InstantDt id1bpublished = ResourceMetadataKeyEnum.PUBLISHED.get(myPatientDao.read(id1b));
|
||||
ourLog.info("Res 3: {}", id1bpublished.getValueAsString());
|
||||
|
||||
|
||||
Thread.sleep(sleep);
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
SearchParameterMap map;
|
||||
Date startDate = new Date(start);
|
||||
Date endDate = new Date(end);
|
||||
DateTimeDt startDateTime = new DateTimeDt(startDate, TemporalPrecisionEnum.MILLI);
|
||||
DateTimeDt endDateTime = new DateTimeDt(endDate, TemporalPrecisionEnum.MILLI);
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.setLastUpdated(new DateRangeParam(startDateTime, endDateTime));
|
||||
ourLog.info("Searching: {}", map.getLastUpdated());
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.setLastUpdated(new DateRangeParam(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, startDateTime), new DateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, endDateTime)));
|
||||
ourLog.info("Searching: {}", map.getLastUpdated());
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.setLastUpdated(new DateRangeParam(new DateParam(QuantityCompararatorEnum.GREATERTHAN, startDateTime), new DateParam(QuantityCompararatorEnum.LESSTHAN, endDateTime)));
|
||||
ourLog.info("Searching: {}", map.getLastUpdated());
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
||||
|
||||
map = new SearchParameterMap();
|
||||
map.setLastUpdated(new DateRangeParam(new DateParam(QuantityCompararatorEnum.GREATERTHAN, startDateTime.getValue()), new DateParam(QuantityCompararatorEnum.LESSTHAN, id1bpublished.getValue())));
|
||||
ourLog.info("Searching: {}", map.getLastUpdated());
|
||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchLastUpdatedParam() throws InterruptedException {
|
||||
String methodName = "testSearchLastUpdatedParam";
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
public class FhirResourceDaoDstu2SubscriptionTest extends BaseJpaDstu2Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2SubscriptionTest.class);
|
||||
|
||||
@Test
|
||||
public void testCreateSubscriptionInvalidCriteria() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subs.setCriteria("Observation");
|
||||
try {
|
||||
mySubscriptionDao.create(subs);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Subscription.criteria must be in the form \"{Resource Type}?[params]\""));
|
||||
}
|
||||
|
||||
subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subs.setCriteria("http://foo.com/Observation?AAA=BBB");
|
||||
try {
|
||||
mySubscriptionDao.create(subs);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Subscription.criteria must be in the form \"{Resource Type}?[params]\""));
|
||||
}
|
||||
|
||||
subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subs.setCriteria("ObservationZZZZ?a=b");
|
||||
try {
|
||||
mySubscriptionDao.create(subs);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Subscription.criteria contains invalid/unsupported resource type: ObservationZZZZ"));
|
||||
}
|
||||
|
||||
subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subs.setCriteria("Observation?identifier=123");
|
||||
try {
|
||||
mySubscriptionDao.create(subs);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Subscription.channel.type must be populated on this server"));
|
||||
}
|
||||
|
||||
subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subs.setCriteria("Observation?identifier=123");
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
assertTrue(mySubscriptionDao.create(subs).getId().hasIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeEnableSubscription() {
|
||||
myDaoConfig.setSubscriptionEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriptionResourcesAppear() throws Exception {
|
||||
myDaoConfig.setSubscriptionPollDelay(0);
|
||||
|
||||
String methodName = "testSubscriptionResourcesAppear";
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
IIdType pId = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.getSubject().setReference(pId);
|
||||
obs.setStatus(ObservationStatusEnum.FINAL);
|
||||
IIdType beforeId = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
|
||||
Subscription subs = new Subscription();
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setCriteria("Observation?subject=Patient/" + pId.getIdPart());
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
IIdType id = mySubscriptionDao.create(subs).getId().toUnqualifiedVersionless();
|
||||
|
||||
Thread.sleep(100);
|
||||
ourLog.info("Before: {}", System.currentTimeMillis());
|
||||
|
||||
obs = new Observation();
|
||||
obs.getSubject().setReference(pId);
|
||||
obs.setStatus(ObservationStatusEnum.FINAL);
|
||||
IIdType afterId1 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
|
||||
obs = new Observation();
|
||||
obs.getSubject().setReference(pId);
|
||||
obs.setStatus(ObservationStatusEnum.FINAL);
|
||||
IIdType afterId2 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
|
||||
Thread.sleep(100);
|
||||
|
||||
ourLog.info("After: {}", System.currentTimeMillis());
|
||||
|
||||
mySubscriptionDao.pollForNewUndeliveredResources();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSubscription() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.setCriteria("Observation?subject=Patient/123");
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
|
||||
IIdType id = mySubscriptionDao.create(subs).getId().toUnqualifiedVersionless();
|
||||
|
||||
TypedQuery<SubscriptionTable> q = myEntityManager.createQuery("SELECT t from SubscriptionTable t WHERE t.mySubscriptionResource.myId = :id", SubscriptionTable.class);
|
||||
q.setParameter("id", id.getIdPartAsLong());
|
||||
final SubscriptionTable table = q.getSingleResult();
|
||||
|
||||
assertNotNull(table);
|
||||
assertNotNull(table.getNextCheck());
|
||||
assertEquals(table.getNextCheck(), table.getSubscriptionResource().getPublished().getValue());
|
||||
assertEquals(SubscriptionStatusEnum.REQUESTED, myEntityManager.find(SubscriptionTable.class, table.getId()).getStatus());
|
||||
assertEquals(SubscriptionStatusEnum.REQUESTED, mySubscriptionDao.read(id).getStatusElement().getValueAsEnum());
|
||||
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
mySubscriptionDao.update(subs);
|
||||
|
||||
assertEquals(SubscriptionStatusEnum.ACTIVE, myEntityManager.find(SubscriptionTable.class, table.getId()).getStatus());
|
||||
assertEquals(SubscriptionStatusEnum.ACTIVE, mySubscriptionDao.read(id).getStatusElement().getValueAsEnum());
|
||||
|
||||
mySubscriptionDao.delete(id);
|
||||
|
||||
assertNull(myEntityManager.find(SubscriptionTable.class, table.getId()));
|
||||
|
||||
/*
|
||||
* Re-create again
|
||||
*/
|
||||
|
||||
subs = new Subscription();
|
||||
subs.setCriteria("Observation?subject=Patient/123");
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setId(id);
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
mySubscriptionDao.update(subs);
|
||||
|
||||
assertEquals(SubscriptionStatusEnum.REQUESTED, myEntityManager.createQuery("SELECT t FROM SubscriptionTable t WHERE t.myResId = " + id.getIdPart(), SubscriptionTable.class).getSingleResult().getStatus());
|
||||
assertEquals(SubscriptionStatusEnum.REQUESTED, mySubscriptionDao.read(id).getStatusElement().getValueAsEnum());
|
||||
}
|
||||
|
||||
}
|
|
@ -77,6 +77,7 @@ import ca.uhn.fhir.model.primitive.InstantDt;
|
|||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||
|
@ -966,8 +967,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
assertEquals(id.withVersion("1"), entries.get(2).getIdElement());
|
||||
|
||||
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)));
|
||||
|
||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) entries.get(2)));
|
||||
assertEquals(BundleEntryTransactionMethodEnum.POST, ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.get((IResource) entries.get(2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.BaseJpaDstu2Test;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
|
||||
public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
||||
|
||||
protected static IGenericClient ourClient;
|
||||
protected static CloseableHttpClient ourHttpClient;
|
||||
protected static int ourPort;
|
||||
private static Server ourServer;
|
||||
protected static String ourServerBase;
|
||||
|
||||
public BaseResourceProviderDstu2Test() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected List<IdDt> toIdListUnqualifiedVersionless(Bundle found) {
|
||||
List<IdDt> list = new ArrayList<IdDt>();
|
||||
for (BundleEntry next : found.getEntries()) {
|
||||
list.add(next.getResource().getId().toUnqualifiedVersionless());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected List<String> toNameList(Bundle resp) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (BundleEntry next : resp.getEntries()) {
|
||||
Patient nextPt = (Patient) next.getResource();
|
||||
String nextStr = nextPt.getNameFirstRep().getGivenAsSingleString() + " " + nextPt.getNameFirstRep().getFamilyAsSingleString();
|
||||
if (isNotBlank(nextStr)) {
|
||||
names.add(nextStr);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
ourHttpClient.close();
|
||||
ourServer = null;
|
||||
ourHttpClient = null;
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
myFhirCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
|
||||
if (ourServer == null) {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
|
||||
RestfulServer restServer = new RestfulServer(myFhirCtx);
|
||||
|
||||
ourServerBase = "http://localhost:" + ourPort + "/fhir/context";
|
||||
|
||||
restServer.setResourceProviders((List)myResourceProviders);
|
||||
|
||||
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
restServer.setPlainProviders(mySystemProvider);
|
||||
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, mySystemDao);
|
||||
confProvider.setImplementationDescription("THIS IS THE DESC");
|
||||
restServer.setServerConformanceProvider(confProvider);
|
||||
|
||||
restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
Server server = new Server(ourPort);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(restServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
|
||||
server.setHandler(proxyHandler);
|
||||
server.start();
|
||||
|
||||
ourClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
|
||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourHttpClient = builder.build();
|
||||
|
||||
ourServer = server;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||
|
@ -29,7 +28,6 @@ import java.util.Date;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -41,23 +39,11 @@ import org.apache.http.client.methods.HttpPost;
|
|||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
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.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.BaseJpaDstu2Test;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
|
@ -95,27 +81,18 @@ import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
|||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
||||
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||
|
||||
private static IGenericClient ourClient;
|
||||
private static CloseableHttpClient ourHttpClient;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourServerBase;
|
||||
|
||||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
|
@ -151,6 +128,33 @@ public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
// }
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testSearchByIdOr() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.RES_ID.matches().values(id1.getIdPart(), id2.getIdPart()))
|
||||
.and(Patient.RES_ID.matches().value(id1.getIdPart()))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleCreate() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
@ -202,6 +206,19 @@ public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@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();
|
||||
|
@ -730,6 +747,50 @@ public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperationWithNoMetaParameter() throws Exception {
|
||||
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" +
|
||||
" <tag>\n" +
|
||||
" <system value=\"http://example.org/codes/tags\"/>\n" +
|
||||
" <code value=\"record-lost\"/>\n" +
|
||||
" <display value=\"Patient File Lost\"/>\n" +
|
||||
" </tag>\n" +
|
||||
" </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);
|
||||
try {
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
assertThat(output, containsString("Input contains no parameter with name 'meta'"));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
post = new HttpPost(ourServerBase + "/Patient/" + id.getIdPart() + "/$meta-delete");
|
||||
post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
response = ourHttpClient.execute(post);
|
||||
try {
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
assertThat(output, containsString("Input contains no parameter with name 'meta'"));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperations() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
@ -1635,84 +1696,4 @@ public class ResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
private List<IdDt> toIdListUnqualifiedVersionless(Bundle found) {
|
||||
List<IdDt> list = new ArrayList<IdDt>();
|
||||
for (BundleEntry next : found.getEntries()) {
|
||||
list.add(next.getResource().getId().toUnqualifiedVersionless());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> toNameList(Bundle resp) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (BundleEntry next : resp.getEntries()) {
|
||||
Patient nextPt = (Patient) next.getResource();
|
||||
String nextStr = nextPt.getNameFirstRep().getGivenAsSingleString() + " " + nextPt.getNameFirstRep().getFamilyAsSingleString();
|
||||
if (isNotBlank(nextStr)) {
|
||||
names.add(nextStr);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
ourHttpClient.close();
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
myFhirCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
myFhirCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
|
||||
if (ourServer == null) {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
|
||||
RestfulServer restServer = new RestfulServer(myFhirCtx);
|
||||
|
||||
ourServerBase = "http://localhost:" + ourPort + "/fhir/context";
|
||||
|
||||
restServer.setResourceProviders((List)myResourceProviders);
|
||||
|
||||
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
restServer.setPlainProviders(mySystemProvider);
|
||||
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, mySystemDao);
|
||||
confProvider.setImplementationDescription("THIS IS THE DESC");
|
||||
restServer.setServerConformanceProvider(confProvider);
|
||||
|
||||
restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
Server server = new Server(ourPort);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(restServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
|
||||
server.setHandler(proxyHandler);
|
||||
server.start();
|
||||
|
||||
ourClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
|
||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourHttpClient = builder.build();
|
||||
|
||||
ourServer = server;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptor;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
public class SubscriptionsRequireManualActivationInterceptorTest extends BaseResourceProviderDstu2Test {
|
||||
|
||||
@Test
|
||||
public void testCreateInvalidNoStatus() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setCriteria("Observation?identifier=123");
|
||||
try {
|
||||
ourClient.create().resource(subs).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("HTTP 422 Unprocessable Entity: Subscription.status must be 'requested' on a newly created subscription", e.getMessage());
|
||||
}
|
||||
|
||||
subs.setId("ABC");
|
||||
try {
|
||||
ourClient.update().resource(subs).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("HTTP 422 Unprocessable Entity: Subscription.status must be 'requested' on a newly created subscription", e.getMessage());
|
||||
}
|
||||
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
ourClient.update().resource(subs).execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateInvalidWrongStatus() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
subs.setCriteria("Observation?identifier=123");
|
||||
try {
|
||||
ourClient.create().resource(subs).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("HTTP 422 Unprocessable Entity: Subscription.status must be 'requested' on a newly created subscription", e.getMessage());
|
||||
}
|
||||
|
||||
subs.setId("ABC");
|
||||
try {
|
||||
ourClient.update().resource(subs).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("HTTP 422 Unprocessable Entity: Subscription.status must be 'requested' on a newly created subscription", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFails() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subs.setCriteria("Observation?identifier=123");
|
||||
IIdType id = ourClient.create().resource(subs).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
subs.setId(id);
|
||||
|
||||
try {
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
ourClient.update().resource(subs).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("HTTP 422 Unprocessable Entity: Subscription.status can not be changed from 'requested' to 'active'", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
subs.setStatus((SubscriptionStatusEnum) null);
|
||||
ourClient.update().resource(subs).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("HTTP 422 Unprocessable Entity: Subscription.status can not be changed from 'requested' to null", e.getMessage());
|
||||
}
|
||||
|
||||
subs.setStatus(SubscriptionStatusEnum.OFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCreateInterceptor() {
|
||||
super.beforeCreateInterceptor();
|
||||
|
||||
SubscriptionsRequireManualActivationInterceptor interceptor = new SubscriptionsRequireManualActivationInterceptor();
|
||||
interceptor.setDao(mySubscriptionDao);
|
||||
myDaoConfig.getInterceptors().add(interceptor);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,16 +21,13 @@
|
|||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
<exclude-unlisted-classes>false</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.connection.username" value="sa" />
|
||||
<property name="hibernate.connection.password" value="" />
|
||||
<property name="hibernate.jdbc.batch_size" value="0" />
|
||||
<property name="hibernate.cache.use_minimal_puts" value="false" />
|
||||
<property name="hibernate.cache.use_query_cache" value="false" />
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" /> -->
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -31,33 +31,33 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- At least one "structures" JAR must also be included -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- This dependency includes the JPA server itself, which is packaged separately from the rest of HAPI FHIR -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- This dependency is used for the "FHIR Tester" web app overlay -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
and other properties supported by BasicDataSource.
|
||||
-->
|
||||
<bean id="myPersistenceDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
|
||||
<property name="url" value="jdbc:derby:directory:jpaserver_derby_files;create=true" />
|
||||
<property name="url" value="jdbc:derby:directory:target/jpaserver_derby_files;create=true" />
|
||||
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"></property>
|
||||
<property name="username" value=""/>
|
||||
<property name="password" value=""/>
|
||||
|
@ -40,7 +40,7 @@
|
|||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -18,27 +18,27 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -52,13 +52,6 @@
|
|||
<artifactId>phloc-commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-test</artifactId>
|
||||
<version>0.9-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="hibernate.dialect" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.jdbc.batch_size" value="20" />
|
||||
<property name="hibernate.cache.use_minimal_puts" value="true" />
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />-->
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /> -->
|
||||
</bean>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" /> -->
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /> -->
|
||||
</bean>
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
<util:list id="myServerInterceptors">
|
||||
<ref bean="myLoggingInterceptor"/>
|
||||
<ref bean="mySubscriptionSecurityInterceptor"/>
|
||||
</util:list>
|
||||
|
||||
<!--
|
||||
|
@ -42,6 +43,8 @@
|
|||
|
||||
<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
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="hibernate.dialect" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.connection.username" value="sa" />
|
||||
<property name="hibernate.connection.password" value="" />
|
||||
|
|
|
@ -1,31 +1,76 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-osgi-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<url>http://jamesagnew.github.io/hapi-fhir/</url>
|
||||
|
||||
<name>HAPI FHIR - OSGi Bundle</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Export-Package>ca.uhn.fhir</Export-Package>
|
||||
<Export-Package>org.hl7.fhir</Export-Package>
|
||||
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
|
||||
<Embed-Dependency>*;scope=!provided|test</Embed-Dependency>
|
||||
<Embed-Directory>lib</Embed-Directory>
|
||||
<Embed-Transitive>true</Embed-Transitive>
|
||||
<_removeheaders>Built-By</_removeheaders>
|
||||
<!-- <Private-Package>org.foo.myproject.*</Private-Package> <Bundle-Activator>org.foo.myproject.impl1.Activator</Bundle-Activator> -->
|
||||
</instructions>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>bundle</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -136,7 +136,7 @@
|
|||
<plugin>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-tinder-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
|
|
@ -10,12 +10,16 @@ import java.util.List;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class DateRangeParamTest {
|
||||
|
||||
private static SimpleDateFormat ourFmt;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DateRangeParamTest.class);
|
||||
|
||||
static {
|
||||
ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
||||
|
@ -25,6 +29,31 @@ public class DateRangeParamTest {
|
|||
return new DateRangeParam(new DateParam(theString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRange() {
|
||||
InstantDt start = new InstantDt("2015-09-23T07:43:34.811-04:00");
|
||||
InstantDt end = new InstantDt("2015-09-23T07:43:34.899-04:00");
|
||||
DateParam lowerBound = new DateParam(QuantityCompararatorEnum.GREATERTHAN, start.getValue());
|
||||
DateParam upperBound = new DateParam(QuantityCompararatorEnum.LESSTHAN, end.getValue());
|
||||
assertEquals(QuantityCompararatorEnum.GREATERTHAN, lowerBound.getComparator());
|
||||
assertEquals(QuantityCompararatorEnum.LESSTHAN, upperBound.getComparator());
|
||||
|
||||
/*
|
||||
* When DateParam (which extends DateTimeDt) gets passed in, make sure we preserve the
|
||||
* comparators..
|
||||
*/
|
||||
DateRangeParam param = new DateRangeParam(lowerBound, upperBound);
|
||||
ourLog.info(param.toString());
|
||||
assertEquals(QuantityCompararatorEnum.GREATERTHAN, param.getLowerBound().getComparator());
|
||||
assertEquals(QuantityCompararatorEnum.LESSTHAN, param.getUpperBound().getComparator());
|
||||
|
||||
param = new DateRangeParam(new DateTimeDt(lowerBound.getValue()), new DateTimeDt(upperBound.getValue()));
|
||||
ourLog.info(param.toString());
|
||||
assertEquals(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, param.getLowerBound().getComparator());
|
||||
assertEquals(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, param.getUpperBound().getComparator());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAnd() {
|
||||
assertEquals(1, new DateAndListParam().addAnd(new DateOrListParam()).getValuesAsQueryTokens().size());
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -17,13 +17,13 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -144,7 +144,7 @@
|
|||
<plugin>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-tinder-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate</id>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -28,6 +28,7 @@ import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
|||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
||||
import ca.uhn.fhir.model.dstu2.resource.MedicationOrder;
|
||||
|
@ -474,17 +475,6 @@ public class JsonParserDstu2Test {
|
|||
assertThat(ourCtx.newJsonParser().setOmitResourceId(true).encodeResourceToString(p), not(containsString("123")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeBundleResourceWithComments() throws Exception {
|
||||
String content = IOUtils.toString(JsonParserDstu2Test.class.getResourceAsStream("/bundle-transaction2.json"));
|
||||
|
||||
ourCtx.newJsonParser().parseBundle(content);
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, content);
|
||||
|
||||
// TODO: preserve comments
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeBundle() throws Exception {
|
||||
String content = IOUtils.toString(JsonParserDstu2Test.class.getResourceAsStream("/bundle-example.json"));
|
||||
|
@ -527,7 +517,7 @@ public class JsonParserDstu2Test {
|
|||
assertEquals(exp, act);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for #146
|
||||
*/
|
||||
|
@ -641,6 +631,17 @@ public class JsonParserDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeBundleResourceWithComments() throws Exception {
|
||||
String content = IOUtils.toString(JsonParserDstu2Test.class.getResourceAsStream("/bundle-transaction2.json"));
|
||||
|
||||
ourCtx.newJsonParser().parseBundle(content);
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, content);
|
||||
|
||||
// TODO: preserve comments
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeBundleWithDeletedEntry() {
|
||||
|
||||
|
@ -856,7 +857,7 @@ public class JsonParserDstu2Test {
|
|||
assertEquals(exp, act);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParsePatientInBundle() {
|
||||
|
||||
|
@ -917,6 +918,17 @@ public class JsonParserDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseWithWrongTypeObjectShouldBeArray() throws Exception {
|
||||
String input = IOUtils.toString(getClass().getResourceAsStream("/invalid_metadata.json"));
|
||||
try {
|
||||
ourCtx.newJsonParser().parseResource(Conformance.class, input);
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
assertEquals("Syntax error parsing JSON FHIR structure: Expected ARRAY at element 'modifierExtension', found 'OBJECT'", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #144 and #146
|
||||
*/
|
||||
|
|
|
@ -51,11 +51,13 @@ public class SearchDstu2Test {
|
|||
private static Server ourServer;
|
||||
private static String ourLastMethod;
|
||||
private static DateAndListParam ourLastDateAndList;
|
||||
private static ReferenceParam ourLastRef;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourLastMethod = null;
|
||||
ourLastDateAndList = null;
|
||||
ourLastRef = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -68,6 +70,59 @@ public class SearchDstu2Test {
|
|||
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchReferenceParams01() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("123", ourLastRef.getIdPart());
|
||||
assertEquals(null, ourLastRef.getResourceType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchReferenceParams02() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref=Patient/123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("123", ourLastRef.getIdPart());
|
||||
assertEquals("Patient", ourLastRef.getResourceType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchReferenceParams03() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref:Patient=Patient/123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("123", ourLastRef.getIdPart());
|
||||
assertEquals("Patient", ourLastRef.getResourceType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchReferenceParams04() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref:Patient=123");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("123", ourLastRef.getIdPart());
|
||||
assertEquals("Patient", ourLastRef.getResourceType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchDateAndList() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?searchDateAndList=2001,2002&searchDateAndList=2003,2004");
|
||||
|
@ -220,7 +275,17 @@ public class SearchDstu2Test {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
|
||||
//@formatter:off
|
||||
@Search(queryName="searchNoList")
|
||||
public List<Patient> searchNoList(
|
||||
@RequiredParam(name = "ref") ReferenceParam theParam) {
|
||||
ourLastMethod = "searchNoList";
|
||||
ourLastRef = theParam;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
//@formatter:off
|
||||
@Search()
|
||||
public List<Patient> searchDateAndList(
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"resourceType": "Conformance",
|
||||
"meta": {
|
||||
"versionId": "0.0.1"
|
||||
},
|
||||
"status": "draft",
|
||||
"experimental": true,
|
||||
"date": "2015-09-23T12:00:00Z",
|
||||
"fhirVersion": "DSTU 2 0.5.0",
|
||||
"acceptUnknown": false,
|
||||
"format": [
|
||||
"json"
|
||||
],
|
||||
"rest": [
|
||||
{
|
||||
"mode": "server",
|
||||
"documentation": "Information about the system's restful capabilities that apply across all applications, such as security",
|
||||
"security": {
|
||||
"cors": false,
|
||||
"service": [
|
||||
{
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://hl7.org/fhir/restful-security-service",
|
||||
"code": "OAuth"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"description": "General description of how security works",
|
||||
"certificate": [
|
||||
{
|
||||
"type": "json"
|
||||
}
|
||||
],
|
||||
"modifierExtension": {
|
||||
"url": "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris"
|
||||
},
|
||||
"extension": {
|
||||
"url": "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris"
|
||||
}
|
||||
},
|
||||
"resource": [
|
||||
{
|
||||
"type": "Patient",
|
||||
"profile": {
|
||||
"reference": "http://hl7.org/fhir/StructureDefinition/patient-daf-dafpatient"
|
||||
},
|
||||
"interaction": [
|
||||
{
|
||||
"code": "read"
|
||||
},
|
||||
{
|
||||
"code": "update"
|
||||
},
|
||||
{
|
||||
"code": "search-type"
|
||||
}
|
||||
],
|
||||
"versioning": "no-version"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -18,12 +18,12 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -27,22 +27,22 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
|
@ -66,13 +66,6 @@
|
|||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-test</artifactId>
|
||||
<version>0.9-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
|
@ -111,12 +104,10 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>xml-apis</artifactId>
|
||||
|
@ -127,53 +118,44 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -21,13 +21,15 @@
|
|||
<class>ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceLink</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.ResourceTag</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionTable</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
<exclude-unlisted-classes>false</exclude-unlisted-classes>
|
||||
<properties>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="hibernate.dialect" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.connection.username" value="sa" />
|
||||
<property name="hibernate.connection.password" value="" />
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" /> -->
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="databasePlatform" value="ca.uhn.fhir.jpa.util.HapiDerbyTenSevenDialect" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!--
|
||||
Because Tinder is a part of the HAPI FHIR build process (it generates
|
||||
|
|
|
@ -44,11 +44,11 @@ public class ${className}ResourceProvider extends
|
|||
|
||||
@Description(shortDefinition="The resource identity")
|
||||
@OptionalParam(name="_id")
|
||||
StringParam theId,
|
||||
StringAndListParam theId,
|
||||
|
||||
@Description(shortDefinition="The resource language")
|
||||
@OptionalParam(name="_language")
|
||||
StringParam theResourceLanguage,
|
||||
StringAndListParam theResourceLanguage,
|
||||
|
||||
@Description(shortDefinition="Search for resources which have the given tag")
|
||||
@OptionalParam(name=ca.uhn.fhir.rest.server.Constants.PARAM_TAG)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
|
||||
default-autowire="no" default-lazy-init="false"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
|
@ -8,6 +9,7 @@
|
|||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
|
||||
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
|
||||
"
|
||||
>
|
||||
|
||||
|
@ -21,6 +23,12 @@
|
|||
</bean>
|
||||
|
||||
#if ( ${versionCapitalized} == 'Dstu2' )
|
||||
<jpa:repositories base-package="ca.uhn.fhir.jpa.dao.data" />
|
||||
|
||||
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
|
||||
<task:executor id="myExecutor" pool-size="5"/>
|
||||
<task:scheduler id="myScheduler" pool-size="10"/>
|
||||
|
||||
<bean id="myJpaValidationSupport${versionCapitalized}" class="ca.uhn.fhir.jpa.dao.JpaValidationSupport${versionCapitalized}"/>
|
||||
#end
|
||||
|
||||
|
@ -33,7 +41,7 @@
|
|||
#foreach ( $res in $resources )
|
||||
<bean id="my${res.name}Dao${versionCapitalized}"
|
||||
## Some resource types have customized DAOs for resource specific functionality
|
||||
#if ( ${versionCapitalized} == 'Dstu2' && ( ${res.name} == 'Bundle' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'ValueSet'))
|
||||
#if ( ${versionCapitalized} == 'Dstu2' && ( ${res.name} == 'Bundle' || ${res.name} == 'Subscription' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'ValueSet'))
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||
#else
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${versionCapitalized}">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -17,12 +17,12 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -45,7 +45,7 @@
|
|||
<plugin>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-tinder-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>custom-structs</id>
|
||||
|
@ -104,7 +104,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
|
|
45
pom.xml
45
pom.xml
|
@ -11,7 +11,7 @@
|
|||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<name>HAPI-FHIR</name>
|
||||
<url>http://jamesagnew.github.io/hapi-fhir/</url>
|
||||
|
||||
|
@ -214,15 +214,13 @@
|
|||
<derby_version>10.11.1.1</derby_version>
|
||||
<!-- Note on Hibernate versions: Hibernate 4.3+ uses JPA 2.1, which is too new for a number of platforms including JBoss EAP 6.x and Glassfish 3.0. Upgrade this
|
||||
version with caution! Also note that if you change this, you may get a failure in hibernate4-maven-plugin. See the note in hapi-fhir-jpaserver-base/pom.xml's configuration
|
||||
for that plugin... <hibernate_version>4.3.7.Final</hibernate_version> -->
|
||||
<hibernate_version>4.2.17.Final</hibernate_version>
|
||||
<hibernate_validator_version>5.1.0.Final</hibernate_validator_version>
|
||||
for that plugin... -->
|
||||
<hibernate_version>5.0.1.Final</hibernate_version>
|
||||
<hibernate_validator_version>5.2.1.Final</hibernate_validator_version>
|
||||
<jetty_version>9.2.6.v20141205</jetty_version>
|
||||
<maven_build_helper_plugin_version>1.9.1</maven_build_helper_plugin_version>
|
||||
<maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version>
|
||||
<maven_failsafe_plugin_version>2.18.1</maven_failsafe_plugin_version>
|
||||
<maven_gpg_plugin_version>1.6</maven_gpg_plugin_version>
|
||||
<maven_jxr_plugin_version>2.5</maven_jxr_plugin_version>
|
||||
<maven_license_plugin_version>1.8</maven_license_plugin_version>
|
||||
<maven_project_info_plugin_version>2.8</maven_project_info_plugin_version>
|
||||
<maven_surefire_plugin_version>2.18.1</maven_surefire_plugin_version>
|
||||
|
@ -231,7 +229,7 @@
|
|||
<mitreid-connect-version>1.1.8</mitreid-connect-version>
|
||||
<phloc_schematron_version>2.7.1</phloc_schematron_version>
|
||||
<phloc_commons_version>4.3.6</phloc_commons_version>
|
||||
<spring_version>4.1.5.RELEASE</spring_version>
|
||||
<spring_version>4.2.1.RELEASE</spring_version>
|
||||
<thymeleaf-version>2.1.4.RELEASE</thymeleaf-version>
|
||||
<ebay_cors_filter_version>1.0.1</ebay_cors_filter_version>
|
||||
<xmlunit_version>1.6</xmlunit_version>
|
||||
|
@ -505,6 +503,11 @@
|
|||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<version>1.9.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
|
@ -525,6 +528,11 @@
|
|||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
|
@ -541,6 +549,16 @@
|
|||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>de.juplo</groupId>
|
||||
<artifactId>hibernate4-maven-plugin</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>2.5.4</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
|
@ -585,11 +603,21 @@
|
|||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
|
@ -1218,7 +1246,6 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>${maven_gpg_plugin_version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
|
@ -1290,7 +1317,7 @@
|
|||
<module>hapi-fhir-cli</module>
|
||||
<module>hapi-fhir-dist</module>
|
||||
<module>examples</module>
|
||||
<!--<module>hapi-fhir-osgi-core</module>-->
|
||||
<module>hapi-fhir-osgi-core</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -17,12 +17,12 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>restful-server-example</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>HAPI FHIR Sample RESTful Server</name>
|
||||
|
@ -35,20 +35,20 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- At least one "structures" JAR must also be included -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- This dependency is used for the "FHIR Tester" web app overlay -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
|
|
@ -6,6 +6,50 @@
|
|||
<title>HAPI FHIR Changelog</title>
|
||||
</properties>
|
||||
<body>
|
||||
<release version="1.3" date="TBD">
|
||||
<action type="add">
|
||||
Bump the version of a few dependencies to the
|
||||
latest versions (dependent HAPI modules listed in brackets):
|
||||
<![CDATA[
|
||||
<ul>
|
||||
<li>Springframework (JPA, Web Tester): 4.1.5 -> 4.2.1</li>
|
||||
<li>Hibernate (JPA, Web Tester): 4.2.17 -> 5.0.1</li>
|
||||
</ul>
|
||||
]]>
|
||||
</action>
|
||||
<action type="add">
|
||||
JPA server removes duplicate resource index entries before storing them
|
||||
(e.g. if a patient has the same name twice, only one index entry is created
|
||||
for that name)
|
||||
</action>
|
||||
<action type="fix">
|
||||
JPA server did not correctly index search parameters of type "reference" where the
|
||||
path had multiple entries (i.e. "Resource.path1 | Resource.path2")
|
||||
</action>
|
||||
<action type="fix">
|
||||
JPA server _history operations (server, type, instance) not correctly set the
|
||||
Bundle.entry.request.method to POST or PUT for create and updates of the resource.
|
||||
</action>
|
||||
<action type="add" issue="225">
|
||||
Support AND/OR on _id search parameter in JPA
|
||||
</action>
|
||||
<action type="fix">
|
||||
Constructor for DateRanfeParam which dates in two DateParam instances was ignoring
|
||||
comparators on the DateParam.
|
||||
</action>
|
||||
<action type="fix">
|
||||
In JSON parsing, finding an object where an array was expected led to an unhelpful
|
||||
error message. Thanks to Avinash Shanbhag for reporting!
|
||||
</action>
|
||||
<action type="add">
|
||||
JPA server gave an unhelpful error message if $meta-add or $meta-delete were called
|
||||
with no meta elements in the input Parameters
|
||||
</action>
|
||||
<action type="fix">
|
||||
Narrative generator did not include OperationOutcome.issue.diagnostics in the
|
||||
generated narrative.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire
|
||||
|
|
Loading…
Reference in New Issue