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:
James Agnew 2020-10-09 07:52:46 -04:00 committed by GitHub
parent a44037daf3
commit 2134d40f1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 160 additions and 65 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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."

View File

@ -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);
}

View File

@ -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
*/

View File

@ -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"));

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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()

View File

@ -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>