Add tests

This commit is contained in:
James Agnew 2017-06-29 21:34:56 -04:00
parent 10ff2dd16c
commit 674424a30b
6 changed files with 356 additions and 248 deletions

View File

@ -32,6 +32,7 @@ import ca.uhn.fhir.model.api.IQueryParameterType;
public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQueryParameterType { public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQueryParameterType {
private static final long serialVersionUID = 1L;
private BigDecimal myQuantity; private BigDecimal myQuantity;
/** /**
@ -41,6 +42,16 @@ public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQu
super(); super();
} }
/**
* Constructor
*
* @param theValue
* A value, e.g. "10"
*/
public NumberParam(int theValue) {
setValue(new BigDecimal(theValue));
}
/** /**
* Constructor * Constructor
* *
@ -79,6 +90,15 @@ public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQu
} }
public BigDecimal getValue() {
return myQuantity;
}
public NumberParam setValue(BigDecimal theValue) {
myQuantity = theValue;
return this;
}
@Override @Override
public String toString() { public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SIMPLE_STYLE); ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SIMPLE_STYLE);
@ -87,13 +107,4 @@ public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQu
return b.build(); return b.build();
} }
public BigDecimal getValue() {
return myQuantity;
}
public NumberParam setValue(BigDecimal theValue) {
myQuantity = theValue;
return this;
}
} }

View File

@ -2099,8 +2099,6 @@ public class SearchBuilder implements ISearchBuilder {
ScrollableResults scroll = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY); ScrollableResults scroll = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
myResultsIterator = new ScrollableResultsIterator(scroll); myResultsIterator = new ScrollableResultsIterator(scroll);
// myResultsIterator = query.getResultList().iterator();
// If the query resulted in extra results being requested // If the query resulted in extra results being requested
if (myAlsoIncludePids != null) { if (myAlsoIncludePids != null) {
myPreResultsIterator = myAlsoIncludePids.iterator(); myPreResultsIterator = myAlsoIncludePids.iterator();

View File

@ -19,24 +19,9 @@ package ca.uhn.fhir.jpa.search;
* limitations under the License. * limitations under the License.
* #L% * #L%
*/ */
import java.util.*;
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType; import javax.transaction.Transactional.TxType;
@ -47,34 +32,18 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.*;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory; import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.*;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.*;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.dao.IDao; import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.dao.data.ISearchIncludeDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchInclude;
import ca.uhn.fhir.jpa.entity.SearchResult;
import ca.uhn.fhir.jpa.entity.SearchStatusEnum;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.util.StopWatch; import ca.uhn.fhir.jpa.util.StopWatch;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.method.PageMethodBinding; import ca.uhn.fhir.rest.method.PageMethodBinding;
@ -83,7 +52,7 @@ import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.server.exceptions.*;
public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
static final int DEFAULT_SYNC_SIZE = 250; public static final int DEFAULT_SYNC_SIZE = 250;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchCoordinatorSvcImpl.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchCoordinatorSvcImpl.class);
@ -360,7 +329,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
} }
@VisibleForTesting @VisibleForTesting
void setLoadingThrottleForUnitTests(Integer theLoadingThrottleForUnitTests) { public void setLoadingThrottleForUnitTests(Integer theLoadingThrottleForUnitTests) {
myLoadingThrottleForUnitTests = theLoadingThrottleForUnitTests; myLoadingThrottleForUnitTests = theLoadingThrottleForUnitTests;
} }
@ -369,7 +338,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
myMaxMillisToWaitForRemoteResults = theMaxMillisToWaitForRemoteResults; myMaxMillisToWaitForRemoteResults = theMaxMillisToWaitForRemoteResults;
} }
void setNeverUseLocalSearchForUnitTests(boolean theNeverUseLocalSearchForUnitTests) { @VisibleForTesting
public void setNeverUseLocalSearchForUnitTests(boolean theNeverUseLocalSearchForUnitTests) {
myNeverUseLocalSearchForUnitTests = theNeverUseLocalSearchForUnitTests; myNeverUseLocalSearchForUnitTests = theNeverUseLocalSearchForUnitTests;
} }
@ -389,7 +359,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
} }
@VisibleForTesting @VisibleForTesting
void setSyncSizeForUnitTests(int theSyncSize) { public void setSyncSizeForUnitTests(int theSyncSize) {
mySyncSize = theSyncSize; mySyncSize = theSyncSize;
} }

