Correctly index timing events

This commit is contained in:
James Agnew 2019-05-31 16:42:45 -04:00
parent f6c7ff1dbb
commit be06c2ee19
5 changed files with 135 additions and 63 deletions

View File

@ -1,37 +1,11 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.*;
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
import org.hl7.fhir.instance.model.api.*;
import org.junit.*;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.jpa.model.entity.*;
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.parser.StrictErrorHandler;
@ -41,6 +15,41 @@ import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType;
import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
@SuppressWarnings("unchecked")
public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
@ -401,7 +410,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
myEncounterDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Encounter.SP_LOCATION_PERIOD, new DateParam("2011-12-12T11:12:12Z"))));
assertThat(actual, contains(id));
runInTransaction(()->{
runInTransaction(() -> {
Class<ResourceIndexedSearchParamDate> type = ResourceIndexedSearchParamDate.class;
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i WHERE i.myMissing = false", type).getResultList();
ourLog.info(toStringMultiline(results));
@ -425,7 +434,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
List<IIdType> actual = toUnqualifiedVersionlessIds(myImmunizationDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Immunization.SP_DOSE_SEQUENCE, new NumberParam("1"))));
assertThat(actual, contains(id));
runInTransaction(()-> {
runInTransaction(() -> {
Class<ResourceIndexedSearchParamNumber> type = ResourceIndexedSearchParamNumber.class;
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
ourLog.info(toStringMultiline(results));
@ -874,6 +883,27 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
}
}
@Test
public void testSearchDate_TimingValueUsingPeriod() {
ProcedureRequest p1 = new ProcedureRequest();
p1.setOccurrence(new Timing());
p1.getOccurrenceTiming().getRepeat().setBounds(new Period());
p1.getOccurrenceTiming().getRepeat().getBoundsPeriod().getStartElement().setValueAsString("2018-01-01");
p1.getOccurrenceTiming().getRepeat().getBoundsPeriod().getEndElement().setValueAsString("2018-02-01");
String id1 = myProcedureRequestDao.create(p1).getId().toUnqualifiedVersionless().getValue();
{
SearchParameterMap map = new SearchParameterMap()
.setLoadSynchronous(true)
.add(ProcedureRequest.SP_OCCURRENCE, new DateParam("lt2019"));
IBundleProvider found = myProcedureRequestDao.search(map);
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
assertEquals(1, found.size().intValue());
}
}
@Test
public void testSearchDateWrongParam() {
Patient p1 = new Patient();
@ -1526,7 +1556,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
dr01.setSubject(new Reference(patientId01));
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[]{patientId01, patientId02, obsId01, obsId02, drId01});
List<Observation> result = toList(myObservationDao
.search(new SearchParameterMap().setLoadSynchronous(true).add(Observation.SP_SUBJECT, new ReferenceParam(Patient.SP_IDENTIFIER, "urn:system|testSearchResourceLinkWithChain01"))));
@ -1631,7 +1661,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
Date after = new Date();
ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick();
ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", new Object[] { patientId01, locId01, obsId01, obsId02 });
ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", new Object[]{patientId01, locId01, obsId01, obsId02});
List<IIdType> result;
SearchParameterMap params;
@ -1694,7 +1724,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
dr01.setSubject(new Reference(patientId01));
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[]{patientId01, patientId02, obsId01, obsId02, drId01});
List<Observation> result = toList(
myObservationDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Observation.SP_SUBJECT, new ReferenceParam("testSearchResourceLinkWithTextLogicalId01"))));

View File

@ -1301,6 +1301,28 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
}
}
@Test
public void testSearchDate_TimingValueUsingPeriod() {
ServiceRequest p1 = new ServiceRequest();
p1.setOccurrence(new Timing());
p1.getOccurrenceTiming().getRepeat().setBounds(new Period());
p1.getOccurrenceTiming().getRepeat().getBoundsPeriod().getStartElement().setValueAsString("2018-01-01");
p1.getOccurrenceTiming().getRepeat().getBoundsPeriod().getEndElement().setValueAsString("2018-02-01");
String id1 = myServiceRequestDao.create(p1).getId().toUnqualifiedVersionless().getValue();
{
SearchParameterMap map = new SearchParameterMap()
.setLoadSynchronous(true)
.add(ServiceRequest.SP_OCCURRENCE, new DateParam("lt2019"));
IBundleProvider found = myServiceRequestDao.search(map);
assertThat(toUnqualifiedVersionlessIdValues(found), containsInAnyOrder(id1));
assertEquals(1, found.size().intValue());
}
}
@Test
public void testSearchDateWrongParam() {
Patient p1 = new Patient();

View File

@ -192,6 +192,14 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
}
}
}
if (nextValue.getRepeat().hasBounds()) {
if (nextValue.getRepeat().getBoundsPeriod().getStart() != null) {
dates.add(nextValue.getRepeat().getBoundsPeriod().getStart());
}
if (nextValue.getRepeat().getBoundsPeriod().getEnd() != null) {
dates.add(nextValue.getRepeat().getBoundsPeriod().getEnd());
}
}
if (dates.isEmpty()) {
continue;
}

View File

@ -201,6 +201,14 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
}
}
}
if (nextValue.getRepeat().hasBounds()) {
if (nextValue.getRepeat().getBoundsPeriod().getStart() != null) {
dates.add(nextValue.getRepeat().getBoundsPeriod().getStart());
}
if (nextValue.getRepeat().getBoundsPeriod().getEnd() != null) {
dates.add(nextValue.getRepeat().getBoundsPeriod().getEnd());
}
}
if (dates.isEmpty()) {
continue;
}

View File

@ -12,6 +12,10 @@
in small batches. This change will likely reduce performance, but does allow
for the operation to succeed without timing out in larger system.
</action>
<action type="fix">
The JPA server did not correctly index Timing fields where the timing contained
a period but no individual events. This has been corrected.
</action>
</release>
<release version="3.8.0" date="2019-05-30" description="Hippo">
<action type="fix">