Account for timezones in lastUpdated search (#2113)
* Add test * Fix * Add changelog * Test fixes * Test fix * Test fixes * Resolve fixme * Test fixes * Remove debug logs * Try to get CI tests passing again
This commit is contained in:
parent
a44037daf3
commit
2134d40f1c
|
@ -277,7 +277,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
|||
if (myLowerBound == null || myLowerBound.getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
int retVal = DateUtils.convertDatetoDayInteger(myLowerBound.getValue());
|
||||
int retVal = DateUtils.convertDateToDayInteger(myLowerBound.getValue());
|
||||
|
||||
if (myLowerBound.getPrefix() != null) {
|
||||
switch (myLowerBound.getPrefix()) {
|
||||
|
@ -308,7 +308,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
|||
if (myUpperBound == null || myUpperBound.getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
int retVal = DateUtils.convertDatetoDayInteger(myUpperBound.getValue());
|
||||
int retVal = DateUtils.convertDateToDayInteger(myUpperBound.getValue());
|
||||
if (myUpperBound.getPrefix() != null) {
|
||||
switch (myUpperBound.getPrefix()) {
|
||||
case LESSTHAN:
|
||||
|
|
|
@ -160,30 +160,42 @@ public final class DateUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Date getHighestInstantFromDate(Date theDateValue) {
|
||||
return getInstantFromDateWithTimezone(theDateValue, TimeZone.getTimeZone("GMT+11:30"));
|
||||
Calendar sourceCal = Calendar.getInstance();
|
||||
sourceCal.setTime(theDateValue);
|
||||
|
||||
}
|
||||
public static Date getLowestInstantFromDate(Date theDateValue) {
|
||||
return getInstantFromDateWithTimezone(theDateValue, TimeZone.getTimeZone("GMT-11:30"));
|
||||
}
|
||||
|
||||
public static Date getInstantFromDateWithTimezone(Date theDateValue, TimeZone theTimezone) {
|
||||
Calendar cal = org.apache.commons.lang3.time.DateUtils.toCalendar(theDateValue);
|
||||
cal.setTimeZone(theTimezone);
|
||||
cal = org.apache.commons.lang3.time.DateUtils.truncate(cal, Calendar.DATE);
|
||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-12:00"));
|
||||
copyDateAndTrundateTime(sourceCal, cal);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
public static int convertDatetoDayInteger(final Date theDateValue) {
|
||||
public static Date getLowestInstantFromDate(Date theDateValue) {
|
||||
Calendar sourceCal = Calendar.getInstance();
|
||||
sourceCal.setTime(theDateValue);
|
||||
|
||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+14:00"));
|
||||
copyDateAndTrundateTime(sourceCal, cal);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
private static void copyDateAndTrundateTime(Calendar theSourceCal, Calendar theCal) {
|
||||
theCal.set(Calendar.YEAR, theSourceCal.get(Calendar.YEAR));
|
||||
theCal.set(Calendar.MONTH, theSourceCal.get(Calendar.MONTH));
|
||||
theCal.set(Calendar.DAY_OF_MONTH, theSourceCal.get(Calendar.DAY_OF_MONTH));
|
||||
theCal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
theCal.set(Calendar.MINUTE, 0);
|
||||
theCal.set(Calendar.SECOND, 0);
|
||||
theCal.set(Calendar.MILLISECOND, 0);
|
||||
}
|
||||
|
||||
public static int convertDateToDayInteger(final Date theDateValue) {
|
||||
notNull(theDateValue, "Date value");
|
||||
SimpleDateFormat format = new SimpleDateFormat(PATTERN_INTEGER_DATE);
|
||||
String theDateString = format.format(theDateValue);
|
||||
return Integer.parseInt(theDateString);
|
||||
}
|
||||
|
||||
public static String convertDateToIso8601String(final Date theDateValue){
|
||||
public static String convertDateToIso8601String(final Date theDateValue) {
|
||||
notNull(theDateValue, "Date value");
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
|
||||
return format.format(theDateValue);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: fix
|
||||
issue: 2113
|
||||
title: "When performing a `_lastUpdated` search in the JPA server where the parameter value(s) are supplied with date
|
||||
(not time) precision, a timezone bug could cause some resoutces to not be included. This has been corrected."
|
|
@ -1029,6 +1029,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
lastUpdatedPredicates.add(predicateLower);
|
||||
}
|
||||
if (theLastUpdated.getUpperBoundAsInstant() != null) {
|
||||
ourLog.debug("LastUpdated upper bound: {}", new InstantDt(theLastUpdated.getUpperBoundAsInstant()));
|
||||
Predicate predicateUpper = builder.lessThanOrEqualTo(myQueryStack.getLastUpdatedColumn(), theLastUpdated.getUpperBoundAsInstant());
|
||||
lastUpdatedPredicates.add(predicateUpper);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.util.SqlQuery;
|
|||
import ca.uhn.fhir.jpa.util.TestUtil;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -54,6 +55,7 @@ import ca.uhn.fhir.util.HapiExtensions;
|
|||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -575,6 +577,33 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
assertThat(ids, empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLastUpdatedWithDateOnly() {
|
||||
SearchParameterMap map;
|
||||
List<String> ids;
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setName("O1");
|
||||
String orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
String yesterday = new DateType(DateUtils.addDays(new Date(), -1)).getValueAsString();
|
||||
String tomorrow = new DateType(DateUtils.addDays(new Date(), 1)).getValueAsString();
|
||||
|
||||
runInTransaction(()->{
|
||||
ourLog.info("Resources:\n * {}", myResourceTableDao.findAll().stream().map(t->t.toString()).collect(Collectors.joining("\n * ")));
|
||||
});
|
||||
|
||||
RuntimeResourceDefinition resDef = myFhirCtx.getResourceDefinition("DiagnosticReport");
|
||||
map = myMatchUrlService.translateMatchUrl("Organization?_lastUpdated=gt" + yesterday + "&_lastUpdated=lt" + tomorrow, resDef);
|
||||
map.setLoadSynchronous(true);
|
||||
myCaptureQueriesListener.clear();
|
||||
ids = toUnqualifiedVersionlessIdValues(myOrganizationDao.search(map));
|
||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
|
||||
assertThat(ids, contains(orgId));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #1053
|
||||
*/
|
||||
|
|
|
@ -71,6 +71,8 @@ import java.math.BigDecimal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
@ -100,11 +102,11 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
assertEquals(SubscriptionMatchingStrategy.IN_MEMORY, mySubscriptionStrategyEvaluator.determineStrategy(getCriteria(resource, params)));
|
||||
}
|
||||
|
||||
private void assertNotMatched(Resource resource, SearchParameterMap params) {
|
||||
InMemoryMatchResult result = match(resource, params);
|
||||
private void assertNotMatched(Resource theResource, SearchParameterMap theParams) {
|
||||
InMemoryMatchResult result = match(theResource, theParams);
|
||||
assertTrue(result.supported(), result.getUnsupportedReason());
|
||||
assertFalse(result.matched());
|
||||
assertEquals(SubscriptionMatchingStrategy.IN_MEMORY, mySubscriptionStrategyEvaluator.determineStrategy(getCriteria(resource, params)));
|
||||
assertFalse(result.matched(), "Failed on ID: " + theResource.getId());
|
||||
assertEquals(SubscriptionMatchingStrategy.IN_MEMORY, mySubscriptionStrategyEvaluator.determineStrategy(getCriteria(theResource, theParams)));
|
||||
}
|
||||
|
||||
private InMemoryMatchResult match(Resource theResource, SearchParameterMap theParams) {
|
||||
|
@ -931,10 +933,11 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
public void testDateSearchParametersShouldBeTimezoneIndependent() {
|
||||
|
||||
List<Observation> nlist = new ArrayList<>();
|
||||
nlist.add(createObservationWithEffective("NO2", "2011-01-03T00:00:00+01:00"));
|
||||
nlist.add(createObservationWithEffective("NO1", "2011-01-01T10:00:00+01:00"));
|
||||
nlist.add(createObservationWithEffective("NO2", "2011-01-03T13:00:00+01:00"));
|
||||
|
||||
List<Observation> ylist = new ArrayList<>();
|
||||
nlist.add(createObservationWithEffective("YES00", "2011-01-02T23:00:00-11:30"));
|
||||
ylist.add(createObservationWithEffective("YES00", "2011-01-02T23:00:00-11:30"));
|
||||
ylist.add(createObservationWithEffective("YES01", "2011-01-02T00:00:00-11:30"));
|
||||
ylist.add(createObservationWithEffective("YES02", "2011-01-02T00:00:00-10:00"));
|
||||
ylist.add(createObservationWithEffective("YES03", "2011-01-02T00:00:00-09:00"));
|
||||
|
@ -959,6 +962,7 @@ public class InMemorySubscriptionMatcherR4Test {
|
|||
ylist.add(createObservationWithEffective("YES22", "2011-01-02T00:00:00+10:00"));
|
||||
ylist.add(createObservationWithEffective("YES23", "2011-01-02T00:00:00+11:00"));
|
||||
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+01:00"));
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Observation.SP_DATE, new DateParam("2011-01-02"));
|
||||
|
|
|
@ -157,7 +157,7 @@ public abstract class BaseResourceIndexedSearchParam extends BaseResourceIndex {
|
|||
super.setPartitionId(theRequestPartitionId);
|
||||
}
|
||||
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
throw new UnsupportedOperationException("No parameter matcher for " + theParam);
|
||||
}
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
if (!(theParam instanceof DateParam)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -271,9 +271,8 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
|
||||
|
||||
boolean result;
|
||||
if (theUseOrdinalDatesForDayComparison) {
|
||||
if (dateParam.getPrecision().ordinal() <= TemporalPrecisionEnum.DAY.ordinal()) {
|
||||
result = matchesOrdinalDateBounds(range);
|
||||
result = matchesDateBounds(range);
|
||||
} else {
|
||||
result = matchesDateBounds(range);
|
||||
}
|
||||
|
@ -324,7 +323,7 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar
|
|||
if (theDate == null) {
|
||||
return null;
|
||||
}
|
||||
return (long) DateUtils.convertDatetoDayInteger(theDate);
|
||||
return (long) DateUtils.convertDateToDayInteger(theDate);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchP
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
if (!(theParam instanceof NumberParam)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
if (!(theParam instanceof QuantityParam)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
if (!(theParam instanceof StringParam)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
if (!(theParam instanceof TokenParam)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ public class ResourceIndexedSearchParamUri extends BaseResourceIndexedSearchPara
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matches(IQueryParameterType theParam) {
|
||||
if (!(theParam instanceof UriParam)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -575,6 +575,7 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
|||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append("pid", myId);
|
||||
b.append("resourceType", myResourceType);
|
||||
b.append("lastUpdated", getUpdated().getValueAsString());
|
||||
if (getDeleted() != null) {
|
||||
b.append("deleted");
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ public final class ResourceIndexedSearchParams {
|
|||
return myPopulatedResourceLinkParameters;
|
||||
}
|
||||
|
||||
public boolean matchParam(ModelConfig theModelConfig, String theResourceName, String theParamName, RuntimeSearchParam theParamDef, IQueryParameterType theParam, boolean theUseOrdinalDatesForDayComparison) {
|
||||
public boolean matchParam(ModelConfig theModelConfig, String theResourceName, String theParamName, RuntimeSearchParam theParamDef, IQueryParameterType theParam) {
|
||||
if (theParamDef == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ public final class ResourceIndexedSearchParams {
|
|||
}
|
||||
Predicate<BaseResourceIndexedSearchParam> namedParamPredicate = param ->
|
||||
param.getParamName().equalsIgnoreCase(theParamName) &&
|
||||
param.matches(theParam, theUseOrdinalDatesForDayComparison);
|
||||
param.matches(theParam);
|
||||
|
||||
return resourceParams.stream().anyMatch(namedParamPredicate);
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ public class InMemoryResourceMatcher {
|
|||
if (theSearchParams == null) {
|
||||
return InMemoryMatchResult.successfulMatch();
|
||||
} else {
|
||||
return InMemoryMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theModelConfig, theResourceName, theParamName, theParamDef, nextAnd, theSearchParams, myModelConfig.getUseOrdinalDatesForDayPrecisionSearches())));
|
||||
return InMemoryMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theModelConfig, theResourceName, theParamName, theParamDef, nextAnd, theSearchParams)));
|
||||
}
|
||||
case COMPOSITE:
|
||||
case HAS:
|
||||
|
@ -216,8 +216,8 @@ public class InMemoryResourceMatcher {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean matchParams(ModelConfig theModelConfig, String theResourceName, String theParamName, RuntimeSearchParam paramDef, List<? extends IQueryParameterType> theNextAnd, ResourceIndexedSearchParams theSearchParams,boolean theUseOrdinalDatesForDayComparison) {
|
||||
return theNextAnd.stream().anyMatch(token -> theSearchParams.matchParam(theModelConfig, theResourceName, theParamName, paramDef, token, theUseOrdinalDatesForDayComparison));
|
||||
private boolean matchParams(ModelConfig theModelConfig, String theResourceName, String theParamName, RuntimeSearchParam paramDef, List<? extends IQueryParameterType> theNextAnd, ResourceIndexedSearchParams theSearchParams) {
|
||||
return theNextAnd.stream().anyMatch(token -> theSearchParams.matchParam(theModelConfig, theResourceName, theParamName, paramDef, token));
|
||||
}
|
||||
|
||||
private boolean hasChain(List<List<IQueryParameterType>> theAndOrParams) {
|
||||
|
|
|
@ -41,9 +41,12 @@ import static org.mockito.Mockito.when;
|
|||
@ExtendWith(SpringExtension.class)
|
||||
public class InMemoryResourceMatcherR5Test {
|
||||
public static final String OBSERVATION_DATE = "1970-10-17";
|
||||
public static final String OBSERVATION_DATETIME = OBSERVATION_DATE + "T01:00:00-08:30";
|
||||
public static final String OBSERVATION_CODE = "MATCH";
|
||||
private static final String EARLY_DATE = "1965-08-09";
|
||||
private static final String LATE_DATE = "2000-06-29";
|
||||
private static final String EARLY_DATETIME = EARLY_DATE + "T12:00:00Z";
|
||||
private static final String LATE_DATETIME = LATE_DATE + "T12:00:00Z";
|
||||
private static final String SOURCE_URI = "urn:source:0";
|
||||
private static final String REQUEST_ID = "a_request_id";
|
||||
private static final String TEST_SOURCE = SOURCE_URI + "#" + REQUEST_ID;
|
||||
|
@ -70,7 +73,7 @@ public class InMemoryResourceMatcherR5Test {
|
|||
|
||||
myObservation = new Observation();
|
||||
myObservation.getMeta().setSource(TEST_SOURCE);
|
||||
myObservation.setEffective(new DateTimeType(OBSERVATION_DATE));
|
||||
myObservation.setEffective(new DateTimeType(OBSERVATION_DATETIME));
|
||||
CodeableConcept codeableConcept = new CodeableConcept();
|
||||
codeableConcept.addCoding().setCode(OBSERVATION_CODE);
|
||||
myObservation.setCode(codeableConcept);
|
||||
|
@ -120,34 +123,52 @@ public class InMemoryResourceMatcherR5Test {
|
|||
}
|
||||
|
||||
private void testDateUnsupportedDateOp(ParamPrefixEnum theOperator) {
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match("date=" + theOperator.getValue() + OBSERVATION_DATE, myObservation, mySearchParams);
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match("date=" + theOperator.getValue() + OBSERVATION_DATETIME, myObservation, mySearchParams);
|
||||
assertFalse(result.supported());
|
||||
assertEquals("Parameter: <date> Reason: The prefix " + theOperator + " is not supported for param type DATE", result.getUnsupportedReason());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateSupportedOps() {
|
||||
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN, true, false, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, true, true, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.EQUAL, false, true, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.LESSTHAN_OR_EQUALS, false, true, true);
|
||||
testDateSupportedOp(ParamPrefixEnum.LESSTHAN, false, false, true);
|
||||
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN, false, true, false, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, false, true, true, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.EQUAL, false, false, true, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.LESSTHAN_OR_EQUALS, false, false, true, true);
|
||||
testDateSupportedOp(ParamPrefixEnum.LESSTHAN, false, false, false, true);
|
||||
}
|
||||
|
||||
private void testDateSupportedOp(ParamPrefixEnum theOperator, boolean theEarly, boolean theSame, boolean theLater) {
|
||||
@Test
|
||||
public void testDateTimeSupportedOps() {
|
||||
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN, true, true, false, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, true, true, true, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.EQUAL, true, false, true, false);
|
||||
testDateSupportedOp(ParamPrefixEnum.LESSTHAN_OR_EQUALS, true, false, true, true);
|
||||
testDateSupportedOp(ParamPrefixEnum.LESSTHAN, true, false, false, true);
|
||||
}
|
||||
|
||||
private void testDateSupportedOp(ParamPrefixEnum theOperator, boolean theIncludeTime, boolean theEarly, boolean theSame, boolean theLater) {
|
||||
String earlyDate = EARLY_DATE;
|
||||
String observationDate = OBSERVATION_DATE;
|
||||
String lateDate = LATE_DATE;
|
||||
if (theIncludeTime) {
|
||||
earlyDate = EARLY_DATETIME;
|
||||
observationDate = OBSERVATION_DATETIME;
|
||||
lateDate = LATE_DATETIME;
|
||||
}
|
||||
|
||||
String equation = "date=" + theOperator.getValue();
|
||||
{
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + EARLY_DATE, myObservation, mySearchParams);
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + earlyDate, myObservation, mySearchParams);
|
||||
assertTrue(result.supported(), result.getUnsupportedReason());
|
||||
assertEquals(result.matched(), theEarly);
|
||||
}
|
||||
{
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + OBSERVATION_DATE, myObservation, mySearchParams);
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + observationDate, myObservation, mySearchParams);
|
||||
assertTrue(result.supported(), result.getUnsupportedReason());
|
||||
assertEquals(result.matched(), theSame);
|
||||
}
|
||||
{
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + LATE_DATE, myObservation, mySearchParams);
|
||||
InMemoryMatchResult result = myInMemoryResourceMatcher.match(equation + lateDate, myObservation, mySearchParams);
|
||||
assertTrue(result.supported(), result.getUnsupportedReason());
|
||||
assertEquals(result.matched(), theLater);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
@ -39,6 +40,7 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -47,8 +49,10 @@ import static ca.uhn.fhir.rest.param.ParamPrefixEnum.GREATERTHAN_OR_EQUALS;
|
|||
import static ca.uhn.fhir.rest.param.ParamPrefixEnum.LESSTHAN_OR_EQUALS;
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class DateRangeParamR4Test {
|
||||
|
||||
|
@ -66,10 +70,10 @@ public class DateRangeParamR4Test {
|
|||
|
||||
static {
|
||||
ourFmtLower = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
||||
ourFmtLower.setTimeZone(TimeZone.getTimeZone("GMT-11:30"));
|
||||
ourFmtLower.setTimeZone(TimeZone.getTimeZone("GMT-10:00"));
|
||||
|
||||
ourFmtUpper = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
||||
ourFmtUpper.setTimeZone(TimeZone.getTimeZone("GMT+11:30"));
|
||||
ourFmtUpper.setTimeZone(TimeZone.getTimeZone("GMT+12:00"));
|
||||
|
||||
ourFmtLowerForTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
||||
ourFmtUpperForTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
||||
|
@ -109,7 +113,7 @@ public class DateRangeParamR4Test {
|
|||
assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString());
|
||||
|
||||
assertEquals(parseLowerForDatePrecision("2012-01-01 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-03 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getLowerBound().getPrefix());
|
||||
assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getUpperBound().getPrefix());
|
||||
}
|
||||
|
@ -125,7 +129,7 @@ public class DateRangeParamR4Test {
|
|||
assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString());
|
||||
|
||||
assertEquals(parseLowerForDatePrecision("2012-01-01 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-03 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getLowerBound().getPrefix());
|
||||
assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getUpperBound().getPrefix());
|
||||
}
|
||||
|
@ -157,7 +161,7 @@ public class DateRangeParamR4Test {
|
|||
assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString());
|
||||
|
||||
assertEquals(null, ourLastDateRange.getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-01 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(null, ourLastDateRange.getLowerBound());
|
||||
assertEquals(ParamPrefixEnum.LESSTHAN, ourLastDateRange.getUpperBound().getPrefix());
|
||||
}
|
||||
|
@ -189,11 +193,30 @@ public class DateRangeParamR4Test {
|
|||
assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString());
|
||||
|
||||
assertEquals(null, ourLastDateRange.getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-03 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
|
||||
assertEquals(null, ourLastDateRange.getLowerBound());
|
||||
assertEquals(ParamPrefixEnum.LESSTHAN_OR_EQUALS, ourLastDateRange.getUpperBound().getPrefix());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangeWithDatePrecision() throws Exception {
|
||||
HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=gt2012-01-01&birthdate=lt2012-01-03");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
consumeResponse(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString());
|
||||
Date lowerBoundInstant = ourLastDateRange.getLowerBoundAsInstant();
|
||||
Date midnightLower = new InstantDt("2012-01-01T00:00:00Z").getValue();
|
||||
assertTrue(lowerBoundInstant.after(midnightLower));
|
||||
|
||||
assertEquals("2012-01-03", ourLastDateRange.getUpperBound().getValueAsString());
|
||||
Date upperBoundInstant = ourLastDateRange.getUpperBoundAsInstant();
|
||||
Date midnightUpper = new InstantDt("2012-01-03T00:00:00Z").getValue();
|
||||
assertTrue(upperBoundInstant.after(midnightUpper));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAnd() {
|
||||
assertEquals(1, new DateAndListParam().addAnd(new DateOrListParam()).getValuesAsQueryTokens().size());
|
||||
|
@ -227,26 +250,26 @@ public class DateRangeParamR4Test {
|
|||
@Test
|
||||
public void testDay() throws Exception {
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-02 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-02 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-04 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getUpperBoundAsInstant());
|
||||
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create("ge2011-01-01", "lt2011-01-02").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-02 00:00:00.0000"), create("ge2011-01-01", "lt2011-01-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create("ge2011-01-01", "lt2011-01-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-02 00:00:00.0000"), create("gt2011-01-01", "le2011-01-02").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create("gt2011-01-01", "le2011-01-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-04 00:00:00.0000"), create("gt2011-01-01", "le2011-01-02").getUpperBoundAsInstant());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromQualifiedDateParam() throws Exception {
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create("2011-01-01").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-02 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
|
||||
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create("ge2011-01-01").getLowerBoundAsInstant());
|
||||
assertEquals(null, create("ge2011-01-01").getUpperBoundAsInstant());
|
||||
|
||||
assertEquals(null, create("le2011-01-01").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-02 00:00:00.0000"), create("le2011-01-01").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create("le2011-01-01").getUpperBoundAsInstant());
|
||||
}
|
||||
|
||||
private DateRangeParam create(String theString) {
|
||||
|
@ -256,16 +279,16 @@ public class DateRangeParamR4Test {
|
|||
@Test
|
||||
public void testMonth() throws Exception {
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create("ge2011-01", "lt2011-02").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-02-01 00:00:00.0000"), create("ge2011-01", "lt2011-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-02-02 00:00:00.0000"), create("ge2011-01", "lt2011-02").getUpperBoundAsInstant());
|
||||
|
||||
assertEquals(parseLowerForDatePrecision("2011-02-01 00:00:00.0000"), create("gt2011-01", "le2011-02").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-03-01 00:00:00.0000"), create("gt2011-01", "le2011-02").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-03-02 00:00:00.0000"), create("gt2011-01", "le2011-02").getUpperBoundAsInstant());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyOneParam() throws Exception {
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create("2011-01-01").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-02 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2011-01-03 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -358,10 +381,10 @@ public class DateRangeParamR4Test {
|
|||
@Test
|
||||
public void testYear() throws Exception {
|
||||
assertEquals(parseLowerForDatePrecision("2011-01-01 00:00:00.0000"), create("ge2011", "lt2012").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-01 00:00:00.0000"), create("ge2011", "lt2012").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2012-01-02 00:00:00.0000"), create("ge2011", "lt2012").getUpperBoundAsInstant());
|
||||
|
||||
assertEquals(parseLowerForDatePrecision("2012-01-01 00:00:00.0000"), create("gt2011", "le2012").getLowerBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2014-01-01 00:00:00.0000"), create("gt2011", "le2013").getUpperBoundAsInstant());
|
||||
assertEquals(parseUpperForDatePrecision("2014-01-02 00:00:00.0000"), create("gt2011", "le2013").getUpperBoundAsInstant());
|
||||
}
|
||||
|
||||
@Test()
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -2551,7 +2551,7 @@
|
|||
<profile>
|
||||
<id>CI</id>
|
||||
<properties>
|
||||
<surefire_jvm_args>-Dfile.encoding=UTF-8 -Xmx2048m -XX:TieredStopAtLevel=1 -XX:+UseParallelGC -Xverify:none -Dfile.encoding=UTF-8 -Xss128M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=2048M</surefire_jvm_args>
|
||||
<surefire_jvm_args>-Dspring.test.context.cache.maxSize=2 -Dfile.encoding=UTF-8 -Xmx2648m -XX:TieredStopAtLevel=1 -Xverify:none -Dfile.encoding=UTF-8 -Xss128M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=2048M</surefire_jvm_args>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
Loading…
Reference in New Issue