From a546c94ccb65728b50bb976697584dbd0b863d3b Mon Sep 17 00:00:00 2001 From: Clayton Bodendein Date: Sat, 21 Oct 2017 23:00:19 -0500 Subject: [PATCH 1/4] Fixes #764 to allow the AbstractJaxRsConformanceProvider to support the DSTU2_HL7ORG FhirContext --- hapi-fhir-jaxrsserver-base/pom.xml | 5 + .../AbstractJaxRsConformanceProvider.java | 9 ++ ...xRsConformanceProviderDstu2Hl7OrgTest.java | 109 +++++++++++++++ ...xRsMockPatientRestProviderDstu2Hl7Org.java | 128 ++++++++++++++++++ .../conf/ServerConformanceProvider.java | 54 ++++---- 5 files changed, 276 insertions(+), 29 deletions(-) create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2Hl7Org.java diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 3f2ac2eacae..b8d880ffb28 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -51,6 +51,11 @@ hapi-fhir-structures-dstu2 ${project.version} + + ca.uhn.hapi.fhir + hapi-fhir-structures-hl7org-dstu2 + ${project.version} + ca.uhn.hapi.fhir hapi-fhir-structures-dstu3 diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java index 0d9c7b2b1c5..22b82df6e86 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java @@ -68,6 +68,7 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv /** the conformance. It is created once during startup */ private CapabilityStatement myDstu3CapabilityStatement; private ca.uhn.fhir.model.dstu2.resource.Conformance myDstu2Conformance; + private org.hl7.fhir.instance.model.Conformance myDstu2Hl7OrgConformance; /** * Constructor allowing the description, servername and server to be set @@ -132,6 +133,10 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider serverCapabilityStatementProvider = new ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider(serverConfiguration); serverCapabilityStatementProvider.initializeOperations(); myDstu2Conformance = serverCapabilityStatementProvider.getServerConformance(null); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) { + org.hl7.fhir.instance.conf.ServerConformanceProvider serverCapabilityStatementProvider = new org.hl7.fhir.instance.conf.ServerConformanceProvider(serverConfiguration); + serverCapabilityStatementProvider.initializeOperations(); + myDstu2Hl7OrgConformance = serverCapabilityStatementProvider.getServerConformance(null); } } @@ -173,6 +178,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { conformance = myDstu2Conformance; // return (Response) response.returnResponse(ParseAction.create(myDstu2CapabilityStatement), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName()); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) { + conformance = myDstu2Hl7OrgConformance; } if (conformance != null) { @@ -261,6 +268,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv return Class.class.cast(CapabilityStatement.class); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { return Class.class.cast(ca.uhn.fhir.model.dstu2.resource.Conformance.class); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) { + return Class.class.cast(org.hl7.fhir.instance.model.Conformance.class); } return null; } diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java new file mode 100644 index 00000000000..9b3a8ca6fda --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java @@ -0,0 +1,109 @@ +package ca.uhn.fhir.jaxrs.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; + +import javax.ws.rs.HttpMethod; +import javax.ws.rs.core.*; + +import org.glassfish.jersey.internal.MapPropertiesDelegate; +import org.glassfish.jersey.server.ContainerRequest; +import org.junit.Before; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider; +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu2Hl7Org; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.server.IResourceProvider; + +public class AbstractJaxRsConformanceProviderDstu2Hl7OrgTest { + + private static final String BASEURI = "http://basiuri"; + private static final String REQUESTURI = BASEURI + "/metadata"; + AbstractJaxRsConformanceProvider provider; + private ConcurrentHashMap, IResourceProvider> providers; + private ContainerRequest headers; + private MultivaluedHashMap queryParameters; + + @Before + public void setUp() throws Exception { + // headers + headers = new ContainerRequest(new URI(BASEURI), new URI(REQUESTURI), HttpMethod.GET, null, + new MapPropertiesDelegate()); + // uri info + queryParameters = new MultivaluedHashMap(); + + + providers = new ConcurrentHashMap, IResourceProvider>(); + provider = createConformanceProvider(providers); + } + + @Test + public void testConformance() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + Response response = createConformanceProvider(providers).conformance(); + System.out.println(response); + } + + @Test + public void testConformanceUsingOptions() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + Response response = createConformanceProvider(providers).conformanceUsingOptions(); + System.out.println(response); + } + + @Test + public void testConformanceWithMethods() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsMockPatientRestProviderDstu2Hl7Org.class, new TestJaxRsMockPatientRestProviderDstu2Hl7Org()); + Response response = createConformanceProvider(providers).conformance(); + assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus()); + assertTrue(response.getEntity().toString().contains("\"type\": \"Patient\"")); + assertTrue(response.getEntity().toString().contains("someCustomOperation")); + System.out.println(response); + System.out.println(response.getEntity()); + } + + @Test + public void testConformanceInXml() throws Exception { + queryParameters.put(Constants.PARAM_FORMAT, Arrays.asList(Constants.CT_XML)); + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsMockPatientRestProviderDstu2Hl7Org.class, new TestJaxRsMockPatientRestProviderDstu2Hl7Org()); + Response response = createConformanceProvider(providers).conformance(); + assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus()); + System.out.println(response.getEntity()); + assertTrue(response.getEntity().toString().contains(" ")); + assertTrue(response.getEntity().toString().contains("someCustomOperation")); + System.out.println(response.getEntity()); + } + + private AbstractJaxRsConformanceProvider createConformanceProvider(final ConcurrentHashMap, IResourceProvider> providers) + throws Exception { + AbstractJaxRsConformanceProvider result = new AbstractJaxRsConformanceProvider(FhirContext.forDstu2Hl7Org(), null, null, null) { + @Override + protected ConcurrentHashMap, IResourceProvider> getProviders() { + return providers; + } + }; + // mocks + UriInfo uriInfo = mock(UriInfo.class); + when(uriInfo.getQueryParameters()).thenReturn(queryParameters); + when(uriInfo.getBaseUri()).thenReturn(new URI(BASEURI)); + when(uriInfo.getRequestUri()).thenReturn(new URI(BASEURI + "/foo")); + result.setUriInfo(uriInfo); + result.setHeaders(headers); + result.setUpPostConstruct(); + return result; + } + +} + diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2Hl7Org.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2Hl7Org.java new file mode 100644 index 00000000000..fae37282aa7 --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2Hl7Org.java @@ -0,0 +1,128 @@ +package ca.uhn.fhir.jaxrs.server.test; + +import java.util.List; + +import javax.ejb.Stateless; +import javax.interceptor.Interceptors; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.hl7.fhir.instance.model.*; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.mockito.Mockito; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; +import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.param.StringAndListParam; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; +import ca.uhn.fhir.rest.server.IPagingProvider; + +/** + * A test server delegating each call to a mock + */ +@Path(TestJaxRsMockPatientRestProviderDstu2Hl7Org.PATH) +@Stateless +@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_XML_NEW }) +@Interceptors(JaxRsExceptionInterceptor.class) +public class TestJaxRsMockPatientRestProviderDstu2Hl7Org extends AbstractJaxRsResourceProvider { + + static final String PATH = "/Patient"; + + public static final TestJaxRsMockPatientRestProviderDstu2Hl7Org mock = Mockito.mock(TestJaxRsMockPatientRestProviderDstu2Hl7Org.class); + + public static final FifoMemoryPagingProvider PAGING_PROVIDER; + + static + { + PAGING_PROVIDER = new FifoMemoryPagingProvider(10); + PAGING_PROVIDER.setDefaultPageSize(10); + PAGING_PROVIDER.setMaximumPageSize(100); + } + + /** + * Constructor + */ + public TestJaxRsMockPatientRestProviderDstu2Hl7Org() { + super(FhirContext.forDstu2Hl7Org()); + } + + @Search + public List search(@RequiredParam(name = Patient.SP_NAME) final StringParam name, @RequiredParam(name=Patient.SP_ADDRESS) StringAndListParam theAddressParts) { + return mock.search(name, theAddressParts); + } + + @Update + public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient,@ConditionalUrlParam final String theConditional) throws Exception { + return mock.update(theId, patient, theConditional); + } + + @Read + public Patient find(@IdParam final IdType theId) { + return mock.find(theId); + } + + @Read(version = true) + public Patient findHistory(@IdParam final IdType theId) { + return mock.findHistory(theId); + } + + @Create + public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional) + throws Exception { + return mock.create(patient, theConditional); + } + + @Delete + public MethodOutcome delete(@IdParam final IdType theId, @ConditionalUrlParam final String theConditional) { + return mock.delete(theId, theConditional); + } + + @Search(compartmentName = "Condition") + public List searchCompartment(@IdParam IdType thePatientId) { + return mock.searchCompartment(thePatientId); + } + + @GET + @Path("/{id}/$someCustomOperation") + public Response someCustomOperationUsingGet(@PathParam("id") String id, String resource) throws Exception { + return customOperation(resource, RequestTypeEnum.GET, id, "$someCustomOperation", + RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE); + } + + @POST + @Path("/{id}/$someCustomOperation") + public Response someCustomOperationUsingPost(@PathParam("id") String id, String resource) throws Exception { + return customOperation(resource, RequestTypeEnum.POST, id, "$someCustomOperation", + RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE); + } + + @Operation(name = "someCustomOperation", idempotent = true, returnParameters = { + @OperationParam(name = "return", type = StringType.class) }) + public Parameters someCustomOperation(@IdParam IdType myId, @OperationParam(name = "dummy") StringType dummyInput) { + return mock.someCustomOperation(myId, dummyInput); + } + + @Validate() + public MethodOutcome validate(@ResourceParam final Patient resource) { + MethodOutcome mO = new MethodOutcome(); + mO.setOperationOutcome(new OperationOutcome()); + return mO; + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Override + public IPagingProvider getPagingProvider() { + return PAGING_PROVIDER; + } + +} diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java index 858e84f87cf..9f69509733b 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java @@ -28,6 +28,7 @@ import java.util.*; import java.util.Map.Entry; import java.util.jar.Manifest; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import ca.uhn.fhir.context.FhirVersionEnum; @@ -70,11 +71,15 @@ public class ServerConformanceProvider implements IServerConformanceProvider myOperationBindingToName; private HashMap> myOperationNameToBindings; private String myPublisher = "Not provided"; - private RestfulServer myRestfulServer; + private RestulfulServerConfiguration myServerConfiguration; public ServerConformanceProvider(RestfulServer theRestfulServer) { - myRestfulServer = theRestfulServer; + this.myServerConfiguration = theRestfulServer.createConfiguration(); } + + public ServerConformanceProvider(RestulfulServerConfiguration theServerConfiguration) { + this.myServerConfiguration = theServerConfiguration; + } /* * Add a no-arg constructor and seetter so that the @@ -85,11 +90,16 @@ public class ServerConformanceProvider implements IServerConformanceProvider systemOps, BaseMethodBinding nextMethodBinding) { if (nextMethodBinding.getRestOperationType() != null) { @@ -114,7 +124,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider>> collectMethodBindings() { Map>> resourceToMethods = new TreeMap>>(); - for (ResourceBinding next : myRestfulServer.getResourceBindings()) { + for (ResourceBinding next : myServerConfiguration.getResourceBindings()) { String resourceName = next.getResourceName(); for (BaseMethodBinding nextMethodBinding : next.getMethodBindings()) { if (resourceToMethods.containsKey(resourceName) == false) { @@ -123,7 +133,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider nextMethodBinding : myRestfulServer.getServerBindings()) { + for (BaseMethodBinding nextMethodBinding : myServerConfiguration.getServerBindings()) { String resourceName = ""; if (resourceToMethods.containsKey(resourceName) == false) { resourceToMethods.put(resourceName, new ArrayList>()); @@ -163,10 +173,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider resourceOps = new HashSet(); ConformanceRestResourceComponent resource = rest.addResource(); String resourceName = nextEntry.getKey(); - RuntimeResourceDefinition def = myRestfulServer.getFhirContext().getResourceDefinition(resourceName); + RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName); resource.getTypeElement().setValue(def.getName()); - resource.getProfile() - .setReference((def.getResourceProfile(myRestfulServer.getServerBaseForRequest(theRequest)))); + ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE)); + String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest); + resource.getProfile().setReference((def.getResourceProfile(serverBase))); TreeSet includes = new TreeSet(); @@ -296,7 +307,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider includes, DynamicSearchMethodBinding searchMethodBinding) { includes.addAll(searchMethodBinding.getIncludes()); @@ -433,7 +429,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider nextTarget : nextParameter.getDeclaredTypes()) { - RuntimeResourceDefinition targetDef = myRestfulServer.getFhirContext().getResourceDefinition(nextTarget); + RuntimeResourceDefinition targetDef = myServerConfiguration.getFhirContext().getResourceDefinition(nextTarget); if (targetDef != null) { ResourceType code; try { From 452f6bc24c1edfb5f1af9a9fc1c8eb8469d31f43 Mon Sep 17 00:00:00 2001 From: Clayton Bodendein Date: Sun, 22 Oct 2017 18:19:10 -0500 Subject: [PATCH 2/4] Related to issue #764 - adds support for the DSTU2_1 FHIR context in AbstractJaxRsConformanceProvider --- hapi-fhir-jaxrsserver-base/pom.xml | 5 + .../AbstractJaxRsConformanceProvider.java | 9 ++ ...ctJaxRsConformanceProviderDstu2_1Test.java | 108 +++++++++++++++ ...stJaxRsMockPatientRestProviderDstu2_1.java | 128 ++++++++++++++++++ .../conf/ServerConformanceProvider.java | 11 +- 5 files changed, 254 insertions(+), 7 deletions(-) create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2_1.java diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index b8d880ffb28..3f728fccc8e 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -56,6 +56,11 @@ hapi-fhir-structures-hl7org-dstu2 ${project.version} + + ca.uhn.hapi.fhir + hapi-fhir-structures-dstu2.1 + ${project.version} + ca.uhn.hapi.fhir hapi-fhir-structures-dstu3 diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java index 22b82df6e86..6f76e3f6959 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java @@ -67,6 +67,7 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv /** the conformance. It is created once during startup */ private CapabilityStatement myDstu3CapabilityStatement; + private org.hl7.fhir.dstu2016may.model.Conformance myDstu2_1Conformance; private ca.uhn.fhir.model.dstu2.resource.Conformance myDstu2Conformance; private org.hl7.fhir.instance.model.Conformance myDstu2Hl7OrgConformance; @@ -129,6 +130,10 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv ServerCapabilityStatementProvider serverCapabilityStatementProvider = new ServerCapabilityStatementProvider(serverConfiguration); serverCapabilityStatementProvider.initializeOperations(); myDstu3CapabilityStatement = serverCapabilityStatementProvider.getServerConformance(null); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_1)) { + org.hl7.fhir.dstu2016may.hapi.rest.server.ServerConformanceProvider serverCapabilityStatementProvider = new org.hl7.fhir.dstu2016may.hapi.rest.server.ServerConformanceProvider(serverConfiguration); + serverCapabilityStatementProvider.initializeOperations(); + myDstu2_1Conformance = serverCapabilityStatementProvider.getServerConformance(null); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider serverCapabilityStatementProvider = new ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider(serverConfiguration); serverCapabilityStatementProvider.initializeOperations(); @@ -175,6 +180,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { conformance = myDstu3CapabilityStatement; // return (Response) response.returnResponse(ParseAction.create(myDstu3CapabilityStatement), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName()); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_1)) { + conformance = myDstu2_1Conformance; } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { conformance = myDstu2Conformance; // return (Response) response.returnResponse(ParseAction.create(myDstu2CapabilityStatement), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName()); @@ -266,6 +273,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv public Class getResourceType() { if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { return Class.class.cast(CapabilityStatement.class); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_1)) { + return Class.class.cast(org.hl7.fhir.dstu2016may.model.Conformance.class); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) { return Class.class.cast(ca.uhn.fhir.model.dstu2.resource.Conformance.class); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) { diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java new file mode 100644 index 00000000000..60b447e0ab4 --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java @@ -0,0 +1,108 @@ +package ca.uhn.fhir.jaxrs.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; + +import javax.ws.rs.HttpMethod; +import javax.ws.rs.core.*; + +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu2_1; +import org.glassfish.jersey.internal.MapPropertiesDelegate; +import org.glassfish.jersey.server.ContainerRequest; +import org.junit.Before; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.server.IResourceProvider; + +public class AbstractJaxRsConformanceProviderDstu2_1Test { + + private static final String BASEURI = "http://basiuri"; + private static final String REQUESTURI = BASEURI + "/metadata"; + AbstractJaxRsConformanceProvider provider; + private ConcurrentHashMap, IResourceProvider> providers; + private ContainerRequest headers; + private MultivaluedHashMap queryParameters; + + @Before + public void setUp() throws Exception { + // headers + headers = new ContainerRequest(new URI(BASEURI), new URI(REQUESTURI), HttpMethod.GET, null, + new MapPropertiesDelegate()); + // uri info + queryParameters = new MultivaluedHashMap(); + + + providers = new ConcurrentHashMap, IResourceProvider>(); + provider = createConformanceProvider(providers); + } + + @Test + public void testConformance() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + Response response = createConformanceProvider(providers).conformance(); + System.out.println(response); + } + + @Test + public void testConformanceUsingOptions() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + Response response = createConformanceProvider(providers).conformanceUsingOptions(); + System.out.println(response); + } + + @Test + public void testConformanceWithMethods() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsMockPatientRestProviderDstu2_1.class, new TestJaxRsMockPatientRestProviderDstu2_1()); + Response response = createConformanceProvider(providers).conformance(); + assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus()); + assertTrue(response.getEntity().toString().contains("\"type\": \"Patient\"")); + assertTrue(response.getEntity().toString().contains("\"someCustomOperation")); + System.out.println(response); + System.out.println(response.getEntity()); + } + + @Test + public void testConformanceInXml() throws Exception { + queryParameters.put(Constants.PARAM_FORMAT, Arrays.asList(Constants.CT_XML)); + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsMockPatientRestProviderDstu2_1.class, new TestJaxRsMockPatientRestProviderDstu2_1()); + Response response = createConformanceProvider(providers).conformance(); + assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus()); + System.out.println(response.getEntity()); + assertTrue(response.getEntity().toString().contains(" ")); + assertTrue(response.getEntity().toString().contains("\"someCustomOperation")); + System.out.println(response.getEntity()); + } + + private AbstractJaxRsConformanceProvider createConformanceProvider(final ConcurrentHashMap, IResourceProvider> providers) + throws Exception { + AbstractJaxRsConformanceProvider result = new AbstractJaxRsConformanceProvider(FhirContext.forDstu2_1(), null, null, null) { + @Override + protected ConcurrentHashMap, IResourceProvider> getProviders() { + return providers; + } + }; + // mocks + UriInfo uriInfo = mock(UriInfo.class); + when(uriInfo.getQueryParameters()).thenReturn(queryParameters); + when(uriInfo.getBaseUri()).thenReturn(new URI(BASEURI)); + when(uriInfo.getRequestUri()).thenReturn(new URI(BASEURI + "/foo")); + result.setUriInfo(uriInfo); + result.setHeaders(headers); + result.setUpPostConstruct(); + return result; + } + +} diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2_1.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2_1.java new file mode 100644 index 00000000000..08aab47036e --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderDstu2_1.java @@ -0,0 +1,128 @@ +package ca.uhn.fhir.jaxrs.server.test; + +import java.util.List; + +import javax.ejb.Stateless; +import javax.interceptor.Interceptors; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.hl7.fhir.dstu2016may.model.*; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.mockito.Mockito; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; +import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.param.StringAndListParam; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; +import ca.uhn.fhir.rest.server.IPagingProvider; + +/** + * A test server delegating each call to a mock + */ +@Path(TestJaxRsMockPatientRestProviderDstu2_1.PATH) +@Stateless +@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_XML_NEW }) +@Interceptors(JaxRsExceptionInterceptor.class) +public class TestJaxRsMockPatientRestProviderDstu2_1 extends AbstractJaxRsResourceProvider { + + static final String PATH = "/Patient"; + + public static final TestJaxRsMockPatientRestProviderDstu2_1 mock = Mockito.mock(TestJaxRsMockPatientRestProviderDstu2_1.class); + + public static final FifoMemoryPagingProvider PAGING_PROVIDER; + + static + { + PAGING_PROVIDER = new FifoMemoryPagingProvider(10); + PAGING_PROVIDER.setDefaultPageSize(10); + PAGING_PROVIDER.setMaximumPageSize(100); + } + + /** + * Constructor + */ + public TestJaxRsMockPatientRestProviderDstu2_1() { + super(FhirContext.forDstu2_1()); + } + + @Search + public List search(@RequiredParam(name = Patient.SP_NAME) final StringParam name, @RequiredParam(name=Patient.SP_ADDRESS) StringAndListParam theAddressParts) { + return mock.search(name, theAddressParts); + } + + @Update + public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient,@ConditionalUrlParam final String theConditional) throws Exception { + return mock.update(theId, patient, theConditional); + } + + @Read + public Patient find(@IdParam final IdType theId) { + return mock.find(theId); + } + + @Read(version = true) + public Patient findHistory(@IdParam final IdType theId) { + return mock.findHistory(theId); + } + + @Create + public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional) + throws Exception { + return mock.create(patient, theConditional); + } + + @Delete + public MethodOutcome delete(@IdParam final IdType theId, @ConditionalUrlParam final String theConditional) { + return mock.delete(theId, theConditional); + } + + @Search(compartmentName = "Condition") + public List searchCompartment(@IdParam IdType thePatientId) { + return mock.searchCompartment(thePatientId); + } + + @GET + @Path("/{id}/$someCustomOperation") + public Response someCustomOperationUsingGet(@PathParam("id") String id, String resource) throws Exception { + return customOperation(resource, RequestTypeEnum.GET, id, "$someCustomOperation", + RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE); + } + + @POST + @Path("/{id}/$someCustomOperation") + public Response someCustomOperationUsingPost(@PathParam("id") String id, String resource) throws Exception { + return customOperation(resource, RequestTypeEnum.POST, id, "$someCustomOperation", + RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE); + } + + @Operation(name = "someCustomOperation", idempotent = true, returnParameters = { + @OperationParam(name = "return", type = StringType.class) }) + public Parameters someCustomOperation(@IdParam IdType myId, @OperationParam(name = "dummy") StringType dummyInput) { + return mock.someCustomOperation(myId, dummyInput); + } + + @Validate() + public MethodOutcome validate(@ResourceParam final Patient resource) { + MethodOutcome mO = new MethodOutcome(); + mO.setOperationOutcome(new OperationOutcome()); + return mO; + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Override + public IPagingProvider getPagingProvider() { + return PAGING_PROVIDER; + } + +} diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java index 9f69509733b..a1fdc04ce16 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java @@ -21,12 +21,9 @@ package org.hl7.fhir.instance.conf; */ import static org.apache.commons.lang3.StringUtils.isNotBlank; -import java.io.IOException; -import java.io.InputStream; import java.text.*; import java.util.*; import java.util.Map.Entry; -import java.util.jar.Manifest; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -71,7 +68,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider myOperationBindingToName; private HashMap> myOperationNameToBindings; private String myPublisher = "Not provided"; - private RestulfulServerConfiguration myServerConfiguration; + private RestulfulServerConfiguration myServerConfiguration; public ServerConformanceProvider(RestfulServer theRestfulServer) { this.myServerConfiguration = theRestfulServer.createConfiguration(); @@ -91,10 +88,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider Date: Sun, 22 Oct 2017 18:43:17 -0500 Subject: [PATCH 3/4] Related to issue #764 - adds support for the R4 FHIR context in AbstractJaxRsConformanceProvider --- hapi-fhir-jaxrsserver-base/pom.xml | 5 + .../AbstractJaxRsConformanceProvider.java | 16 ++- ...xRsConformanceProviderDstu2Hl7OrgTest.java | 6 +- ...ctJaxRsConformanceProviderDstu2_1Test.java | 6 +- ...bstractJaxRsConformanceProviderR4Test.java | 108 +++++++++++++++ ...tJaxRsDummyPatientProviderDstu2Hl7Org.java | 15 ++ .../TestJaxRsDummyPatientProviderDstu2_1.java | 15 ++ .../test/TestJaxRsDummyPatientProviderR4.java | 15 ++ .../TestJaxRsMockPatientRestProviderR4.java | 128 ++++++++++++++++++ 9 files changed, 305 insertions(+), 9 deletions(-) create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderR4Test.java create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2Hl7Org.java create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2_1.java create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderR4.java create mode 100644 hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderR4.java diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 3f728fccc8e..76b6a885650 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -66,6 +66,11 @@ hapi-fhir-structures-dstu3 ${project.version} + + ca.uhn.hapi.fhir + hapi-fhir-structures-r4 + ${project.version} + javax.ws.rs diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java index 6f76e3f6959..1b7f328e6e9 100644 --- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java +++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java @@ -66,6 +66,7 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv private RestulfulServerConfiguration serverConfiguration = new RestulfulServerConfiguration(); /** the conformance. It is created once during startup */ + private org.hl7.fhir.r4.model.CapabilityStatement myR4CapabilityStatement; private CapabilityStatement myDstu3CapabilityStatement; private org.hl7.fhir.dstu2016may.model.Conformance myDstu2_1Conformance; private ca.uhn.fhir.model.dstu2.resource.Conformance myDstu2Conformance; @@ -126,7 +127,11 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv HardcodedServerAddressStrategy hardcodedServerAddressStrategy = new HardcodedServerAddressStrategy(); hardcodedServerAddressStrategy.setValue(getBaseForServer()); serverConfiguration.setServerAddressStrategy(hardcodedServerAddressStrategy); - if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { + if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.R4)) { + org.hl7.fhir.r4.hapi.rest.server.ServerCapabilityStatementProvider serverCapabilityStatementProvider = new org.hl7.fhir.r4.hapi.rest.server.ServerCapabilityStatementProvider(serverConfiguration); + serverCapabilityStatementProvider.initializeOperations(); + myR4CapabilityStatement = serverCapabilityStatementProvider.getServerConformance(null); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { ServerCapabilityStatementProvider serverCapabilityStatementProvider = new ServerCapabilityStatementProvider(serverConfiguration); serverCapabilityStatementProvider.initializeOperations(); myDstu3CapabilityStatement = serverCapabilityStatementProvider.getServerConformance(null); @@ -177,7 +182,10 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv response.addHeader(Constants.HEADER_CORS_ALLOW_ORIGIN, "*"); IBaseResource conformance = null; - if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { + if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.R4)) { + conformance = myR4CapabilityStatement; +// return (Response) response.returnResponse(ParseAction.create(myDstu3CapabilityStatement), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName()); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { conformance = myDstu3CapabilityStatement; // return (Response) response.returnResponse(ParseAction.create(myDstu3CapabilityStatement), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName()); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_1)) { @@ -271,7 +279,9 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv @SuppressWarnings("unchecked") @Override public Class getResourceType() { - if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { + if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.R4)) { + return Class.class.cast(org.hl7.fhir.r4.model.CapabilityStatement.class); + } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { return Class.class.cast(CapabilityStatement.class); } else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2_1)) { return Class.class.cast(org.hl7.fhir.dstu2016may.model.Conformance.class); diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java index 9b3a8ca6fda..eac40d8bce2 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2Hl7OrgTest.java @@ -12,13 +12,13 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.*; +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProviderDstu2Hl7Org; import org.glassfish.jersey.internal.MapPropertiesDelegate; import org.glassfish.jersey.server.ContainerRequest; import org.junit.Before; import org.junit.Test; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider; import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu2Hl7Org; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.server.IResourceProvider; @@ -48,7 +48,7 @@ public class AbstractJaxRsConformanceProviderDstu2Hl7OrgTest { @Test public void testConformance() throws Exception { providers.put(AbstractJaxRsConformanceProvider.class, provider); - providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + providers.put(TestJaxRsDummyPatientProviderDstu2Hl7Org.class, new TestJaxRsDummyPatientProviderDstu2Hl7Org()); Response response = createConformanceProvider(providers).conformance(); System.out.println(response); } @@ -56,7 +56,7 @@ public class AbstractJaxRsConformanceProviderDstu2Hl7OrgTest { @Test public void testConformanceUsingOptions() throws Exception { providers.put(AbstractJaxRsConformanceProvider.class, provider); - providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + providers.put(TestJaxRsDummyPatientProviderDstu2Hl7Org.class, new TestJaxRsDummyPatientProviderDstu2Hl7Org()); Response response = createConformanceProvider(providers).conformanceUsingOptions(); System.out.println(response); } diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java index 60b447e0ab4..115e68d9210 100644 --- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java @@ -12,6 +12,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.*; +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProviderDstu2_1; import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu2_1; import org.glassfish.jersey.internal.MapPropertiesDelegate; import org.glassfish.jersey.server.ContainerRequest; @@ -19,7 +20,6 @@ import org.junit.Before; import org.junit.Test; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.server.IResourceProvider; @@ -48,7 +48,7 @@ public class AbstractJaxRsConformanceProviderDstu2_1Test { @Test public void testConformance() throws Exception { providers.put(AbstractJaxRsConformanceProvider.class, provider); - providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + providers.put(TestJaxRsDummyPatientProviderDstu2_1.class, new TestJaxRsDummyPatientProviderDstu2_1()); Response response = createConformanceProvider(providers).conformance(); System.out.println(response); } @@ -56,7 +56,7 @@ public class AbstractJaxRsConformanceProviderDstu2_1Test { @Test public void testConformanceUsingOptions() throws Exception { providers.put(AbstractJaxRsConformanceProvider.class, provider); - providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider()); + providers.put(TestJaxRsDummyPatientProviderDstu2_1.class, new TestJaxRsDummyPatientProviderDstu2_1()); Response response = createConformanceProvider(providers).conformanceUsingOptions(); System.out.println(response); } diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderR4Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderR4Test.java new file mode 100644 index 00000000000..80c86d751d5 --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderR4Test.java @@ -0,0 +1,108 @@ +package ca.uhn.fhir.jaxrs.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; + +import javax.ws.rs.HttpMethod; +import javax.ws.rs.core.*; + +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProviderR4; +import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderR4; +import org.glassfish.jersey.internal.MapPropertiesDelegate; +import org.glassfish.jersey.server.ContainerRequest; +import org.junit.Before; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.server.IResourceProvider; + +public class AbstractJaxRsConformanceProviderR4Test { + + private static final String BASEURI = "http://basiuri"; + private static final String REQUESTURI = BASEURI + "/metadata"; + AbstractJaxRsConformanceProvider provider; + private ConcurrentHashMap, IResourceProvider> providers; + private ContainerRequest headers; + private MultivaluedHashMap queryParameters; + + @Before + public void setUp() throws Exception { + // headers + headers = new ContainerRequest(new URI(BASEURI), new URI(REQUESTURI), HttpMethod.GET, null, + new MapPropertiesDelegate()); + // uri info + queryParameters = new MultivaluedHashMap(); + + + providers = new ConcurrentHashMap, IResourceProvider>(); + provider = createConformanceProvider(providers); + } + + @Test + public void testConformance() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsDummyPatientProviderR4.class, new TestJaxRsDummyPatientProviderR4()); + Response response = createConformanceProvider(providers).conformance(); + System.out.println(response); + } + + @Test + public void testConformanceUsingOptions() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsDummyPatientProviderR4.class, new TestJaxRsDummyPatientProviderR4()); + Response response = createConformanceProvider(providers).conformanceUsingOptions(); + System.out.println(response); + } + + @Test + public void testConformanceWithMethods() throws Exception { + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsMockPatientRestProviderR4.class, new TestJaxRsMockPatientRestProviderR4()); + Response response = createConformanceProvider(providers).conformance(); + assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus()); + assertTrue(response.getEntity().toString().contains("\"type\": \"Patient\"")); + assertTrue(response.getEntity().toString().contains("\"someCustomOperation")); + System.out.println(response); + System.out.println(response.getEntity()); + } + + @Test + public void testConformanceInXml() throws Exception { + queryParameters.put(Constants.PARAM_FORMAT, Arrays.asList(Constants.CT_XML)); + providers.put(AbstractJaxRsConformanceProvider.class, provider); + providers.put(TestJaxRsMockPatientRestProviderR4.class, new TestJaxRsMockPatientRestProviderR4()); + Response response = createConformanceProvider(providers).conformance(); + assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus()); + System.out.println(response.getEntity()); + assertTrue(response.getEntity().toString().contains(" ")); + assertTrue(response.getEntity().toString().contains("\"someCustomOperation")); + System.out.println(response.getEntity()); + } + + private AbstractJaxRsConformanceProvider createConformanceProvider(final ConcurrentHashMap, IResourceProvider> providers) + throws Exception { + AbstractJaxRsConformanceProvider result = new AbstractJaxRsConformanceProvider(FhirContext.forR4(), null, null, null) { + @Override + protected ConcurrentHashMap, IResourceProvider> getProviders() { + return providers; + } + }; + // mocks + UriInfo uriInfo = mock(UriInfo.class); + when(uriInfo.getQueryParameters()).thenReturn(queryParameters); + when(uriInfo.getBaseUri()).thenReturn(new URI(BASEURI)); + when(uriInfo.getRequestUri()).thenReturn(new URI(BASEURI + "/foo")); + result.setUriInfo(uriInfo); + result.setHeaders(headers); + result.setUpPostConstruct(); + return result; + } + +} diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2Hl7Org.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2Hl7Org.java new file mode 100644 index 00000000000..c41b8611024 --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2Hl7Org.java @@ -0,0 +1,15 @@ +package ca.uhn.fhir.jaxrs.server.test; + +import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; +import org.hl7.fhir.instance.model.Patient; + +/** + * A dummy patient provider exposing no methods + */ +public class TestJaxRsDummyPatientProviderDstu2Hl7Org extends AbstractJaxRsResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } +} diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2_1.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2_1.java new file mode 100644 index 00000000000..420aa5cee48 --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderDstu2_1.java @@ -0,0 +1,15 @@ +package ca.uhn.fhir.jaxrs.server.test; + +import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; +import org.hl7.fhir.dstu2016may.model.Patient; + +/** + * A dummy patient provider exposing no methods + */ +public class TestJaxRsDummyPatientProviderDstu2_1 extends AbstractJaxRsResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } +} diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderR4.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderR4.java new file mode 100644 index 00000000000..1c3f91f4c1d --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsDummyPatientProviderR4.java @@ -0,0 +1,15 @@ +package ca.uhn.fhir.jaxrs.server.test; + +import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; +import org.hl7.fhir.r4.model.Patient; + +/** + * A dummy patient provider exposing no methods + */ +public class TestJaxRsDummyPatientProviderR4 extends AbstractJaxRsResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } +} diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderR4.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderR4.java new file mode 100644 index 00000000000..0b34916b778 --- /dev/null +++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsMockPatientRestProviderR4.java @@ -0,0 +1,128 @@ +package ca.uhn.fhir.jaxrs.server.test; + +import java.util.List; + +import javax.ejb.Stateless; +import javax.interceptor.Interceptors; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.mockito.Mockito; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider; +import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.param.StringAndListParam; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; +import ca.uhn.fhir.rest.server.IPagingProvider; + +/** + * A test server delegating each call to a mock + */ +@Path(TestJaxRsMockPatientRestProviderR4.PATH) +@Stateless +@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML, Constants.CT_FHIR_JSON_NEW, Constants.CT_FHIR_XML_NEW }) +@Interceptors(JaxRsExceptionInterceptor.class) +public class TestJaxRsMockPatientRestProviderR4 extends AbstractJaxRsResourceProvider { + + static final String PATH = "/Patient"; + + public static final TestJaxRsMockPatientRestProviderR4 mock = Mockito.mock(TestJaxRsMockPatientRestProviderR4.class); + + public static final FifoMemoryPagingProvider PAGING_PROVIDER; + + static + { + PAGING_PROVIDER = new FifoMemoryPagingProvider(10); + PAGING_PROVIDER.setDefaultPageSize(10); + PAGING_PROVIDER.setMaximumPageSize(100); + } + + /** + * Constructor + */ + public TestJaxRsMockPatientRestProviderR4() { + super(FhirContext.forR4()); + } + + @Search + public List search(@RequiredParam(name = Patient.SP_NAME) final StringParam name, @RequiredParam(name=Patient.SP_ADDRESS) StringAndListParam theAddressParts) { + return mock.search(name, theAddressParts); + } + + @Update + public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient,@ConditionalUrlParam final String theConditional) throws Exception { + return mock.update(theId, patient, theConditional); + } + + @Read + public Patient find(@IdParam final IdType theId) { + return mock.find(theId); + } + + @Read(version = true) + public Patient findHistory(@IdParam final IdType theId) { + return mock.findHistory(theId); + } + + @Create + public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional) + throws Exception { + return mock.create(patient, theConditional); + } + + @Delete + public MethodOutcome delete(@IdParam final IdType theId, @ConditionalUrlParam final String theConditional) { + return mock.delete(theId, theConditional); + } + + @Search(compartmentName = "Condition") + public List searchCompartment(@IdParam IdType thePatientId) { + return mock.searchCompartment(thePatientId); + } + + @GET + @Path("/{id}/$someCustomOperation") + public Response someCustomOperationUsingGet(@PathParam("id") String id, String resource) throws Exception { + return customOperation(resource, RequestTypeEnum.GET, id, "$someCustomOperation", + RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE); + } + + @POST + @Path("/{id}/$someCustomOperation") + public Response someCustomOperationUsingPost(@PathParam("id") String id, String resource) throws Exception { + return customOperation(resource, RequestTypeEnum.POST, id, "$someCustomOperation", + RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE); + } + + @Operation(name = "someCustomOperation", idempotent = true, returnParameters = { + @OperationParam(name = "return", type = StringType.class) }) + public Parameters someCustomOperation(@IdParam IdType myId, @OperationParam(name = "dummy") StringType dummyInput) { + return mock.someCustomOperation(myId, dummyInput); + } + + @Validate() + public MethodOutcome validate(@ResourceParam final Patient resource) { + MethodOutcome mO = new MethodOutcome(); + mO.setOperationOutcome(new OperationOutcome()); + return mO; + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Override + public IPagingProvider getPagingProvider() { + return PAGING_PROVIDER; + } + +} From d7f13432dfc04b18e06fe93ab695fdb396baea3c Mon Sep 17 00:00:00 2001 From: Clayton Bodendein Date: Mon, 30 Oct 2017 12:48:23 -0500 Subject: [PATCH 4/4] Related to issue #764, changed the private conformanceDate method in DSTU2_HL7ORG's ServerConformanceProvider to be consistent with the ServerConformanceProvider in other FHIR contexts --- .../instance/conf/ServerConformanceProvider.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java index a1fdc04ce16..a410287cfda 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/conf/ServerConformanceProvider.java @@ -29,6 +29,7 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import ca.uhn.fhir.context.FhirVersionEnum; +import ca.uhn.fhir.parser.DataFormatException; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.*; import org.hl7.fhir.instance.model.Conformance.*; @@ -165,7 +166,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider