Don't discard _count from parameters when method has @Count
This commit is contained in:
parent
563f4e4c46
commit
d5e2170595
|
@ -55,7 +55,7 @@ public class CountParameter implements IParameter {
|
|||
|
||||
@Override
|
||||
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
|
||||
String[] sinceParams = theRequest.getParameters().remove(Constants.PARAM_COUNT);
|
||||
String[] sinceParams = theRequest.getParameters().get(Constants.PARAM_COUNT);
|
||||
if (sinceParams != null) {
|
||||
if (sinceParams.length > 0) {
|
||||
if (StringUtils.isNotBlank(sinceParams[0])) {
|
||||
|
|
|
@ -325,6 +325,96 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* ?identifier=
|
||||
*/
|
||||
@Test
|
||||
public void testTransactionCreateMatchUrlWithOneMatchNoResourceName1() {
|
||||
String methodName = "testTransactionCreateMatchUrlWithOneMatch";
|
||||
Bundle request = new Bundle();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType id = myPatientDao.update(p, mySrd).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/" + methodName);
|
||||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("Some Observation");
|
||||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = mySystemDao.transaction(mySrd, request);
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
Entry respEntry = resp.getEntry().get(0);
|
||||
assertEquals(Constants.STATUS_HTTP_200_OK + " OK", respEntry.getResponse().getStatus());
|
||||
assertThat(respEntry.getResponse().getLocation(), endsWith("Patient/" + id.getIdPart() + "/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
respEntry = resp.getEntry().get(1);
|
||||
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
|
||||
assertThat(respEntry.getResponse().getLocation(), containsString("Observation/"));
|
||||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = (Observation) myObservationDao.read(new IdDt(respEntry.getResponse().getLocationElement()), mySrd);
|
||||
assertEquals(id.toVersionless(), o.getSubject().getReference());
|
||||
assertEquals("1", o.getId().getVersionIdPart());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* identifier=
|
||||
*/
|
||||
@Test
|
||||
public void testTransactionCreateMatchUrlWithOneMatchNoResourceName2() {
|
||||
String methodName = "testTransactionCreateMatchUrlWithOneMatch";
|
||||
Bundle request = new Bundle();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType id = myPatientDao.update(p, mySrd).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/" + methodName);
|
||||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("Some Observation");
|
||||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = mySystemDao.transaction(mySrd, request);
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
Entry respEntry = resp.getEntry().get(0);
|
||||
assertEquals(Constants.STATUS_HTTP_200_OK + " OK", respEntry.getResponse().getStatus());
|
||||
assertThat(respEntry.getResponse().getLocation(), endsWith("Patient/" + id.getIdPart() + "/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
respEntry = resp.getEntry().get(1);
|
||||
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
|
||||
assertThat(respEntry.getResponse().getLocation(), containsString("Observation/"));
|
||||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = (Observation) myObservationDao.read(new IdDt(respEntry.getResponse().getLocationElement()), mySrd);
|
||||
assertEquals(id.toVersionless(), o.getSubject().getReference());
|
||||
assertEquals("1", o.getId().getVersionIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionCreateMatchUrlWithTwoMatch() {
|
||||
String methodName = "testTransactionCreateMatchUrlWithTwoMatch";
|
||||
|
|
|
@ -80,6 +80,30 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionFromBundle2() throws Exception {
|
||||
String input = IOUtils.toString(getClass().getResourceAsStream("/transaction-bundle.xml"));
|
||||
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
|
||||
Bundle response = mySystemDao.transaction(mySrd, bundle);
|
||||
|
||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
|
||||
assertEquals("201 Created", response.getEntryFirstRep().getResponse().getStatus());
|
||||
assertEquals("Practitioner/1/_history/1", response.getEntryFirstRep().getResponse().getLocation());
|
||||
|
||||
/*
|
||||
* Now a second time
|
||||
*/
|
||||
|
||||
bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
|
||||
response = mySystemDao.transaction(mySrd, bundle);
|
||||
|
||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
|
||||
assertEquals("200 OK", response.getEntryFirstRep().getResponse().getStatus());
|
||||
assertEquals("Practitioner/1/_history/1", response.getEntryFirstRep().getResponse().getLocation());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testTransactionWithNullReference() {
|
||||
Patient p = new Patient();
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<!-- we need to use a transaction for this type of procedure -->
|
||||
<type value="transaction"/>
|
||||
<!-- Bundle Id will be generated by Map Force on the client - this is the resource id for the bundle -->
|
||||
<id value="f9935843-19a2-4a1a-4016-7bea52de77f8"/>
|
||||
<!--Lets process patient first -->
|
||||
<!--We still need to include patient in the bundle for our check even though it a cut down bogus entry -->
|
||||
<entry>
|
||||
<!--Should this be provided for a Create i.e. should the adapter generate the local id (if resource not exist) or let the fhir server do it? -->
|
||||
<!--This is generate by Map Force and use for references. If Practitioner does not exist FHIR server should use it at Local Resource Id -->
|
||||
<fullUrl value="urn:uuid:47709cc7-b3ec-4abc-9d26-3df3d3d57907"/>
|
||||
<resource>
|
||||
<Practitioner xmlns="http://hl7.org/fhir">
|
||||
<identifier>
|
||||
<use value="official"/>
|
||||
<!--Reuse value from CDA -->
|
||||
<system value="urn:oid:2.16.840.1.113883.2.4.6.3"/>
|
||||
<!--Reuse OIDs from CDA -->
|
||||
<!-- BSN identification system -->
|
||||
<value value="567IUI51C157"/>
|
||||
</identifier>
|
||||
<name>
|
||||
<use value="official"/>
|
||||
<family value="Heps"/>
|
||||
<given value="Simone"/>
|
||||
<suffix value="MD"/>
|
||||
</name>
|
||||
<telecom>
|
||||
<system value="phone"/>
|
||||
<value value="020556936"/>
|
||||
<use value="work"/>
|
||||
</telecom>
|
||||
<telecom>
|
||||
<system value="email"/>
|
||||
<value value="S.M.Heps@bmc.nl"/>
|
||||
<use value="work"/>
|
||||
</telecom>
|
||||
<telecom>
|
||||
<system value="fax"/>
|
||||
<value value="0205669283"/>
|
||||
<use value="work"/>
|
||||
</telecom>
|
||||
<address>
|
||||
<use value="work"/>
|
||||
<line value="Galapagosweg 91"/>
|
||||
<city value="Den Burg"/>
|
||||
<postalCode value="9105 PZ"/>
|
||||
<country value="NLD"/>
|
||||
<!-- ISO 3166 Codes (Countries) -->
|
||||
</address>
|
||||
<gender value="female"/>
|
||||
<birthDate value="1971-11-07"/>
|
||||
</Practitioner>
|
||||
</resource>
|
||||
<request>
|
||||
<!--For this entry we only want to create the practitioner based on the entry data if we dont find one -->
|
||||
<method value="POST"/>
|
||||
<url value="Practitioner"/>
|
||||
<!--Use DrProviderNumber Paul to add more syntax below -->
|
||||
<ifNoneExist value="identifier=567IUI51C157"/>
|
||||
</request>
|
||||
</entry>
|
||||
</Bundle>
|
|
@ -0,0 +1,137 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.HumanName;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.annotation.Count;
|
||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class SearchCountParamDstu3Test {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchCountParamDstu3Test.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourLastMethod;
|
||||
private static Integer ourLastParam;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourLastMethod = null;
|
||||
ourLastParam = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_count=2");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertEquals("search", ourLastMethod);
|
||||
assertEquals(new Integer(2), ourLastParam);
|
||||
|
||||
//@formatter:off
|
||||
assertThat(responseContent, stringContainsInOrder(
|
||||
"<link>",
|
||||
"<relation value=\"self\"/>",
|
||||
"<url value=\"http://localhost:" + ourPort + "/Patient?_count=2\"/>",
|
||||
"</link>",
|
||||
"<link>",
|
||||
"<relation value=\"next\"/>",
|
||||
"<url value=\"http://localhost:" + ourPort + "?_getpages=", "&_getpagesoffset=2&_count=2&_bundletype=searchset\"/>",
|
||||
"</link>"));
|
||||
//@formatter:on
|
||||
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
ourServer.stop();
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
RestfulServer servlet = new RestfulServer(ourCtx);
|
||||
servlet.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
servlet.setResourceProviders(patientProvider);
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourClient = builder.build();
|
||||
|
||||
}
|
||||
|
||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Search()
|
||||
public List search(
|
||||
@OptionalParam(name=Patient.SP_IDENTIFIER) TokenParam theIdentifier,
|
||||
@Count() Integer theParam
|
||||
) {
|
||||
ourLastMethod = "search";
|
||||
ourLastParam = theParam;
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
for (int i = 1; i < 100; i++) {
|
||||
retVal.add((Patient) new Patient().addName(new HumanName().addFamily("FAMILY")).setId("" + i));
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -176,6 +176,11 @@
|
|||
value be completely contained by the range specified. Thanks to Chris Moesel
|
||||
for the suggestion.
|
||||
</action>
|
||||
<action type="fix">
|
||||
In server, if a parameter was annotated with the <![CDATA[@Count]]> annotation, the
|
||||
count would not appear in the self/prev/next links and would not actually be applied
|
||||
to the search results by the server. Thanks to Jim Steele for letting us know!
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.5" date="2016-04-20">
|
||||
<action type="fix" issue="339">
|
||||
|
|
Loading…
Reference in New Issue