View File

@ -5,6 +5,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsInRelativeOrder; import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
@ -47,11 +48,12 @@ import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass; import org.junit.*;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.test.util.AopTestUtils;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.api.*;
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;
@ -85,10 +87,7 @@ import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SummaryEnum; import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
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;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
@ -100,10 +99,27 @@ import ca.uhn.fhir.util.UrlUtil;
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test { public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw;
@Override
@After
public void after() throws Exception {
super.after();
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(null);
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(SearchCoordinatorSvcImpl.DEFAULT_SYNC_SIZE);
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(false);
}
@Before @Before
public void beforeDisableResultReuse() { public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null); myDaoConfig.setReuseCachedSearchResultsForMillis(null);
mySearchCoordinatorSvcRaw = AopTestUtils.getTargetObject(mySearchCoordinatorSvc);
} }
@AfterClass @AfterClass
@ -118,6 +134,58 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setAllowMultipleDelete(true);
} }
@Test
public void testPagingOverEverythingSet() throws InterruptedException {
Patient p = new Patient();
p.setActive(true);
String pid = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
for (int i = 0; i < 20; i++) {
Observation o = new Observation();
o.getSubject().setReference(pid);
o.addIdentifier().setSystem("foo").setValue(Integer.toString(i));
myObservationDao.create(o);
}
mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(50);
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(10);
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(true);
ca.uhn.fhir.model.dstu2.resource.Bundle response = ourClient
.operation()
.onInstance(new IdDt(pid))
.named("everything")
.withSearchParameter(Parameters.class, "_count", new NumberParam(10))
.returnResourceType(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.useHttpGet()
.execute();
assertEquals(10, response.getEntry().size());
assertEquals(null, response.getTotalElement().getValueAsString());
assertThat(response.getLink("next").getUrl(), not(emptyString()));
// Load page 2
String nextUrl = response.getLink("next").getUrl();
response = ourClient.fetchResourceFromUrl(ca.uhn.fhir.model.dstu2.resource.Bundle.class, nextUrl);
assertEquals(10, response.getEntry().size());
assertThat(response.getLink("next").getUrl(), not(emptyString()));
// Load page 3
Thread.sleep(2000);
nextUrl = response.getLink("next").getUrl();
response = ourClient.fetchResourceFromUrl(ca.uhn.fhir.model.dstu2.resource.Bundle.class, nextUrl);
assertEquals(1, response.getEntry().size());
assertEquals(21, response.getTotal().intValue());
assertEquals(null, response.getLink("next"));
}
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException { private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false"); HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
CloseableHttpResponse resp = ourHttpClient.execute(get); CloseableHttpResponse resp = ourHttpClient.execute(get);

View File

@ -6,6 +6,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsInRelativeOrder; import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasItems;
@ -50,13 +51,16 @@ import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
import org.hl7.fhir.instance.model.Encounter.EncounterState; import org.hl7.fhir.instance.model.Encounter.EncounterState;
import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.instance.model.api.*;
import org.junit.*; import org.junit.*;
import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.SearchBuilder;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.model.primitive.UriDt;
@ -76,11 +80,7 @@ import ca.uhn.fhir.util.UrlUtil;
public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu3Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu3Test.class);
private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw;
@Before
public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
}
@Override @Override
@After @After
@ -90,6 +90,11 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete()); myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences()); myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis()); myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(null);
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(SearchCoordinatorSvcImpl.DEFAULT_SYNC_SIZE);
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(false);
} }
@Override @Override
@ -100,95 +105,10 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setAllowMultipleDelete(true);
} }
@Test @Before
public void testSearchWithEmptyParameter() throws Exception { public void beforeDisableResultReuse() {
Observation obs= new Observation(); myDaoConfig.setReuseCachedSearchResultsForMillis(null);
obs.setStatus(ObservationStatus.FINAL); mySearchCoordinatorSvcRaw = AopTestUtils.getTargetObject(mySearchCoordinatorSvc);
obs.getCode().addCoding().setSystem("foo").setCode("bar");
ourClient.create().resource(obs).execute();
testSearchWithEmptyParameter("/Observation?value-quantity=");
testSearchWithEmptyParameter("/Observation?code=bar&value-quantity=");
testSearchWithEmptyParameter("/Observation?value-date=");
testSearchWithEmptyParameter("/Observation?code=bar&value-date=");
testSearchWithEmptyParameter("/Observation?value-concept=");
testSearchWithEmptyParameter("/Observation?code=bar&value-concept=");
}
private void testSearchWithEmptyParameter(String url) throws IOException, ClientProtocolException {
HttpGet get = new HttpGet(ourServerBase + url);
CloseableHttpResponse resp = ourHttpClient.execute(get);
try {
assertEquals(200, resp.getStatusLine().getStatusCode());
String respString = IOUtils.toString(resp.getEntity().getContent(), Constants.CHARSET_UTF8);
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, respString);
assertEquals(1, bundle.getEntry().size());
} finally {
IOUtils.closeQuietly(resp.getEntity().getContent());
}
}
@Test
public void testSearchWithMissingDate2() throws Exception {
MedicationRequest mr1 = new MedicationRequest();
mr1.getCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01");
IIdType id1 = myMedicationRequestDao.create(mr1).getId().toUnqualifiedVersionless();
MedicationRequest mr2 = new MedicationRequest();
mr2.getCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
IIdType id2 = myMedicationRequestDao.create(mr2).getId().toUnqualifiedVersionless();
HttpGet get = new HttpGet(ourServerBase + "/MedicationRequest?date:missing=false");
CloseableHttpResponse resp = ourHttpClient.execute(get);
try {
assertEquals(200, resp.getStatusLine().getStatusCode());
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, IOUtils.toString(resp.getEntity().getContent(), Constants.CHARSET_UTF8));
List<String> ids = toUnqualifiedVersionlessIdValues(bundle);
assertThat(ids, contains(id1.getValue()));
} finally {
IOUtils.closeQuietly(resp);
}
}
@Test
public void testEverythingWithOnlyPatient() {
Patient p = new Patient();
p.setActive(true);
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
myFhirCtx.getRestfulClientFactory().setSocketTimeout(300 * 1000);
Bundle response = ourClient
.operation()
.onInstance(id)
.named("everything")
.withNoParameters(Parameters.class)
.returnResourceType(Bundle.class)
.execute();
assertEquals(1, response.getEntry().size());
}
@Test
public void testSaveAndRetrieveResourceWithExtension() {
Patient nextPatient = new Patient();
nextPatient.setId("Patient/B");
nextPatient
.addExtension()
.setUrl("http://foo")
.setValue(new Reference("Practitioner/A"));
ourClient.update().resource(nextPatient).execute();
Patient p = ourClient.read().resource(Patient.class).withId("B").execute();
String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(encoded);
assertThat(encoded, containsString("http://foo"));
} }
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException { private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
@ -197,7 +117,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
IOUtils.closeQuietly(resp.getEntity().getContent()); IOUtils.closeQuietly(resp.getEntity().getContent());
assertEquals(200, resp.getStatusLine().getStatusCode()); assertEquals(200, resp.getStatusLine().getStatusCode());
} }
private ArrayList<IBaseResource> genResourcesOfType(Bundle theRes, Class<? extends IBaseResource> theClass) { private ArrayList<IBaseResource> genResourcesOfType(Bundle theRes, Class<? extends IBaseResource> theClass) {
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>(); ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (BundleEntryComponent next : theRes.getEntry()) { for (BundleEntryComponent next : theRes.getEntry()) {
@ -354,8 +275,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
/** /**
* See #438 * See #438
*/ */
@ -429,7 +348,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
Validate.notNull(input); Validate.notNull(input);
ourClient.create().resource(input).execute().getResource(); ourClient.create().resource(input).execute().getResource();
} }
@Test @Test
public void testCreateConditional() { public void testCreateConditional() {
@ -552,6 +470,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
@Test @Test
public void testCreateResourceConditionalComplex() throws IOException { public void testCreateResourceConditionalComplex() throws IOException {
Patient pt = new Patient(); Patient pt = new Patient();
@ -614,6 +534,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
response.close(); response.close();
} }
} }
@Test @Test
public void testCreateResourceWithNumericId() throws IOException { public void testCreateResourceWithNumericId() throws IOException {
@ -1300,31 +1221,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
// private void delete(String theResourceType, String theParamName, String theParamValue) {
// Bundle resources;
// do {
// IQuery<Bundle> forResource = ourClient.search().forResource(theResourceType);
// if (theParamName != null) {
// forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
// }
// resources = forResource.execute();
// for (IResource next : resources.toListOfResources()) {
// ourLog.info("Deleting resource: {}", next.getId());
// ourClient.delete().resource(next).execute();
// }
// } while (resources.size() > 0);
// }
//
// 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 @Test
public void testEverythingPatientOperation() throws Exception { public void testEverythingPatientOperation() throws Exception {
String methodName = "testEverythingOperation"; String methodName = "testEverythingOperation";
@ -1370,53 +1266,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
ourLog.info(ids.toString()); ourLog.info(ids.toString());
} }
@Test
public void testSearchByLastUpdated() throws Exception {
String methodName = "testSearchByLastUpdated";
Patient p = new Patient();
p.addName().setFamily(methodName+"1");
IIdType pid1 = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
Thread.sleep(10);
long time1 = System.currentTimeMillis();
Thread.sleep(10);
Patient p2 = new Patient();
p2.addName().setFamily(methodName+"2");
IIdType pid2 = ourClient.create().resource(p2).execute().getId().toUnqualifiedVersionless();
HttpGet get = new HttpGet(ourServerBase + "/Patient?_lastUpdated=lt" + new InstantType(new Date(time1)).getValueAsString());
CloseableHttpResponse response = ourHttpClient.execute(get);
try {
assertEquals(200, response.getStatusLine().getStatusCode());
String output = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
IOUtils.closeQuietly(response.getEntity().getContent());
ourLog.info(output);
List<IIdType> ids = toUnqualifiedVersionlessIds(myFhirCtx.newXmlParser().parseResource(Bundle.class, output));
ourLog.info(ids.toString());
assertThat(ids, containsInAnyOrder(pid1));
} finally {
response.close();
}
get = new HttpGet(ourServerBase + "/Patient?_lastUpdated=gt" + new InstantType(new Date(time1)).getValueAsString());
response = ourHttpClient.execute(get);
try {
assertEquals(200, response.getStatusLine().getStatusCode());
String output = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
IOUtils.closeQuietly(response.getEntity().getContent());
ourLog.info(output);
List<IIdType> ids = toUnqualifiedVersionlessIds(myFhirCtx.newXmlParser().parseResource(Bundle.class, output));
ourLog.info(ids.toString());
assertThat(ids, containsInAnyOrder(pid2));
} finally {
response.close();
}
}
@Test @Test
public void testEverythingPatientType() throws Exception { public void testEverythingPatientType() throws Exception {
String methodName = "testEverythingPatientType"; String methodName = "testEverythingPatientType";
@ -1679,6 +1528,50 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
assertEquals(77, ids.size()); assertEquals(77, ids.size());
} }
@Test
public void testEverythingWithOnlyPatient() {
Patient p = new Patient();
p.setActive(true);
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
myFhirCtx.getRestfulClientFactory().setSocketTimeout(300 * 1000);
Bundle response = ourClient
.operation()
.onInstance(id)
.named("everything")
.withNoParameters(Parameters.class)
.returnResourceType(Bundle.class)
.execute();
assertEquals(1, response.getEntry().size());
}
// private void delete(String theResourceType, String theParamName, String theParamValue) {
// Bundle resources;
// do {
// IQuery<Bundle> forResource = ourClient.search().forResource(theResourceType);
// if (theParamName != null) {
// forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
// }
// resources = forResource.execute();
// for (IResource next : resources.toListOfResources()) {
// ourLog.info("Deleting resource: {}", next.getId());
// ourClient.delete().resource(next).execute();
// }
// } while (resources.size() > 0);
// }
//
// 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();
// }
// }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Test @Test
public void testFullTextSearch() throws RuntimeException, Exception { public void testFullTextSearch() throws RuntimeException, Exception {
@ -1727,7 +1620,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
response.close(); response.close();
} }
} }
@Test @Test
public void testHasParameter() throws Exception { public void testHasParameter() throws Exception {
IIdType pid0; IIdType pid0;
@ -2074,6 +1968,57 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
@Test
public void testPagingOverEverythingSet() throws InterruptedException {
Patient p = new Patient();
p.setActive(true);
String pid = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
for (int i = 0; i < 20; i++) {
Observation o = new Observation();
o.getSubject().setReference(pid);
o.addIdentifier().setSystem("foo").setValue(Integer.toString(i));
myObservationDao.create(o);
}
mySearchCoordinatorSvcRaw.setLoadingThrottleForUnitTests(50);
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(10);
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(true);
Bundle response = ourClient
.operation()
.onInstance(new IdType(pid))
.named("everything")
.withSearchParameter(Parameters.class, "_count", new NumberParam(10))
.returnResourceType(Bundle.class)
.useHttpGet()
.execute();
assertEquals(10, response.getEntry().size());
assertEquals(null, response.getTotalElement().getValueAsString());
assertThat(response.getLink("next").getUrl(), not(emptyString()));
// Load page 2
String nextUrl = response.getLink("next").getUrl();
response = ourClient.fetchResourceFromUrl(Bundle.class, nextUrl);
assertEquals(10, response.getEntry().size());
assertEquals(null, response.getTotalElement().getValueAsString());
assertThat(response.getLink("next").getUrl(), not(emptyString()));
// Load page 3
Thread.sleep(2000);
nextUrl = response.getLink("next").getUrl();
response = ourClient.fetchResourceFromUrl(Bundle.class, nextUrl);
assertEquals(1, response.getEntry().size());
assertEquals(21, response.getTotal());
assertEquals(null, response.getLink("next"));
}
@Test @Test
public void testPatchUsingJsonPatch() throws Exception { public void testPatchUsingJsonPatch() throws Exception {
String methodName = "testPatchUsingJsonPatch"; String methodName = "testPatchUsingJsonPatch";
@ -2297,6 +2242,25 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString()); assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
} }
@Test
public void testSaveAndRetrieveResourceWithExtension() {
Patient nextPatient = new Patient();
nextPatient.setId("Patient/B");
nextPatient
.addExtension()
.setUrl("http://foo")
.setValue(new Reference("Practitioner/A"));
ourClient.update().resource(nextPatient).execute();
Patient p = ourClient.read().resource(Patient.class).withId("B").execute();
String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(encoded);
assertThat(encoded, containsString("http://foo"));
}
@Test @Test
public void testSaveAndRetrieveWithContained() { public void testSaveAndRetrieveWithContained() {
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -2517,6 +2481,52 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
@Test
public void testSearchByLastUpdated() throws Exception {
String methodName = "testSearchByLastUpdated";
Patient p = new Patient();
p.addName().setFamily(methodName+"1");
IIdType pid1 = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
Thread.sleep(10);
long time1 = System.currentTimeMillis();
Thread.sleep(10);
Patient p2 = new Patient();
p2.addName().setFamily(methodName+"2");
IIdType pid2 = ourClient.create().resource(p2).execute().getId().toUnqualifiedVersionless();
HttpGet get = new HttpGet(ourServerBase + "/Patient?_lastUpdated=lt" + new InstantType(new Date(time1)).getValueAsString());
CloseableHttpResponse response = ourHttpClient.execute(get);
try {
assertEquals(200, response.getStatusLine().getStatusCode());
String output = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
IOUtils.closeQuietly(response.getEntity().getContent());
ourLog.info(output);
List<IIdType> ids = toUnqualifiedVersionlessIds(myFhirCtx.newXmlParser().parseResource(Bundle.class, output));
ourLog.info(ids.toString());
assertThat(ids, containsInAnyOrder(pid1));
} finally {
response.close();
}
get = new HttpGet(ourServerBase + "/Patient?_lastUpdated=gt" + new InstantType(new Date(time1)).getValueAsString());
response = ourHttpClient.execute(get);
try {
assertEquals(200, response.getStatusLine().getStatusCode());
String output = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
IOUtils.closeQuietly(response.getEntity().getContent());
ourLog.info(output);
List<IIdType> ids = toUnqualifiedVersionlessIds(myFhirCtx.newXmlParser().parseResource(Bundle.class, output));
ourLog.info(ids.toString());
assertThat(ids, containsInAnyOrder(pid2));
} finally {
response.close();
}
}
@Test @Test
public void testSearchByReferenceIds() { public void testSearchByReferenceIds() {
Organization o1 = new Organization(); Organization o1 = new Organization();
@ -2587,6 +2597,28 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
@Test
public void testSearchInvalidParam() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("0");
patient.addName().setFamily("testSearchWithMixedParams").addGiven("Joe");
myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
// should be subject._id
HttpGet httpPost = new HttpGet(ourServerBase + "/Observation?subject.id=FOO");
CloseableHttpResponse resp = ourHttpClient.execute(httpPost);
try {
String respString = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(respString);
assertThat(respString, containsString("Invalid parameter chain: subject.id"));
assertEquals(400, resp.getStatusLine().getStatusCode());
} finally {
IOUtils.closeQuietly(resp.getEntity().getContent());
}
ourLog.info("Outgoing post: {}", httpPost);
}
@Test @Test
public void testSearchLastUpdatedParamRp() throws InterruptedException { public void testSearchLastUpdatedParamRp() throws InterruptedException {
String methodName = "testSearchLastUpdatedParamRp"; String methodName = "testSearchLastUpdatedParamRp";
@ -3047,6 +3079,34 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
} }
@Test
public void testSearchWithEmptyParameter() throws Exception {
Observation obs= new Observation();
obs.setStatus(ObservationStatus.FINAL);
obs.getCode().addCoding().setSystem("foo").setCode("bar");
ourClient.create().resource(obs).execute();
testSearchWithEmptyParameter("/Observation?value-quantity=");
testSearchWithEmptyParameter("/Observation?code=bar&value-quantity=");
testSearchWithEmptyParameter("/Observation?value-date=");
testSearchWithEmptyParameter("/Observation?code=bar&value-date=");
testSearchWithEmptyParameter("/Observation?value-concept=");
testSearchWithEmptyParameter("/Observation?code=bar&value-concept=");
}
private void testSearchWithEmptyParameter(String url) throws IOException, ClientProtocolException {
HttpGet get = new HttpGet(ourServerBase + url);
CloseableHttpResponse resp = ourHttpClient.execute(get);
try {
assertEquals(200, resp.getStatusLine().getStatusCode());
String respString = IOUtils.toString(resp.getEntity().getContent(), Constants.CHARSET_UTF8);
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, respString);
assertEquals(1, bundle.getEntry().size());
} finally {
IOUtils.closeQuietly(resp.getEntity().getContent());
}
}
@Test @Test
public void testSearchWithInclude() throws Exception { public void testSearchWithInclude() throws Exception {
Organization org = new Organization(); Organization org = new Organization();
@ -3211,25 +3271,28 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
@Test @Test
public void testSearchInvalidParam() throws Exception { public void testSearchWithMissingDate2() throws Exception {
Patient patient = new Patient(); MedicationRequest mr1 = new MedicationRequest();
patient.addIdentifier().setSystem("urn:system").setValue("0"); mr1.getCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
patient.addName().setFamily("testSearchWithMixedParams").addGiven("Joe"); mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01");
myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); IIdType id1 = myMedicationRequestDao.create(mr1).getId().toUnqualifiedVersionless();
// should be subject._id MedicationRequest mr2 = new MedicationRequest();
HttpGet httpPost = new HttpGet(ourServerBase + "/Observation?subject.id=FOO"); mr2.getCategory().addCoding().setSystem("urn:medicationroute").setCode("oral");
IIdType id2 = myMedicationRequestDao.create(mr2).getId().toUnqualifiedVersionless();
CloseableHttpResponse resp = ourHttpClient.execute(httpPost); HttpGet get = new HttpGet(ourServerBase + "/MedicationRequest?date:missing=false");
CloseableHttpResponse resp = ourHttpClient.execute(get);
try { try {
String respString = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8); assertEquals(200, resp.getStatusLine().getStatusCode());
ourLog.info(respString); Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, IOUtils.toString(resp.getEntity().getContent(), Constants.CHARSET_UTF8));
assertThat(respString, containsString("Invalid parameter chain: subject.id"));
assertEquals(400, resp.getStatusLine().getStatusCode()); List<String> ids = toUnqualifiedVersionlessIdValues(bundle);
assertThat(ids, contains(id1.getValue()));
} finally { } finally {
IOUtils.closeQuietly(resp.getEntity().getContent()); IOUtils.closeQuietly(resp);
} }
ourLog.info("Outgoing post: {}", httpPost);
} }
/** /**

View File

@ -42,8 +42,6 @@ public class PagingMultinodeProviderDstu3Test extends BaseResourceProviderDstu3T
myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setAllowMultipleDelete(true);
mySearchCoordinatorSvcRaw = AopTestUtils.getTargetObject(mySearchCoordinatorSvc); mySearchCoordinatorSvcRaw = AopTestUtils.getTargetObject(mySearchCoordinatorSvc);
// mySearchCoordinatorSvcRaw = (SearchCoordinatorSvcImpl)mySearchCoordinatorSvc;
} }
@Test @Test