Work on #164 - Correct performance issue
This commit is contained in:
parent
fbcd15a16d
commit
da3ec668de
|
@ -368,18 +368,6 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
private Set<Long> addPredicateParamMissing(Set<Long> thePids, String joinName, String theParamName, Class<? extends BaseResourceIndexedSearchParam> theParamTable) {
|
||||
String resourceType = getContext().getResourceDefinition(getResourceType()).getName();
|
||||
|
||||
{ // TODO: rmeove this!
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Object> cq = builder.createQuery();
|
||||
Root<? extends BaseResourceIndexedSearchParam> subQfrom = cq.from(theParamTable);
|
||||
cq.select(subQfrom);
|
||||
Predicate subQname = builder.equal(subQfrom.get("myParamName"), theParamName);
|
||||
Predicate subQtype = builder.equal(subQfrom.get("myResourceType"), resourceType);
|
||||
cq.where(builder.and(subQtype, subQname));
|
||||
List<Object> results = myEntityManager.createQuery(cq).getResultList();
|
||||
ourLog.info("All results: {}", results);
|
||||
}
|
||||
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
|
@ -424,12 +412,13 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
|||
subQ.where(createResourceLinkPathPredicate(theParamName, builder, subQfrom));
|
||||
|
||||
Predicate joinPredicate = builder.not(builder.in(from.get("myId")).value(subQ));
|
||||
|
||||
Predicate typePredicate = builder.equal(from.get("myResourceType"), myResourceName);
|
||||
|
||||
if (thePids.size() > 0) {
|
||||
Predicate inPids = (from.get("myId").in(thePids));
|
||||
cq.where(builder.and(inPids, joinPredicate));
|
||||
cq.where(builder.and(inPids, typePredicate, joinPredicate));
|
||||
} else {
|
||||
cq.where(joinPredicate);
|
||||
cq.where(builder.and(typePredicate, joinPredicate));
|
||||
}
|
||||
|
||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||
|
|
|
@ -1676,7 +1676,7 @@ public class FhirResourceDaoDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithMissingReference() {
|
||||
IdDt orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||
IdDt orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
|
||||
IdDt notMissing;
|
||||
IdDt missing;
|
||||
{
|
||||
|
@ -1710,6 +1710,7 @@ public class FhirResourceDaoDstu2Test {
|
|||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||
assertThat(patients, containsInRelativeOrder(missing));
|
||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||
assertThat(patients, not(containsInRelativeOrder(orgId)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,70 +53,31 @@ public class ResourceProviderDstu1Test {
|
|||
|
||||
private static ClassPathXmlApplicationContext ourAppCtx;
|
||||
private static IGenericClient ourClient;
|
||||
private static DaoConfig ourDaoConfig;
|
||||
private static FhirContext ourFhirCtx;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu1Test.class);
|
||||
private static IFhirResourceDao<Organization> ourOrganizationDao;
|
||||
// private static IFhirResourceDao<Observation> ourObservationDao;
|
||||
// private static IFhirResourceDao<Patient> ourPatientDao;
|
||||
// private static IFhirResourceDao<Questionnaire> ourQuestionnaireDao;
|
||||
private static Server ourServer;
|
||||
private static IFhirResourceDao<Organization> ourOrganizationDao;
|
||||
private static DaoConfig ourDaoConfig;
|
||||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
/**
|
||||
* Test for issue #60
|
||||
*/
|
||||
@Test
|
||||
public void testStoreUtf8Characters() throws Exception {
|
||||
Organization org = new Organization();
|
||||
org.setName("測試醫院");
|
||||
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||
|
||||
// Read back directly from the DAO
|
||||
{
|
||||
Organization returned = ourOrganizationDao.read(orgId);
|
||||
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
||||
ourLog.info(val);
|
||||
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
|
||||
}
|
||||
// Read back through the HTTP API
|
||||
{
|
||||
Organization returned = ourClient.read(Organization.class, orgId);
|
||||
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
||||
ourLog.info(val);
|
||||
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
|
||||
private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new StringClientParam(theParamName).matches().value(theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
ourLog.info("Deleting resource: {}", next.getId());
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithInclude() throws Exception {
|
||||
Organization org = new Organization();
|
||||
org.addIdentifier().setSystem("urn:system").setValue( "testSearchWithInclude01");
|
||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||
|
||||
Patient pat = new Patient();
|
||||
pat.addIdentifier().setSystem("urn:system").setValue("testSearchWithInclude02");
|
||||
pat.getManagingOrganization().setReference(orgId);
|
||||
ourClient.create().resource(pat).prettyPrint().encodedXml().execute().getId();
|
||||
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("urn:system","testSearchWithInclude02"))
|
||||
.include(Patient.INCLUDE_MANAGINGORGANIZATION)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals(2, found.size());
|
||||
assertEquals(Patient.class, found.getEntries().get(0).getResource().getClass());
|
||||
assertEquals(null, found.getEntries().get(0).getSearchMode().getValueAsEnum());
|
||||
assertEquals(null, found.getEntries().get(0).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE));
|
||||
assertEquals(Organization.class, found.getEntries().get(1).getResource().getClass());
|
||||
assertEquals(null, found.getEntries().get(1).getSearchMode().getValueAsEnum());
|
||||
assertEquals(null, found.getEntries().get(1).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE));
|
||||
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
ourLog.info("Deleting resource: {}", next.getId());
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,96 +104,6 @@ public class ResourceProviderDstu1Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testImagingStudyResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(ImagingStudy.class).execute().size();
|
||||
|
||||
String resBody = IOUtils.toString(ResourceProviderDstu1Test.class.getResource("/imagingstudy.json"));
|
||||
client.create().resource(resBody).execute();
|
||||
|
||||
int newSize = client.search().forResource(ImagingStudy.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testDocumentManifestResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(DocumentManifest.class).execute().size();
|
||||
|
||||
String resBody = IOUtils.toString(ResourceProviderDstu1Test.class.getResource("/documentmanifest.json"));
|
||||
client.create().resource(resBody).execute();
|
||||
|
||||
int newSize = client.search().forResource(DocumentManifest.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testDocumentReferenceResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(DocumentReference.class).execute().size();
|
||||
|
||||
String resBody = IOUtils.toString(ResourceProviderDstu1Test.class.getResource("/documentreference.json"));
|
||||
client.create().resource(resBody).execute();
|
||||
|
||||
int newSize = client.search().forResource(DocumentReference.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testDiagnosticOrderResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(DiagnosticOrder.class).execute().size();
|
||||
|
||||
DiagnosticOrder res = new DiagnosticOrder();
|
||||
res.addIdentifier().setSystem("urn:foo").setValue( "123");
|
||||
|
||||
client.create().resource(res).execute();
|
||||
|
||||
int newSize = client.search().forResource(DiagnosticOrder.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new StringClientParam(theParamName).matches().value(theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
ourLog.info("Deleting resource: {}", next.getId());
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
ourLog.info("Deleting resource: {}", next.getId());
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithClientSuppliedId() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testCreateWithId01");
|
||||
|
@ -302,6 +173,80 @@ public class ResourceProviderDstu1Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testDiagnosticOrderResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(DiagnosticOrder.class).execute().size();
|
||||
|
||||
DiagnosticOrder res = new DiagnosticOrder();
|
||||
res.addIdentifier().setSystem("urn:foo").setValue( "123");
|
||||
|
||||
client.create().resource(res).execute();
|
||||
|
||||
int newSize = client.search().forResource(DiagnosticOrder.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testDocumentManifestResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(DocumentManifest.class).execute().size();
|
||||
|
||||
String resBody = IOUtils.toString(ResourceProviderDstu1Test.class.getResource("/documentmanifest.json"));
|
||||
client.create().resource(resBody).execute();
|
||||
|
||||
int newSize = client.search().forResource(DocumentManifest.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testDocumentReferenceResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(DocumentReference.class).execute().size();
|
||||
|
||||
String resBody = IOUtils.toString(ResourceProviderDstu1Test.class.getResource("/documentreference.json"));
|
||||
client.create().resource(resBody).execute();
|
||||
|
||||
int newSize = client.search().forResource(DocumentReference.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
@Test
|
||||
public void testImagingStudyResources() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
||||
int initialSize = client.search().forResource(ImagingStudy.class).execute().size();
|
||||
|
||||
String resBody = IOUtils.toString(ResourceProviderDstu1Test.class.getResource("/imagingstudy.json"));
|
||||
client.create().resource(resBody).execute();
|
||||
|
||||
int newSize = client.search().forResource(ImagingStudy.class).execute().size();
|
||||
|
||||
assertEquals(1, newSize - initialSize);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAndRetrieveExistingNarrative() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01");
|
||||
|
@ -418,6 +363,61 @@ public class ResourceProviderDstu1Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithInclude() throws Exception {
|
||||
Organization org = new Organization();
|
||||
org.addIdentifier().setSystem("urn:system").setValue( "testSearchWithInclude01");
|
||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||
|
||||
Patient pat = new Patient();
|
||||
pat.addIdentifier().setSystem("urn:system").setValue("testSearchWithInclude02");
|
||||
pat.getManagingOrganization().setReference(orgId);
|
||||
ourClient.create().resource(pat).prettyPrint().encodedXml().execute().getId();
|
||||
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("urn:system","testSearchWithInclude02"))
|
||||
.include(Patient.INCLUDE_MANAGINGORGANIZATION)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals(2, found.size());
|
||||
assertEquals(Patient.class, found.getEntries().get(0).getResource().getClass());
|
||||
assertEquals(null, found.getEntries().get(0).getSearchMode().getValueAsEnum());
|
||||
assertEquals(null, found.getEntries().get(0).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE));
|
||||
assertEquals(Organization.class, found.getEntries().get(1).getResource().getClass());
|
||||
assertEquals(null, found.getEntries().get(1).getSearchMode().getValueAsEnum());
|
||||
assertEquals(null, found.getEntries().get(1).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for issue #60
|
||||
*/
|
||||
@Test
|
||||
public void testStoreUtf8Characters() throws Exception {
|
||||
Organization org = new Organization();
|
||||
org.setName("測試醫院");
|
||||
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||
|
||||
// Read back directly from the DAO
|
||||
{
|
||||
Organization returned = ourOrganizationDao.read(orgId);
|
||||
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
||||
ourLog.info(val);
|
||||
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
|
||||
}
|
||||
// Read back through the HTTP API
|
||||
{
|
||||
Organization returned = ourClient.read(Organization.class, orgId);
|
||||
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
||||
ourLog.info(val);
|
||||
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryToCreateResourceWithReferenceThatDoesntExist() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01");
|
||||
|
|
|
@ -398,6 +398,14 @@ public class ResourceProviderDstu2Test {
|
|||
ourLog.info("Starting testSearchWithMissing");
|
||||
String methodName = "testSearchWithMissing";
|
||||
|
||||
List<IResource> resources = new ArrayList<IResource>();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Organization org = new Organization();
|
||||
org.setName(methodName + "_0" + i);
|
||||
resources.add(org);
|
||||
}
|
||||
ourClient.transaction().withResources(resources).prettyPrint().encodedXml().execute();
|
||||
|
||||
Organization org = new Organization();
|
||||
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
|
||||
org.setName(methodName + "name");
|
||||
|
@ -413,45 +421,31 @@ public class ResourceProviderDstu2Test {
|
|||
.search()
|
||||
.forResource(Organization.class)
|
||||
.where(Organization.NAME.isMissing(false))
|
||||
.limitTo(100)
|
||||
.prettyPrint()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
List<IdDt> list = toIdListUnqualifiedVersionless(found);
|
||||
ourLog.info(methodName + ": " + list.toString());
|
||||
assertThat(list, containsInRelativeOrder(orgNotMissing));
|
||||
assertThat("Wanted " + orgNotMissing + " but got: " + list, list, containsInRelativeOrder(orgNotMissing));
|
||||
assertThat(list, not(containsInRelativeOrder(orgMissing)));
|
||||
}
|
||||
|
||||
/*
|
||||
* The next search seems to not always work on the first try. I've checked the SQL that gets generated by
|
||||
* hibernate and it appears to be correct, and I've verified that everything that's in the database
|
||||
* is good too. I'm surmising that some weird interplat between the way Derby flushes to disk and the
|
||||
* way the nested query that gets used works is causing a timing issue. Bottom line, this seems to
|
||||
* succeed after a few tries....
|
||||
*/
|
||||
for (int i = 0;i < 5; i++)
|
||||
{
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Organization.class)
|
||||
.where(Organization.NAME.isMissing(true))
|
||||
.limitTo(100)
|
||||
.prettyPrint()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
List<IdDt> list = toIdListUnqualifiedVersionless(found);
|
||||
if (!list.contains(orgMissing)) {
|
||||
if (i < 5) {
|
||||
Thread.sleep(1000);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing);
|
||||
assertThat(list, not(containsInRelativeOrder(orgNotMissing)));
|
||||
assertThat("Wanted " + orgMissing + " but found: " + list, list, containsInRelativeOrder(orgMissing));
|
||||
}
|
||||
}
|
||||
|
||||
private List<IdDt> toIdListUnqualifiedVersionless(Bundle found) {
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
had tags but no other meta elements. Thanks to Bill de Beaubien and
|
||||
Claude Nanjo for finding this.
|
||||
</action>
|
||||
<action type="fix" issue="164">
|
||||
Correct performance issue with :missing=true search requests where the parameter is a resource link. Thanks to wanghaisheng for all his help in testing this.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.0" date="2015-May-8">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue