More perf work
This commit is contained in:
parent
c5c154346e
commit
fa435fb8b2
|
@ -46,6 +46,7 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.web.servlet.ThemeResolver;
|
import org.springframework.web.servlet.ThemeResolver;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
@ -100,7 +101,7 @@ public class SearchBuilder {
|
||||||
private Root<ResourceTable> myResourceTableRoot;
|
private Root<ResourceTable> myResourceTableRoot;
|
||||||
private ArrayList<Predicate> myPredicates;
|
private ArrayList<Predicate> myPredicates;
|
||||||
private CriteriaBuilder myBuilder;
|
private CriteriaBuilder myBuilder;
|
||||||
private CriteriaQuery<Tuple> myResourceTableQuery;
|
private AbstractQuery<Long> myResourceTableQuery;
|
||||||
private PlatformTransactionManager myPlatformTransactionManager;
|
private PlatformTransactionManager myPlatformTransactionManager;
|
||||||
|
|
||||||
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theFulltextSearchSvc,
|
public SearchBuilder(FhirContext theFhirContext, EntityManager theEntityManager, PlatformTransactionManager thePlatformTransactionManager, IFulltextSearchSvc theFulltextSearchSvc,
|
||||||
|
@ -1257,19 +1258,20 @@ public class SearchBuilder {
|
||||||
throw new InvalidRequestException("This server does not support _sort specifications of type " + param.getParamType() + " - Can't serve _sort=" + theSort.getParamName());
|
throw new InvalidRequestException("This server does not support _sort specifications of type " + param.getParamType() + " - Can't serve _sort=" + theSort.getParamName());
|
||||||
}
|
}
|
||||||
|
|
||||||
From<?, ?> stringJoin = theFrom.join(joinAttrName, JoinType.INNER);
|
From<?, ?> join = theFrom.join(joinAttrName, JoinType.LEFT);
|
||||||
|
|
||||||
if (param.getParamType() == RestSearchParameterTypeEnum.REFERENCE) {
|
if (param.getParamType() == RestSearchParameterTypeEnum.REFERENCE) {
|
||||||
thePredicates.add(stringJoin.get("mySourcePath").as(String.class).in(param.getPathsSplit()));
|
thePredicates.add(join.get("mySourcePath").as(String.class).in(param.getPathsSplit()));
|
||||||
} else {
|
} else {
|
||||||
thePredicates.add(theBuilder.equal(stringJoin.get("myParamName"), theSort.getParamName()));
|
Predicate joinParam1 = theBuilder.equal(join.get("myParamName"), theSort.getParamName());
|
||||||
|
thePredicates.add(joinParam1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String next : sortAttrName) {
|
for (String next : sortAttrName) {
|
||||||
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
if (theSort.getOrder() == null || theSort.getOrder() == SortOrderEnum.ASC) {
|
||||||
theOrders.add(theBuilder.asc(stringJoin.get(next)));
|
theOrders.add(theBuilder.asc(join.get(next)));
|
||||||
} else {
|
} else {
|
||||||
theOrders.add(theBuilder.desc(stringJoin.get(next)));
|
theOrders.add(theBuilder.desc(join.get(next)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,27 +1472,53 @@ public class SearchBuilder {
|
||||||
|
|
||||||
public List<Long> loadSearchPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
public List<Long> loadSearchPage(SearchParameterMap theParams, int theFromIndex, int theToIndex) {
|
||||||
|
|
||||||
// if (myFulltextSearchSvc == null) {
|
|
||||||
// if (theParams.containsKey(Constants.PARAM_TEXT)) {
|
|
||||||
// throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
|
|
||||||
// } else if (theParams.containsKey(Constants.PARAM_CONTENT)) {
|
|
||||||
// throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // FIXME: add from and to
|
|
||||||
// List<Long> searchResultPids = myFulltextSearchSvc.search(myResourceName, theParams);
|
|
||||||
// if (searchResultPids != null) {
|
|
||||||
// if (searchResultPids.isEmpty()) {
|
|
||||||
// return Collections.emptyList();
|
|
||||||
// }
|
|
||||||
// return searchResultPids;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
myBuilder = myEntityManager.getCriteriaBuilder();
|
myBuilder = myEntityManager.getCriteriaBuilder();
|
||||||
myResourceTableQuery = myBuilder.createTupleQuery();
|
CriteriaQuery<Long> outerQuery = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort
|
||||||
|
*
|
||||||
|
* If we have a sort, we wrap the criteria search (the search that actually
|
||||||
|
* finds the appropriate resources) in an outer search which is then sorted
|
||||||
|
*/
|
||||||
|
if (theParams.getSort() != null) {
|
||||||
|
|
||||||
|
outerQuery = myBuilder.createQuery(Long.class);
|
||||||
|
Root<ResourceTable> outerQueryFrom = outerQuery.from(ResourceTable.class);
|
||||||
|
|
||||||
|
List<Order> orders = Lists.newArrayList();
|
||||||
|
List<Predicate> predicates = Lists.newArrayList();
|
||||||
|
|
||||||
|
createSort(myBuilder, outerQueryFrom, theParams.getSort(), orders, predicates);
|
||||||
|
if (orders.size() > 0) {
|
||||||
|
outerQuery.orderBy(orders);
|
||||||
|
}
|
||||||
|
|
||||||
|
Subquery<Long> subQ = outerQuery.subquery(Long.class);
|
||||||
|
Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class);
|
||||||
|
|
||||||
|
myResourceTableQuery = subQ;
|
||||||
|
myResourceTableRoot = subQfrom;
|
||||||
|
|
||||||
|
Expression<Long> selectExpr = subQfrom.get("myId").as(Long.class);
|
||||||
|
subQ.select(selectExpr);
|
||||||
|
|
||||||
|
predicates.add(0, myBuilder.in(outerQueryFrom.get("myId").as(Long.class)).value(subQ));
|
||||||
|
|
||||||
|
outerQuery.multiselect(outerQueryFrom.get("myId").as(Long.class));
|
||||||
|
outerQuery.where(predicates.toArray(new Predicate[0]));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
outerQuery = myBuilder.createQuery(Long.class);
|
||||||
|
myResourceTableQuery = outerQuery;
|
||||||
|
myResourceTableRoot = myResourceTableQuery.from(ResourceTable.class);
|
||||||
|
outerQuery.multiselect(myResourceTableRoot.get("myId").as(Long.class));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
myResourceTableQuery.distinct(true);
|
myResourceTableQuery.distinct(true);
|
||||||
myResourceTableRoot = myResourceTableQuery.from(ResourceTable.class);
|
|
||||||
myPredicates = new ArrayList<Predicate>();
|
myPredicates = new ArrayList<Predicate>();
|
||||||
if (theParams.getEverythingMode() == null) {
|
if (theParams.getEverythingMode() == null) {
|
||||||
myPredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), myResourceName));
|
myPredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), myResourceName));
|
||||||
|
@ -1509,7 +1537,9 @@ public class SearchBuilder {
|
||||||
Long pid = BaseHapiFhirDao.translateForcedIdToPid(myResourceName, idParm.getValue(), myForcedIdDao);
|
Long pid = BaseHapiFhirDao.translateForcedIdToPid(myResourceName, idParm.getValue(), myForcedIdDao);
|
||||||
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid));
|
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid));
|
||||||
} else {
|
} else {
|
||||||
myPredicates.add(myBuilder.equal(join.get("myTargetResourceType").as(String.class), myResourceName));
|
Predicate targetTypePredicate = myBuilder.equal(join.get("myTargetResourceType").as(String.class), myResourceName);
|
||||||
|
Predicate sourceTypePredicate = myBuilder.equal(myResourceTableRoot.get("myResourceType").as(String.class), myResourceName);
|
||||||
|
myPredicates.add(myBuilder.or(sourceTypePredicate, targetTypePredicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1539,14 +1569,19 @@ public class SearchBuilder {
|
||||||
|
|
||||||
myResourceTableQuery.where(myBuilder.and(SearchBuilder.toArray(myPredicates)));
|
myResourceTableQuery.where(myBuilder.and(SearchBuilder.toArray(myPredicates)));
|
||||||
|
|
||||||
myResourceTableQuery.multiselect(myResourceTableRoot.get("myId").as(Long.class));
|
/*
|
||||||
TypedQuery<Tuple> query = myEntityManager.createQuery(myResourceTableQuery);
|
* Now perform the search
|
||||||
|
*/
|
||||||
|
TypedQuery<Long> query = myEntityManager.createQuery(outerQuery);
|
||||||
query.setFirstResult(theFromIndex);
|
query.setFirstResult(theFromIndex);
|
||||||
query.setMaxResults(theToIndex - theFromIndex);
|
query.setMaxResults(theToIndex - theFromIndex);
|
||||||
|
|
||||||
List<Long> pids = new ArrayList<Long>();
|
List<Long> pids = new ArrayList<Long>();
|
||||||
for (Tuple next : query.getResultList()) {
|
|
||||||
pids.add(next.get(0, Long.class));
|
for (Long next : query.getResultList()) {
|
||||||
|
if (next != null) {
|
||||||
|
pids.add(next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pids;
|
return pids;
|
||||||
|
@ -1889,6 +1924,10 @@ public class SearchBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dupes will cause a crash later anyhow, but this is expensive so only do it
|
||||||
|
// when running asserts
|
||||||
|
assert new HashSet<Long>(theIncludePids).size() == theIncludePids.size() : "PID list contains duplicates: " + theIncludePids;
|
||||||
|
|
||||||
Map<Long, Integer> position = new HashMap<Long, Integer>();
|
Map<Long, Integer> position = new HashMap<Long, Integer>();
|
||||||
for (Long next : theIncludePids) {
|
for (Long next : theIncludePids) {
|
||||||
position.put(next, theResourceListToPopulate.size());
|
position.put(next, theResourceListToPopulate.size());
|
||||||
|
|
|
@ -77,11 +77,11 @@ public class SearchParamPresenceSvcImpl implements ISearchParamPresenceSvc {
|
||||||
entitiesToSave.add(present);
|
entitiesToSave.add(present);
|
||||||
}
|
}
|
||||||
|
|
||||||
mySearchParamPresentDao.deleteInBatch(entitiesToDelete);
|
|
||||||
mySearchParamPresentDao.save(entitiesToSave);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mySearchParamPresentDao.deleteInBatch(entitiesToDelete);
|
||||||
|
mySearchParamPresentDao.save(entitiesToSave);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||||
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||||
|
@ -190,7 +191,7 @@ public abstract class BaseJpaTest {
|
||||||
return bundleStr;
|
return bundleStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager) {
|
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager, ISearchParamPresenceSvc theSearchParamPresenceSvc) {
|
||||||
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
||||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
||||||
txTemplate.execute(new TransactionCallback<Void>() {
|
txTemplate.execute(new TransactionCallback<Void>() {
|
||||||
|
@ -255,6 +256,7 @@ public abstract class BaseJpaTest {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
theSearchParamPresenceSvc.flushCachesForUnitTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<String> toCodes(Set<TermConcept> theConcepts) {
|
public static Set<String> toCodes(Set<TermConcept> theConcepts) {
|
||||||
|
|
|
@ -26,12 +26,14 @@ import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.config.TestDstu1Config;
|
import ca.uhn.fhir.jpa.config.TestDstu1Config;
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.BundleEntry;
|
import ca.uhn.fhir.model.api.BundleEntry;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -61,10 +63,11 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
||||||
private static IFhirResourceDao<Patient> ourPatientDao;
|
private static IFhirResourceDao<Patient> ourPatientDao;
|
||||||
private static IFhirSystemDao<List<IResource>, MetaDt> ourSystemDao;
|
private static IFhirSystemDao<List<IResource>, MetaDt> ourSystemDao;
|
||||||
private static PlatformTransactionManager ourTxManager;
|
private static PlatformTransactionManager ourTxManager;
|
||||||
|
private static ISearchParamPresenceSvc ourSearchParamPresenceSvc;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
super.purgeDatabase(ourEntityManager, ourTxManager);
|
super.purgeDatabase(ourEntityManager, ourTxManager, ourSearchParamPresenceSvc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -493,6 +496,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
||||||
ourSystemDao = ourCtx.getBean("mySystemDaoDstu1", IFhirSystemDao.class);
|
ourSystemDao = ourCtx.getBean("mySystemDaoDstu1", IFhirSystemDao.class);
|
||||||
ourEntityManager = ourCtx.getBean(EntityManager.class);
|
ourEntityManager = ourCtx.getBean(EntityManager.class);
|
||||||
ourTxManager = ourCtx.getBean(PlatformTransactionManager.class);
|
ourTxManager = ourCtx.getBean(PlatformTransactionManager.class);
|
||||||
|
ourSearchParamPresenceSvc = ourCtx.getBean(ISearchParamPresenceSvc.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||||
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||||
|
@ -147,6 +148,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myValueSetDaoDstu2")
|
@Qualifier("myValueSetDaoDstu2")
|
||||||
protected IFhirResourceDaoValueSet<ValueSet, CodingDt, CodeableConceptDt> myValueSetDao;
|
protected IFhirResourceDaoValueSet<ValueSet, CodingDt, CodeableConceptDt> myValueSetDao;
|
||||||
|
@Autowired
|
||||||
|
protected ISearchParamPresenceSvc mySearchParamPresenceSvc;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void beforeCreateInterceptor() {
|
public void beforeCreateInterceptor() {
|
||||||
myInterceptor = mock(IServerInterceptor.class);
|
myInterceptor = mock(IServerInterceptor.class);
|
||||||
|
@ -167,7 +171,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
||||||
@Transactional()
|
@Transactional()
|
||||||
public void beforePurgeDatabase() {
|
public void beforePurgeDatabase() {
|
||||||
final EntityManager entityManager = this.myEntityManager;
|
final EntityManager entityManager = this.myEntityManager;
|
||||||
purgeDatabase(entityManager, myTxManager);
|
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -1307,15 +1307,15 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
SearchParameterMap params;
|
SearchParameterMap params;
|
||||||
|
|
||||||
|
params = new SearchParameterMap();
|
||||||
|
params.add(Patient.SP_ORGANIZATION, new ReferenceParam().setMissing(true));
|
||||||
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(pid1, pid3));
|
||||||
|
|
||||||
params = new SearchParameterMap();
|
params = new SearchParameterMap();
|
||||||
params.add(Patient.SP_NAME, new StringParam("FAMILY1"));
|
params.add(Patient.SP_NAME, new StringParam("FAMILY1"));
|
||||||
params.add(Patient.SP_ORGANIZATION, new ReferenceParam().setMissing(true));
|
params.add(Patient.SP_ORGANIZATION, new ReferenceParam().setMissing(true));
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(pid1));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(pid1));
|
||||||
|
|
||||||
params = new SearchParameterMap();
|
|
||||||
params.add(Patient.SP_ORGANIZATION, new ReferenceParam().setMissing(true));
|
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(pid1, pid3));
|
|
||||||
|
|
||||||
params = new SearchParameterMap();
|
params = new SearchParameterMap();
|
||||||
params.add(Patient.SP_NAME, new StringParam("FAMILY9999"));
|
params.add(Patient.SP_NAME, new StringParam("FAMILY9999"));
|
||||||
params.add(Patient.SP_ORGANIZATION, new ReferenceParam().setMissing(true));
|
params.add(Patient.SP_ORGANIZATION, new ReferenceParam().setMissing(true));
|
||||||
|
|
|
@ -224,8 +224,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
@Transactional()
|
@Transactional()
|
||||||
public void beforePurgeDatabase() {
|
public void beforePurgeDatabase() {
|
||||||
final EntityManager entityManager = this.myEntityManager;
|
final EntityManager entityManager = this.myEntityManager;
|
||||||
purgeDatabase(entityManager, myTxManager);
|
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc);
|
||||||
mySearchParamPresenceSvc.flushCachesForUnitTest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEverythingTimings() throws Exception {
|
public void testEverythingTimings() throws Exception {
|
||||||
String methodName = "testEverythingIncludesBackReferences";
|
String methodName = "testEverythingTimings";
|
||||||
|
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName(methodName);
|
org.setName(methodName);
|
||||||
|
@ -124,7 +124,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pat2 = new Patient();
|
Patient pat2 = new Patient();
|
||||||
pat2.addAddress().addLine(methodName);
|
pat2.addAddress().addLine(methodName + "2");
|
||||||
pat2.getManagingOrganization().setReferenceElement(orgId);
|
pat2.getManagingOrganization().setReferenceElement(orgId);
|
||||||
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
@ -2862,6 +2862,125 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSortOnPopulatedField() throws Exception {
|
||||||
|
Patient pBA = new Patient();
|
||||||
|
pBA.setId("BA");
|
||||||
|
pBA.setActive(true);
|
||||||
|
pBA.setGender(AdministrativeGender.MALE);
|
||||||
|
pBA.addName().setFamily("B").addGiven("A");
|
||||||
|
myPatientDao.update(pBA);
|
||||||
|
|
||||||
|
Patient pBB = new Patient();
|
||||||
|
pBB.setId("BB");
|
||||||
|
pBB.setActive(true);
|
||||||
|
pBB.setGender(AdministrativeGender.MALE);
|
||||||
|
pBB.addName().setFamily("B").addGiven("B");
|
||||||
|
pBB.addName().setFamily("Z").addGiven("Z");
|
||||||
|
myPatientDao.update(pBB);
|
||||||
|
|
||||||
|
Patient pAB = new Patient();
|
||||||
|
pAB.setId("AB");
|
||||||
|
pAB.setActive(true);
|
||||||
|
pAB.setGender(AdministrativeGender.MALE);
|
||||||
|
pAB.addName().setFamily("A").addGiven("B");
|
||||||
|
myPatientDao.update(pAB);
|
||||||
|
|
||||||
|
Patient pAA = new Patient();
|
||||||
|
pAA.setId("AA");
|
||||||
|
pAA.setActive(true);
|
||||||
|
pAA.setGender(AdministrativeGender.MALE);
|
||||||
|
pAA.addName().setFamily("A").addGiven("A");
|
||||||
|
myPatientDao.update(pAA);
|
||||||
|
|
||||||
|
SearchParameterMap map;
|
||||||
|
List<String> ids;
|
||||||
|
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.setSort(new SortSpec("family", SortOrderEnum.ASC).setChain(new SortSpec("given", SortOrderEnum.ASC)));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
assertThat(ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB"));
|
||||||
|
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.setSort(new SortSpec("gender").setChain(new SortSpec("family", SortOrderEnum.ASC).setChain(new SortSpec("given", SortOrderEnum.ASC))));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
ourLog.info("IDS: {}", ids);
|
||||||
|
assertThat(ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB"));
|
||||||
|
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.add(Patient.SP_ACTIVE, new TokenParam(null, "true"));
|
||||||
|
map.setSort(new SortSpec("family", SortOrderEnum.ASC).setChain(new SortSpec("given", SortOrderEnum.ASC)));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
assertThat(ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSort() throws Exception {
|
||||||
|
Patient pBA = new Patient();
|
||||||
|
pBA.setId("BA");
|
||||||
|
pBA.setActive(true);
|
||||||
|
pBA.setGender(AdministrativeGender.MALE);
|
||||||
|
pBA.addName().setFamily("B").addGiven("A");
|
||||||
|
myPatientDao.update(pBA);
|
||||||
|
|
||||||
|
Patient pBB = new Patient();
|
||||||
|
pBB.setId("BB");
|
||||||
|
pBB.setActive(true);
|
||||||
|
pBB.setGender(AdministrativeGender.MALE);
|
||||||
|
pBB.addName().setFamily("B").addGiven("B");
|
||||||
|
myPatientDao.update(pBB);
|
||||||
|
|
||||||
|
Patient pAB = new Patient();
|
||||||
|
pAB.setId("AB");
|
||||||
|
pAB.setActive(true);
|
||||||
|
pAB.setGender(AdministrativeGender.MALE);
|
||||||
|
pAB.addName().setFamily("A").addGiven("B");
|
||||||
|
myPatientDao.update(pAB);
|
||||||
|
|
||||||
|
Patient pAA = new Patient();
|
||||||
|
pAA.setId("AA");
|
||||||
|
pAA.setActive(true);
|
||||||
|
pAA.setGender(AdministrativeGender.MALE);
|
||||||
|
pAA.addName().setFamily("A").addGiven("A");
|
||||||
|
myPatientDao.update(pAA);
|
||||||
|
|
||||||
|
Patient pCA = new Patient();
|
||||||
|
pCA.setId("CA");
|
||||||
|
pCA.setActive(false);
|
||||||
|
pCA.addName().setFamily("C").addGiven("A");
|
||||||
|
pCA.addName().setFamily("Z").addGiven("A");
|
||||||
|
myPatientDao.update(pCA);
|
||||||
|
|
||||||
|
SearchParameterMap map;
|
||||||
|
List<String> ids;
|
||||||
|
|
||||||
|
// Sort across all resources
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.setSort(new SortSpec("family", SortOrderEnum.ASC).setChain(new SortSpec("given", SortOrderEnum.ASC)));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
assertThat(ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB", "Patient/CA"));
|
||||||
|
|
||||||
|
// A sort on a field that isn't populated in all cases
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.setSort(new SortSpec("gender"));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
ourLog.info("IDS: {}", ids);
|
||||||
|
assertThat(ids, containsInAnyOrder("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB", "Patient/CA"));
|
||||||
|
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.setSort(new SortSpec("gender").setChain(new SortSpec("family", SortOrderEnum.ASC).setChain(new SortSpec("given", SortOrderEnum.ASC))));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
ourLog.info("IDS: {}", ids);
|
||||||
|
assertThat(ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB", "Patient/CA"));
|
||||||
|
|
||||||
|
// Sort
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.add(Patient.SP_ACTIVE, new TokenParam(null, "true"));
|
||||||
|
map.setSort(new SortSpec("family", SortOrderEnum.ASC).setChain(new SortSpec("given", SortOrderEnum.ASC)));
|
||||||
|
ids = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
|
||||||
|
assertThat(ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithUriParamAbove() throws Exception {
|
public void testSearchWithUriParamAbove() throws Exception {
|
||||||
ValueSet vs1 = new ValueSet();
|
ValueSet vs1 = new ValueSet();
|
||||||
|
|
|
@ -23,6 +23,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.config.TestDstu3WithoutLuceneConfig;
|
import ca.uhn.fhir.jpa.config.TestDstu3WithoutLuceneConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.*;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
|
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
|
||||||
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.rest.param.StringParam;
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
@ -139,6 +140,8 @@ public class FhirResourceDaoDstu3SearchWithLuceneDisabledTest extends BaseJpaTes
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected PlatformTransactionManager myTxManager;
|
protected PlatformTransactionManager myTxManager;
|
||||||
|
@Autowired
|
||||||
|
protected ISearchParamPresenceSvc mySearchParamPresenceSvc;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myJpaValidationSupportChainDstu3")
|
@Qualifier("myJpaValidationSupportChainDstu3")
|
||||||
|
@ -148,7 +151,7 @@ public class FhirResourceDaoDstu3SearchWithLuceneDisabledTest extends BaseJpaTes
|
||||||
@Transactional()
|
@Transactional()
|
||||||
public void beforePurgeDatabase() {
|
public void beforePurgeDatabase() {
|
||||||
final EntityManager entityManager = this.myEntityManager;
|
final EntityManager entityManager = this.myEntityManager;
|
||||||
purgeDatabase(entityManager, myTxManager);
|
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -39,6 +39,7 @@ import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||||
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -87,6 +88,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
private static CloseableHttpClient ourHttpClient;
|
private static CloseableHttpClient ourHttpClient;
|
||||||
private static EntityManager ourEntityManager;
|
private static EntityManager ourEntityManager;
|
||||||
private static PlatformTransactionManager ourTxManager;
|
private static PlatformTransactionManager ourTxManager;
|
||||||
|
private static ISearchParamPresenceSvc ourSearchParamPresenceSvc;
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() throws Exception {
|
public static void afterClassClearContext() throws Exception {
|
||||||
|
@ -551,6 +553,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
ourOrganizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDaoDstu1", IFhirResourceDao.class);
|
ourOrganizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDaoDstu1", IFhirResourceDao.class);
|
||||||
ourEntityManager = ourAppCtx.getBean(EntityManager.class);
|
ourEntityManager = ourAppCtx.getBean(EntityManager.class);
|
||||||
ourTxManager = ourAppCtx.getBean(PlatformTransactionManager.class);
|
ourTxManager = ourAppCtx.getBean(PlatformTransactionManager.class);
|
||||||
|
ourSearchParamPresenceSvc = ourAppCtx.getBean(ISearchParamPresenceSvc.class);
|
||||||
|
|
||||||
List<IResourceProvider> rpsDev = (List<IResourceProvider>) ourAppCtx.getBean("myResourceProvidersDstu1", List.class);
|
List<IResourceProvider> rpsDev = (List<IResourceProvider>) ourAppCtx.getBean("myResourceProvidersDstu1", List.class);
|
||||||
restServer.setResourceProviders(rpsDev);
|
restServer.setResourceProviders(rpsDev);
|
||||||
|
@ -593,7 +596,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
super.purgeDatabase(ourEntityManager, ourTxManager);
|
super.purgeDatabase(ourEntityManager, ourTxManager, ourSearchParamPresenceSvc);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2169,7 +2169,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSaveAndRetrieveExistingNarrativeJson() {
|
public void testSaveAndRetrieveExistingNarrativeJson() {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
@ -3046,41 +3045,37 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
p.addName().addGiven("Sarah").setFamily("Graham");
|
p.addName().addGiven("Sarah").setFamily("Graham");
|
||||||
ourClient.create().resource(p).execute();
|
ourClient.create().resource(p).execute();
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
Bundle resp = ourClient
|
Bundle resp = ourClient
|
||||||
.search()
|
.search()
|
||||||
.forResource(Patient.class)
|
.forResource(Patient.class)
|
||||||
.where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", methodName))
|
.where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", methodName))
|
||||||
.sort().ascending(Patient.FAMILY)
|
.sort().ascending(Patient.FAMILY)
|
||||||
.sort().ascending(Patient.GIVEN)
|
.sort().ascending(Patient.GIVEN)
|
||||||
.count(100)
|
.count(100)
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
List<String> names = toNameList(resp);
|
List<String> names = toNameList(resp);
|
||||||
|
|
||||||
ourLog.info(StringUtils.join(names, '\n'));
|
ourLog.info(StringUtils.join(names, '\n'));
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
assertThat(names, contains( // this matches in order only
|
assertThat(names, contains( // this matches in order only
|
||||||
"Daniel Adams",
|
"Daniel Adams",
|
||||||
"Aaron Alexis",
|
"Aaron Alexis",
|
||||||
"Carol Allen",
|
"Carol Allen",
|
||||||
"Ruth Black",
|
"Ruth Black",
|
||||||
"Brian Brooks",
|
"Brian Brooks",
|
||||||
"Amy Clark",
|
"Amy Clark",
|
||||||
"Susan Clark",
|
"Susan Clark",
|
||||||
"Anthony Coleman",
|
"Anthony Coleman",
|
||||||
"Lisa Coleman",
|
"Lisa Coleman",
|
||||||
"Steven Coleman",
|
"Steven Coleman",
|
||||||
"Ruth Cook",
|
"Ruth Cook",
|
||||||
"Betty Davis",
|
"Betty Davis",
|
||||||
"Joshua Diaz",
|
"Joshua Diaz",
|
||||||
"Brian Gracia",
|
"Brian Gracia",
|
||||||
"Sarah Graham",
|
"Sarah Graham",
|
||||||
"Stephan Graham"));
|
"Stephan Graham"));
|
||||||
//@formatter:om
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3118,7 +3113,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
CloseableHttpResponse resp = ourHttpClient.execute(post);
|
CloseableHttpResponse resp = ourHttpClient.execute(post);
|
||||||
try {
|
try {
|
||||||
assertEquals(200, resp.getStatusLine().getStatusCode());
|
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||||
String output= IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8);
|
String output = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
} finally {
|
} finally {
|
||||||
resp.close();
|
resp.close();
|
||||||
|
@ -3157,7 +3152,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
ourLog.info(responseString);
|
ourLog.info(responseString);
|
||||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||||
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, responseString);
|
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, responseString);
|
||||||
assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Can not update resource, request URL must contain an ID element for update (PUT) operation (it must be of the form [base]/[resource type]/[id])"));
|
assertThat(oo.getIssue().get(0).getDiagnostics(),
|
||||||
|
containsString("Can not update resource, request URL must contain an ID element for update (PUT) operation (it must be of the form [base]/[resource type]/[id])"));
|
||||||
} finally {
|
} finally {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
@ -3234,13 +3230,16 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
try {
|
try {
|
||||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||||
OperationOutcome oo = myFhirCtx.newJsonParser().parseResource(OperationOutcome.class, new InputStreamReader(response.getEntity().getContent()));
|
OperationOutcome oo = myFhirCtx.newJsonParser().parseResource(OperationOutcome.class, new InputStreamReader(response.getEntity().getContent()));
|
||||||
assertEquals("Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"FOO\" does not match URL ID of \"" + p1id.getIdPart() + "\"", oo.getIssue().get(0).getDiagnostics());
|
assertEquals(
|
||||||
|
"Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"FOO\" does not match URL ID of \""
|
||||||
|
+ p1id.getIdPart() + "\"",
|
||||||
|
oo.getIssue().get(0).getDiagnostics());
|
||||||
} finally {
|
} finally {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to update with the no ID in the resource body
|
// Try to update with the no ID in the resource body
|
||||||
p1.setId((String)null);
|
p1.setId((String) null);
|
||||||
|
|
||||||
encoded = myFhirCtx.newJsonParser().encodeResourceToString(p1);
|
encoded = myFhirCtx.newJsonParser().encodeResourceToString(p1);
|
||||||
put = new HttpPut(ourServerBase + "/Patient/" + p1id.getIdPart());
|
put = new HttpPut(ourServerBase + "/Patient/" + p1id.getIdPart());
|
||||||
|
@ -3270,7 +3269,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateRejectsInvalidTypes() throws InterruptedException {
|
public void testUpdateRejectsInvalidTypes() throws InterruptedException {
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</logger>
|
</logger>
|
||||||
<!-- Set to 'trace' to enable SQL Value logging -->
|
<!-- Set to 'trace' to enable SQL Value logging -->
|
||||||
<logger name="org.hibernate.type" additivity="false" level="trace">
|
<logger name="org.hibernate.type" additivity="false" level="info">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue