matchingParamValues) {
IBaseResource requestContents = (IBaseResource) theRequest.getUserData().get(REQUEST_CONTENTS_USERDATA_KEY);
if (requestContents != null) {
@@ -394,10 +438,6 @@ public class OperationParameter implements IParameter {
}
}
- public static void throwInvalidMode(String paramValues) {
- throw new InvalidRequestException("Invalid mode value: \"" + paramValues + "\"");
- }
-
interface IOperationParamConverter {
Object incomingServer(Object theObject);
@@ -429,5 +469,9 @@ public class OperationParameter implements IParameter {
}
+ public static void throwInvalidMode(String paramValues) {
+ throw new InvalidRequestException("Invalid mode value: \"" + paramValues + "\"");
+ }
+
}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/BaseLastNProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/BaseLastNProvider.java
new file mode 100644
index 00000000000..396b84ede9a
--- /dev/null
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/BaseLastNProvider.java
@@ -0,0 +1,43 @@
+package ca.uhn.fhir.rest.server.provider;
+
+import ca.uhn.fhir.rest.annotation.Operation;
+import ca.uhn.fhir.rest.annotation.OperationParam;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
+import org.hl7.fhir.instance.model.api.IBaseBundle;
+import org.hl7.fhir.instance.model.api.IBaseCoding;
+import org.hl7.fhir.instance.model.api.IBaseReference;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
+
+import java.util.List;
+
+/**
+ * This class implements the Observation
+ * $lastn operation.
+ *
+ * It is does not implement the actual storage logic for this operation, but can be
+ * subclassed to provide this functionality.
+ *
+ *
+ * @since 4.1.0
+ */
+public abstract class BaseLastNProvider {
+
+ @Operation(name = Constants.OPERATION_LASTN, typeName = "Observation", idempotent = true)
+ public IBaseBundle lastN(
+ ServletRequestDetails theRequestDetails,
+ @OperationParam(name = "subject", typeName = "reference", min = 0, max = 1) IBaseReference theSubject,
+ @OperationParam(name = "category", typeName = "coding", min = 0, max = OperationParam.MAX_UNLIMITED) List theCategories,
+ @OperationParam(name = "code", typeName = "coding", min = 0, max = OperationParam.MAX_UNLIMITED) List theCodes,
+ @OperationParam(name = "max", typeName = "integer", min = 0, max = 1) IPrimitiveType theMax
+ ) {
+ return processLastN(theSubject, theCategories, theCodes, theMax);
+ }
+
+ /**
+ * Subclasses should implement this method
+ */
+ protected abstract IBaseBundle processLastN(IBaseReference theSubject, List theCategories, List theCodes, IPrimitiveType theMax);
+
+
+}
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/BaseR4ServerTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/BaseR4ServerTest.java
new file mode 100644
index 00000000000..3b5b4c6376f
--- /dev/null
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/BaseR4ServerTest.java
@@ -0,0 +1,44 @@
+package ca.uhn.fhir.rest.server;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.context.api.BundleInclusionRule;
+import ca.uhn.fhir.rest.api.EncodingEnum;
+import ca.uhn.fhir.rest.client.api.IGenericClient;
+import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
+import ca.uhn.fhir.test.utilities.JettyUtil;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.junit.After;
+
+public class BaseR4ServerTest {
+ private FhirContext myCtx = FhirContext.forR4();
+ private Server myServer;
+ protected IGenericClient myClient;
+ protected String myBaseUrl;
+
+ @After
+ public void after() throws Exception {
+ JettyUtil.closeServer(myServer);
+ }
+
+ protected void startServer(Object theProvider) throws Exception {
+ RestfulServer servlet = new RestfulServer(myCtx);
+ servlet.registerProvider(theProvider);
+ ServletHandler proxyHandler = new ServletHandler();
+ servlet.setDefaultResponseEncoding(EncodingEnum.XML);
+ servlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE);
+ ServletHolder servletHolder = new ServletHolder(servlet);
+ proxyHandler.addServletWithMapping(servletHolder, "/*");
+
+ myServer = new Server(0);
+ myServer.setHandler(proxyHandler);
+ JettyUtil.startServer(myServer);
+ int port = JettyUtil.getPortForStartedServer(myServer);
+
+ myBaseUrl = "http://localhost:" + port;
+ myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
+ myClient = myCtx.newRestfulGenericClient(myBaseUrl);
+ }
+
+}
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/LastNProviderTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/LastNProviderTest.java
new file mode 100644
index 00000000000..bba6c0d3b4e
--- /dev/null
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/LastNProviderTest.java
@@ -0,0 +1,64 @@
+package ca.uhn.fhir.rest.server;
+
+import ca.uhn.fhir.rest.server.provider.BaseLastNProvider;
+import org.hl7.fhir.instance.model.api.IBaseBundle;
+import org.hl7.fhir.instance.model.api.IBaseCoding;
+import org.hl7.fhir.instance.model.api.IBaseReference;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
+import org.hl7.fhir.r4.model.Bundle;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class LastNProviderTest extends BaseR4ServerTest {
+
+ private IBaseReference myLastSubject;
+ private List myLastCategories;
+ private List myLastCodes;
+ private IPrimitiveType myLastMax;
+
+ @Test
+ public void testAllParamsPopulated() throws Exception {
+
+ class MyProvider extends BaseLastNProvider {
+
+ @Override
+ protected IBaseBundle processLastN(IBaseReference theSubject, List theCategories, List theCodes, IPrimitiveType theMax) {
+ myLastSubject = theSubject;
+ myLastCategories = theCategories;
+ myLastCodes = theCodes;
+ myLastMax = theMax;
+
+ Bundle retVal = new Bundle();
+ retVal.setId("abc123");
+ retVal.setType(Bundle.BundleType.SEARCHSET);
+ return retVal;
+ }
+ }
+ MyProvider provider = new MyProvider();
+ startServer(provider);
+
+ Bundle response = myClient
+ .search()
+ .byUrl(myBaseUrl + "/Observation/$lastn?subject=Patient/123&category=http://terminology.hl7.org/CodeSystem/observation-category|laboratory,http://terminology.hl7.org/CodeSystem/observation-category|vital-signs&code=http://loinc.org|1111-1,http://loinc.org|2222-2&max=15")
+ .returnBundle(Bundle.class)
+ .execute();
+ assertEquals("abc123", response.getIdElement().getIdPart());
+ assertEquals("Patient/123", myLastSubject.getReferenceElement().getValue());
+ assertEquals(2, myLastCategories.size());
+ assertEquals("http://terminology.hl7.org/CodeSystem/observation-category", myLastCategories.get(0).getSystem());
+ assertEquals("laboratory", myLastCategories.get(0).getCode());
+ assertEquals("http://terminology.hl7.org/CodeSystem/observation-category", myLastCategories.get(1).getSystem());
+ assertEquals("vital-signs", myLastCategories.get(1).getCode());
+ assertEquals(2, myLastCodes.size());
+ assertEquals("http://loinc.org", myLastCodes.get(0).getSystem());
+ assertEquals("1111-1", myLastCodes.get(0).getCode());
+ assertEquals("http://loinc.org", myLastCodes.get(1).getSystem());
+ assertEquals("2222-2", myLastCodes.get(1).getCode());
+ assertEquals(15, myLastMax.getValue().intValue());
+ }
+
+
+}
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMethodSelectionR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMethodSelectionR4Test.java
index 14fa05826ef..3204c2c629f 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMethodSelectionR4Test.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMethodSelectionR4Test.java
@@ -1,24 +1,15 @@
package ca.uhn.fhir.rest.server;
-import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.context.api.BundleInclusionRule;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.Search;
-import ca.uhn.fhir.rest.api.EncodingEnum;
-import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
-import ca.uhn.fhir.test.utilities.JettyUtil;
import com.google.common.collect.Lists;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
-import org.junit.After;
import org.junit.Test;
import java.util.List;
@@ -27,18 +18,9 @@ import java.util.Set;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;
-public class ServerMethodSelectionR4Test {
+public class ServerMethodSelectionR4Test extends BaseR4ServerTest {
- private FhirContext myCtx = FhirContext.forR4();
- private Server myServer;
- private IGenericClient myClient;
-
- @After
- public void after() throws Exception {
- JettyUtil.closeServer(myServer);
- }
-
/**
* Server method with no _include
* Client request with _include
@@ -161,22 +143,6 @@ public class ServerMethodSelectionR4Test {
assertEquals(1, results.getEntry().size());
}
- private void startServer(Object theProvider) throws Exception {
- RestfulServer servlet = new RestfulServer(myCtx);
- servlet.registerProvider(theProvider);
- ServletHandler proxyHandler = new ServletHandler();
- servlet.setDefaultResponseEncoding(EncodingEnum.XML);
- servlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE);
- ServletHolder servletHolder = new ServletHolder(servlet);
- proxyHandler.addServletWithMapping(servletHolder, "/*");
-
- myServer = new Server(0);
- myServer.setHandler(proxyHandler);
- JettyUtil.startServer(myServer);
- int port = JettyUtil.getPortForStartedServer(myServer);
-
- myClient = myCtx.newRestfulGenericClient("http://localhost:" + port);
- }
public static class MyBaseProvider implements IResourceProvider {
@@ -185,6 +151,7 @@ public class ServerMethodSelectionR4Test {
public Class extends IBaseResource> getResourceType() {
return Patient.class;
}
+
}
}
diff --git a/pom.xml b/pom.xml
index 55b1dd4ae39..bc7792167a8 100755
--- a/pom.xml
+++ b/pom.xml
@@ -601,7 +601,7 @@
5.4.4.Final
- 5.11.1.Final
+ 5.11.3.Final
5.5.5
5.4.2.Final
4.4.11
@@ -857,18 +857,6 @@
7.0.0.jre8