Fix a crash when no count parameter supplied

This commit is contained in:
James Agnew 2018-02-02 12:31:59 -05:00
parent 1b9bbc90d6
commit 0e2d55081f
5 changed files with 414 additions and 137 deletions

View File

@ -192,10 +192,10 @@ public class ParameterUtil {
}
public static Object fromInteger(Class<?> theType, IntegerDt theArgument) {
if (theType.equals(Integer.class)) {
if (theArgument == null) {
return null;
}
if (theType.equals(Integer.class)) {
return theArgument.getValue();
}
IPrimitiveType<?> retVal = (IPrimitiveType<?>) ReflectionUtil.newInstance(theType);

View File

@ -54,7 +54,7 @@ public class Enumeration<T extends Enum<?>> extends PrimitiveType<T> implements
*/
@Deprecated
public Enumeration() {
// nothing
super();
}
/**

View File

@ -728,6 +728,7 @@ public class JsonParserDstu3Test {
Observation obs = new Observation();
obs.setId("1");
obs.getMeta().addProfile("http://profile");
obs.setStatus(ObservationStatus.FINAL);
Extension ext = obs.addExtension();
ext.setUrl("http://exturl").setValue(new StringType("ext_url_value"));
@ -758,6 +759,9 @@ public class JsonParserDstu3Test {
assertEquals(1, obs.getExtension().size());
assertEquals("http://exturl", obs.getExtension().get(0).getUrl());
assertEquals("ext_url_value", ((StringType) obs.getExtension().get(0).getValue()).getValue());
assertEquals("final", obs.getStatusElement().getValueAsString());
assertEquals(ObservationStatus.FINAL, obs.getStatusElement().getValue());
}
@Test

View File

@ -0,0 +1,267 @@
package ca.uhn.fhir.rest.server;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.annotation.Count;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.util.PortUtil;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
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.hamcrest.core.IsEqual;
import org.hamcrest.core.StringStartsWith;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
public class PlainProviderR4Test {
private static FhirContext ourCtx = FhirContext.forR4();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PlainProviderR4Test.class);
private CloseableHttpClient myClient;
private int myPort;
private RestfulServer myRestfulServer;
private Server myServer;
@After
public void after() throws Exception {
myServer.stop();
}
@Before
public void before() throws Exception {
myPort = PortUtil.findFreePort();
myServer = new Server(myPort);
ServletHandler proxyHandler = new ServletHandler();
ServletHolder servletHolder = new ServletHolder();
myRestfulServer = new RestfulServer(ourCtx);
servletHolder.setServlet(myRestfulServer);
proxyHandler.addServletWithMapping(servletHolder, "/fhir/context/*");
myServer.setHandler(proxyHandler);
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
myClient = builder.build();
}
@Test
public void testGlobalHistory() throws Exception {
GlobalHistoryProvider provider = new GlobalHistoryProvider();
myRestfulServer.setProviders(provider);
myServer.start();
String baseUri = "http://localhost:" + myPort + "/fhir/context";
HttpResponse status = myClient.execute(new HttpGet(baseUri + "/_history?_since=2012-01-02T00%3A01%3A02&_count=12"));
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent);
assertEquals(3, bundle.getEntry().size());
assertThat(provider.myLastSince.getValueAsString(), StringStartsWith.startsWith("2012-01-02T00:01:02"));
assertThat(provider.myLastCount.getValueAsString(), IsEqual.equalTo("12"));
status = myClient.execute(new HttpGet(baseUri + "/_history?&_count=12"));
responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent);
assertEquals(3, bundle.getEntry().size());
assertNull(provider.myLastSince);
assertThat(provider.myLastCount.getValueAsString(), IsEqual.equalTo("12"));
status =myClient.execute(new HttpGet(baseUri + "/_history?_since=2012-01-02T00%3A01%3A02"));
responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent);
assertEquals(3, bundle.getEntry().size());
assertThat(provider.myLastSince.getValueAsString(), StringStartsWith.startsWith("2012-01-02T00:01:02"));
assertNull(provider.myLastCount);
}
@Test
public void testGlobalHistoryNoParams() throws Exception {
GlobalHistoryProvider provider = new GlobalHistoryProvider();
myRestfulServer.setProviders(provider);
myServer.start();
String baseUri = "http://localhost:" + myPort + "/fhir/context";
CloseableHttpResponse status = myClient.execute(new HttpGet(baseUri + "/_history"));
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent);
assertEquals(3, bundle.getEntry().size());
assertNull(provider.myLastSince);
assertNull(provider.myLastCount);
}
@Test
public void testSearchByParamIdentifier() throws Exception {
myRestfulServer.setProviders(new SearchProvider());
myServer.start();
String baseUri = "http://localhost:" + myPort + "/fhir/context";
String uri = baseUri + "/Patient?identifier=urn:hapitest:mrns%7C00001";
HttpGet httpGet = new HttpGet(uri);
try (CloseableHttpResponse status = myClient.execute(httpGet)) {
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent);
assertEquals(1, bundle.getEntry().size());
Patient patient = (Patient) bundle.getEntry().get(0).getResource();
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
assertEquals(uri.replace(":hapitest:", "%3Ahapitest%3A"), bundle.getLink("self").getUrl());
}
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
private static Organization createOrganization() {
Organization retVal = new Organization();
retVal.setId("1");
retVal.addIdentifier();
retVal.getIdentifier().get(0).setUse(Identifier.IdentifierUse.OFFICIAL);
retVal.getIdentifier().get(0).setSystem(("urn:hapitest:mrns"));
retVal.getIdentifier().get(0).setValue("00001");
retVal.setName("Test Org");
return retVal;
}
private static Patient createPatient() {
Patient patient = new Patient();
patient.setId("1");
patient.addIdentifier();
patient.getIdentifier().get(0).setUse(Identifier.IdentifierUse.OFFICIAL);
patient.getIdentifier().get(0).setSystem(("urn:hapitest:mrns"));
patient.getIdentifier().get(0).setValue("00001");
patient.addName();
patient.getName().get(0).setFamily("Test");
patient.getName().get(0).addGiven("PatientOne");
patient.getGenderElement().setValueAsString("male");
return patient;
}
public static class GlobalHistoryProvider {
private IntegerType myLastCount;
private InstantType myLastSince;
@History
public List<IBaseResource> getGlobalHistory(@Since InstantType theSince, @Count IntegerType theCount) {
myLastSince = theSince;
myLastCount = theCount;
ArrayList<IBaseResource> retVal = new ArrayList<>();
Resource p = createPatient();
p.setId(new IdType("1"));
p.getMeta().setVersionId("A");
p.getMeta().getLastUpdatedElement().setValueAsString("2012-01-01T01:00:01");
retVal.add(p);
p = createPatient();
p.setId(new IdType("1"));
p.getMeta().setVersionId("B");
p.getMeta().getLastUpdatedElement().setValueAsString("2012-01-01T01:00:03");
retVal.add(p);
p = createOrganization();
p.setId(new IdType("1"));
p.getMeta().setVersionId("A");
p.getMeta().getLastUpdatedElement().setValueAsString("2013-01-01T01:00:01");
retVal.add(p);
return retVal;
}
}
public static class SearchProvider {
@Search(type = Patient.class)
public Patient findPatient(@RequiredParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier) {
for (Patient next : getIdToPatient().values()) {
for (Identifier nextId : next.getIdentifier()) {
if (nextId.getSystem().equals(theIdentifier.getSystem()) && nextId.getValue().equals(theIdentifier.getValue())) {
return next;
}
}
}
return null;
}
public Map<String, Patient> getIdToPatient() {
Map<String, Patient> idToPatient = new HashMap<>();
{
Patient patient = createPatient();
idToPatient.put("1", patient);
}
{
Patient patient = new Patient();
patient.getIdentifier().add(new Identifier());
patient.getIdentifier().get(0).setUse(Identifier.IdentifierUse.OFFICIAL);
patient.getIdentifier().get(0).setSystem(("urn:hapitest:mrns"));
patient.getIdentifier().get(0).setValue("00002");
patient.getName().add(new HumanName());
patient.getName().get(0).setFamily("Test");
patient.getName().get(0).addGiven("PatientTwo");
patient.getGenderElement().setValueAsString("female");
idToPatient.put("2", patient);
}
return idToPatient;
}
/**
* Retrieve the resource by its identifier
*
* @param theId
* The resource identity
* @return The resource
*/
@Read(type = Patient.class)
public Patient getPatientById(@IdParam IdType theId) {
return getIdToPatient().get(theId.getValue());
}
}
}

View File

@ -98,6 +98,12 @@
to build correctly on JDK 9.0. Currently building is supported on
JDK 8.x and 9.x only.
</action>
<action type="fix">
Fixed a regression in server where a count parameter in the form
<![CDATA[<code>@Count IntegerType theCount</code>]]>
caused an exception if the client made a request with
no count parameter included. Thanks to Viviana Sanz for reporting!
</action>
</release>
<release version="3.2.0" date="2018-01-13">
<action type="add">