Work on subscriptions, and correct an issue with DateRangeParam where comparators get ignored
This commit is contained in:
parent
ef6a9302c0
commit
a15ed8e944
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -87,7 +87,6 @@ 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.SubscriptionCandidateResource;
|
||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||
|
@ -1217,18 +1216,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
postUpdate(theEntity, (T) theResource);
|
||||
}
|
||||
|
||||
/*
|
||||
* When subscription is enabled, for each resource we store we also
|
||||
* store a subscription candidate. These are examined by the subscription
|
||||
* module and then deleted.
|
||||
*/
|
||||
if (myConfig.isSubscriptionEnabled() && thePerformIndexing) {
|
||||
SubscriptionCandidateResource candidate = new SubscriptionCandidateResource();
|
||||
candidate.setResource(theEntity);
|
||||
candidate.setResourceVersion(theEntity.getVersion());
|
||||
myEntityManager.persist(candidate);
|
||||
}
|
||||
|
||||
if (thePerformIndexing) {
|
||||
|
||||
if (paramsStringPopulated) {
|
||||
|
|
|
@ -36,6 +36,7 @@ public class DaoConfig {
|
|||
private List<IServerInterceptor> myInterceptors;
|
||||
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
||||
private boolean mySubscriptionEnabled;
|
||||
private long mySubscriptionPollDelay = 1000;
|
||||
|
||||
/**
|
||||
* See {@link #setIncludeLimit(int)}
|
||||
|
@ -65,6 +66,10 @@ public class DaoConfig {
|
|||
return myResourceEncoding;
|
||||
}
|
||||
|
||||
public long getSubscriptionPollDelay() {
|
||||
return mySubscriptionPollDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #setSubscriptionEnabled(boolean)}
|
||||
*/
|
||||
|
@ -133,4 +138,8 @@ public class DaoConfig {
|
|||
mySubscriptionEnabled = theSubscriptionEnabled;
|
||||
}
|
||||
|
||||
public void setSubscriptionPollDelay(long theSubscriptionPollDelay) {
|
||||
mySubscriptionPollDelay = theSubscriptionPollDelay;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.util.List;
|
|||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
@ -19,11 +18,13 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
|||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
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.model.primitive.IdDt;
|
||||
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> {
|
||||
|
@ -34,7 +35,7 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
SubscriptionTable subscriptionEntity = new SubscriptionTable();
|
||||
subscriptionEntity.setSubscriptionResource(theEntity);
|
||||
subscriptionEntity.setNextCheck(theEntity.getPublished().getValue());
|
||||
subscriptionEntity.setNextCheckSince(theEntity.getPublished().getValue());
|
||||
subscriptionEntity.setMostRecentMatch(theEntity.getPublished().getValue());
|
||||
subscriptionEntity.setStatus(theSubscription.getStatusElement().getValueAsEnum());
|
||||
myEntityManager.persist(subscriptionEntity);
|
||||
}
|
||||
|
@ -55,6 +56,37 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
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());
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,6 +124,25 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
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");
|
||||
|
@ -113,21 +164,7 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
} catch (DataFormatException e) {
|
||||
throw new UnprocessableEntityException("Subscription.criteria contains invalid/unsupported resource type: " + resType);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
return resDef;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.entity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
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_CAND_RES")
|
||||
public class SubscriptionCandidateResource {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
@SequenceGenerator(name = "SEQ_SUBSCRIPTION_CAND_ID", sequenceName = "SEQ_SUBSCRIPTION_CAND_ID")
|
||||
@Column(name = "PID", insertable = false, updatable = false)
|
||||
private Long myId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID")
|
||||
private ResourceTable myResource;
|
||||
|
||||
@Column(name = "RES_VERSION", nullable = false)
|
||||
private long myResourceVersion;
|
||||
|
||||
public ResourceTable getResource() {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
public long getResourceVersion() {
|
||||
return myResourceVersion;
|
||||
}
|
||||
|
||||
public void setResource(ResourceTable theResource) {
|
||||
myResource = theResource;
|
||||
}
|
||||
|
||||
public void setResourceVersion(long theResourceVersion) {
|
||||
myResourceVersion = theResourceVersion;
|
||||
}
|
||||
|
||||
}
|
|
@ -51,8 +51,8 @@ public class SubscriptionTable {
|
|||
private Date myNextCheck;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "NEXT_CHECK_SINCE", nullable = false)
|
||||
private Date myNextCheckSince;
|
||||
@Column(name = "MOST_RECENT_MATCH", nullable = false)
|
||||
private Date myMostRecentMatch;
|
||||
|
||||
@Column(name = "RES_ID", insertable = false, updatable = false)
|
||||
private Long myResId;
|
||||
|
@ -77,10 +77,6 @@ public class SubscriptionTable {
|
|||
return myNextCheck;
|
||||
}
|
||||
|
||||
public Date getNextCheckSince() {
|
||||
return myNextCheckSince;
|
||||
}
|
||||
|
||||
public SubscriptionStatusEnum getStatus() {
|
||||
return myStatus;
|
||||
}
|
||||
|
@ -97,10 +93,6 @@ public class SubscriptionTable {
|
|||
myNextCheck = theNextCheck;
|
||||
}
|
||||
|
||||
public void setNextCheckSince(Date theNextCheckSince) {
|
||||
myNextCheckSince = theNextCheckSince;
|
||||
}
|
||||
|
||||
public void setStatus(SubscriptionStatusEnum theStatus) {
|
||||
myStatus = theStatus;
|
||||
}
|
||||
|
@ -109,4 +101,12 @@ public class SubscriptionTable {
|
|||
mySubscriptionResource = theSubscriptionResource;
|
||||
}
|
||||
|
||||
public Date getMostRecentMatch() {
|
||||
return myMostRecentMatch;
|
||||
}
|
||||
|
||||
public void setMostRecentMatch(Date theMostRecentMatch) {
|
||||
myMostRecentMatch = theMostRecentMatch;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ 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.SubscriptionCandidateResource;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource;
|
||||
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
|
||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
||||
|
@ -186,7 +185,6 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
entityManager.createQuery("DELETE from " + SubscriptionCandidateResource.class.getSimpleName() + " d").executeUpdate();
|
||||
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();
|
||||
|
|
|
@ -63,6 +63,7 @@ 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;
|
||||
|
@ -638,6 +639,72 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@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";
|
||||
|
|
|
@ -88,7 +88,9 @@ public class FhirResourceDaoDstu2SubscriptionTest extends BaseJpaDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriptionResourcesAppear() {
|
||||
public void testSubscriptionResourcesAppear() throws Exception {
|
||||
myDaoConfig.setSubscriptionPollDelay(0);
|
||||
|
||||
String methodName = "testSubscriptionResourcesAppear";
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
|
@ -101,10 +103,13 @@ public class FhirResourceDaoDstu2SubscriptionTest extends BaseJpaDstu2Test {
|
|||
|
||||
Subscription subs = new Subscription();
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setCriteria("Observation?subject=Patient/123");
|
||||
subs.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
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);
|
||||
|
@ -115,6 +120,10 @@ public class FhirResourceDaoDstu2SubscriptionTest extends BaseJpaDstu2Test {
|
|||
obs.setStatus(ObservationStatusEnum.FINAL);
|
||||
IIdType afterId2 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
|
||||
|
||||
Thread.sleep(100);
|
||||
|
||||
ourLog.info("After: {}", System.currentTimeMillis());
|
||||
|
||||
mySubscriptionDao.pollForNewUndeliveredResources();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
<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.SubscriptionCandidateResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
<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.SubscriptionCandidateResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
<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.SubscriptionCandidateResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
<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.SubscriptionCandidateResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
<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.SubscriptionCandidateResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource</class>
|
||||
<class>ca.uhn.fhir.jpa.entity.TagDefinition</class>
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
<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>
|
||||
</release>
|
||||
<release version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue