diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/PathSpecification.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/PathSpecification.java index cd4dc5a70d1..d0735007872 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/PathSpecification.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/PathSpecification.java @@ -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 { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateParam.java index d05f1851ac9..a05cb5b41e9 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateParam.java @@ -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 { - 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); - } - } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java index 4a26354a01c..72f38ebcbe9 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java @@ -214,8 +214,16 @@ public class DateRangeParam implements IQueryParameterAnd { * "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 { 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()); } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/QualifiedDateParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/QualifiedDateParam.java index 9277775927d..e0fedce6463 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/QualifiedDateParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/QualifiedDateParam.java @@ -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 diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java index 21f7c0866ba..a9479b8b625 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java @@ -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 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) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java index 2d8b384ae33..63048c6e56c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java @@ -36,6 +36,7 @@ public class DaoConfig { private List 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; + } + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java index 21132614b95..710d9826694 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java @@ -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 FhirResourceDaoDstu2implements IFhirResourceDaoSubscription { @@ -34,7 +35,7 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2 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 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 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 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; } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionCandidateResource.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionCandidateResource.java deleted file mode 100644 index 02616288289..00000000000 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionCandidateResource.java +++ /dev/null @@ -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; - } - -} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java index e602038f1c1..9ac60c9f6c6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java @@ -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; + } + } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java index 35e88788e3e..dbdc63ae895 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java @@ -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() { @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(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java index 3dd3d1bb0e1..9137609fc73 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java @@ -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"; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SubscriptionTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SubscriptionTest.java index 8916ea4eb5a..68018559a09 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SubscriptionTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SubscriptionTest.java @@ -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(); } diff --git a/hapi-fhir-jpaserver-base/src/test/resources/META-INF/persistence.xml b/hapi-fhir-jpaserver-base/src/test/resources/META-INF/persistence.xml index bad2178e79b..897f9420809 100644 --- a/hapi-fhir-jpaserver-base/src/test/resources/META-INF/persistence.xml +++ b/hapi-fhir-jpaserver-base/src/test/resources/META-INF/persistence.xml @@ -22,7 +22,6 @@ ca.uhn.fhir.jpa.entity.ResourceLink ca.uhn.fhir.jpa.entity.ResourceTag ca.uhn.fhir.jpa.entity.SubscriptionTable - ca.uhn.fhir.jpa.entity.SubscriptionCandidateResource ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource ca.uhn.fhir.jpa.entity.TagDefinition diff --git a/hapi-fhir-jpaserver-example/src/main/resources/META-INF/fhirtest_persistence.xml b/hapi-fhir-jpaserver-example/src/main/resources/META-INF/fhirtest_persistence.xml index 3b0edd509bd..29aef2bb642 100644 --- a/hapi-fhir-jpaserver-example/src/main/resources/META-INF/fhirtest_persistence.xml +++ b/hapi-fhir-jpaserver-example/src/main/resources/META-INF/fhirtest_persistence.xml @@ -21,7 +21,6 @@ ca.uhn.fhir.jpa.entity.ResourceTable ca.uhn.fhir.jpa.entity.ResourceTag ca.uhn.fhir.jpa.entity.SubscriptionTable - ca.uhn.fhir.jpa.entity.SubscriptionCandidateResource ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource ca.uhn.fhir.jpa.entity.TagDefinition diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/META-INF/fhirtest_persistence.xml b/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/META-INF/fhirtest_persistence.xml index 8fd4f7e4de4..ed759870e4e 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/META-INF/fhirtest_persistence.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/META-INF/fhirtest_persistence.xml @@ -21,7 +21,6 @@ ca.uhn.fhir.jpa.entity.ResourceTable ca.uhn.fhir.jpa.entity.ResourceTag ca.uhn.fhir.jpa.entity.SubscriptionTable - ca.uhn.fhir.jpa.entity.SubscriptionCandidateResource ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource ca.uhn.fhir.jpa.entity.TagDefinition diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/test/resources/fhir_jpatest_persistence.xml b/hapi-fhir-jpaserver-uhnfhirtest/src/test/resources/fhir_jpatest_persistence.xml index e655590260a..b5f2917f62f 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/src/test/resources/fhir_jpatest_persistence.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/src/test/resources/fhir_jpatest_persistence.xml @@ -17,7 +17,6 @@ ca.uhn.fhir.jpa.entity.ResourceTable ca.uhn.fhir.jpa.entity.ResourceTag ca.uhn.fhir.jpa.entity.SubscriptionTable - ca.uhn.fhir.jpa.entity.SubscriptionCandidateResource ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource true diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java index 105d22e155b..97553951cba 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java @@ -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()); diff --git a/hapi-fhir-testpage-overlay/src/test/resources/META-INF/persistence.xml b/hapi-fhir-testpage-overlay/src/test/resources/META-INF/persistence.xml index c91d1098ab5..cdfcfad2d68 100644 --- a/hapi-fhir-testpage-overlay/src/test/resources/META-INF/persistence.xml +++ b/hapi-fhir-testpage-overlay/src/test/resources/META-INF/persistence.xml @@ -22,7 +22,6 @@ ca.uhn.fhir.jpa.entity.ResourceLink ca.uhn.fhir.jpa.entity.ResourceTag ca.uhn.fhir.jpa.entity.SubscriptionTable - ca.uhn.fhir.jpa.entity.SubscriptionCandidateResource ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource ca.uhn.fhir.jpa.entity.TagDefinition diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 15be0c39bec..8f8c2692189 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -33,6 +33,10 @@ Support AND/OR on _id search parameter in JPA + + Constructor for DateRanfeParam which dates in two DateParam instances was ignoring + comparators on the DateParam. +