add unit tests
This commit is contained in:
parent
1afaea81d6
commit
9f7a104315
|
@ -39,229 +39,58 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<!-- conformance profile -->
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
|
||||||
<version>1.3-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||||
<version>1.3-SNAPSHOT</version>
|
<version>1.3-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
|
||||||
<version>1.3-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
|
||||||
<version>1.3-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- UNKNOWN -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.thymeleaf</groupId>
|
|
||||||
<artifactId>thymeleaf</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.phloc</groupId>
|
|
||||||
<artifactId>phloc-schematron</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.phloc</groupId>
|
|
||||||
<artifactId>phloc-commons</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- PREVIOUS TESTING
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-servlets</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-servlet</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-server</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-util</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-webapp</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
<!-- own api -->
|
|
||||||
<!--dependency>
|
|
||||||
<groupId>org.jboss.resteasy</groupId>
|
|
||||||
<artifactId>resteasy-jaxrs</artifactId>
|
|
||||||
<version>2.2.1.GA</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.ws.rs</groupId>
|
<groupId>javax.ws.rs</groupId>
|
||||||
<artifactId>javax.ws.rs-api</artifactId>
|
<artifactId>javax.ws.rs-api</artifactId>
|
||||||
<version>2.0</version>
|
<version>2.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.ejb</groupId>
|
<groupId>javax.ejb</groupId>
|
||||||
<artifactId>ejb-api</artifactId>
|
<artifactId>ejb-api</artifactId>
|
||||||
<version>3.0</version>
|
<version>3.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Jetty -->
|
|
||||||
<!-- http://stackoverflow.com/questions/10048004/integrating-jetty-with-jax-rs-jersey -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-server</artifactId>
|
<artifactId>jetty-server</artifactId>
|
||||||
|
<version>${jetty_version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-util</artifactId>
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
<version>${jetty_version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.glassfish.jersey.core</groupId>
|
||||||
<artifactId>jetty-webapp</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Jersey (JAX-RS) -->
|
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.jersey</groupId>
|
|
||||||
<artifactId>jersey-server</artifactId>
|
<artifactId>jersey-server</artifactId>
|
||||||
</dependency>
|
<version>${jersey_version}</version>
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.jersey.contribs</groupId>
|
|
||||||
<artifactId>jersey-spring</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.ws.rs</groupId>
|
|
||||||
<artifactId>jsr311-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.jersey</groupId>
|
|
||||||
<artifactId>jersey-test-framework</artifactId>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.grizzly</groupId>
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
<artifactId>grizzly-servlet-webserver</artifactId>
|
<artifactId>jersey-container-servlet-core</artifactId>
|
||||||
|
<version>${jersey_version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
|
<artifactId>jersey-container-jetty-http</artifactId>
|
||||||
|
<version>${jersey_version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<!--
|
|
||||||
<build>
|
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<skipDeploy>true</skipDeploy>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-tinder-plugin</artifactId>
|
|
||||||
<version>1.3-SNAPSHOT</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>build_dstu1</id>
|
|
||||||
<goals>
|
|
||||||
<goal>generate-jparest-server</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<version>dstu</version>
|
|
||||||
<packageBase>ca.uhn.fhir.jpa.rp.dstu</packageBase>
|
|
||||||
<targetResourceSpringBeansFile>hapi-fhir-server-resourceproviders-dstu1.xml</targetResourceSpringBeansFile>
|
|
||||||
<baseResourceNames/>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>build_dstu2</id>
|
|
||||||
<goals>
|
|
||||||
<goal>generate-jparest-server</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<version>dstu2</version>
|
|
||||||
<packageBase>ca.uhn.fhir.jpa.rp.dstu2</packageBase>
|
|
||||||
<targetResourceSpringBeansFile>hapi-fhir-server-resourceproviders-dstu2.xml</targetResourceSpringBeansFile>
|
|
||||||
<baseResourceNames/>
|
|
||||||
<excludeResourceNames>
|
|
||||||
<excludeResourceName>OperationDefinition</excludeResourceName>
|
|
||||||
<excludeResourceName>OperationOutcome</excludeResourceName>
|
|
||||||
</excludeResourceNames>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
|
||||||
<version>1.3-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
|
||||||
<version>1.3-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>${basedir}/src/main/resources</directory>
|
|
||||||
</resource>
|
|
||||||
<resource>
|
|
||||||
<directory>${basedir}/target/generated-sources/tinder</directory>
|
|
||||||
</resource>
|
|
||||||
<resource>
|
|
||||||
<directory>${basedir}/target/generated-resources/tinder</directory>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</build>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<reporting>
|
<reporting>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -8,7 +8,7 @@ import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequestDetails;
|
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
@ -30,18 +30,19 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
|
||||||
public static FhirContext CTX = FhirContext.forDstu2();
|
public static FhirContext CTX = FhirContext.forDstu2();
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
private UriInfo info;
|
private UriInfo theUriInfo;
|
||||||
@Context
|
@Context
|
||||||
private HttpHeaders headers;
|
private HttpHeaders theHeaders;
|
||||||
|
|
||||||
public FhirContext getFhirContext() {
|
@Override
|
||||||
|
public FhirContext getFhirContext() {
|
||||||
return CTX;
|
return CTX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* param and query methods
|
* param and query methods
|
||||||
*/
|
*/
|
||||||
protected HashMap<String, String[]> getQueryMap() {
|
public HashMap<String, String[]> getQueryMap() {
|
||||||
MultivaluedMap<String, String> queryParameters = getInfo().getQueryParameters();
|
MultivaluedMap<String, String> queryParameters = getInfo().getQueryParameters();
|
||||||
HashMap<String, String[]> params = new HashMap<String, String[]>();
|
HashMap<String, String[]> params = new HashMap<String, String[]>();
|
||||||
for (String key : queryParameters.keySet()) {
|
for (String key : queryParameters.keySet()) {
|
||||||
|
@ -56,48 +57,42 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
|
||||||
return addressStrategy;
|
return addressStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getBaseUri() {
|
public String getBaseUri() {
|
||||||
return getInfo().getBaseUri().toASCIIString();
|
return getInfo().getBaseUri().toASCIIString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PARSING METHODS
|
* PARSING METHODS
|
||||||
*/
|
*/
|
||||||
public IParser getParser(JaxRsRequestDetails theRequestDetails) {
|
public IParser getParser(JaxRsRequest theRequestDetails) {
|
||||||
return RestfulServerUtils.getNewParser(getFhirContext(), theRequestDetails);
|
return RestfulServerUtils.getNewParser(getFhirContext(), theRequestDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JaxRsRequestDetails createRequestDetails(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation) {
|
protected JaxRsRequest createRequestDetails(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation) {
|
||||||
JaxRsRequestDetails theRequest = new JaxRsRequestDetails(headers, resourceString);
|
return new JaxRsRequest(this, resourceString, requestType, restOperation);
|
||||||
theRequest.setFhirServerBase(getBaseUri());
|
|
||||||
theRequest.setRestOperationType(restOperation);
|
|
||||||
theRequest.setServer(this);
|
|
||||||
theRequest.setParameters(getQueryMap());
|
|
||||||
theRequest.setRequestType(requestType);
|
|
||||||
return theRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the info
|
* Get the info
|
||||||
* @return the info
|
* @return the info
|
||||||
*/
|
*/
|
||||||
public UriInfo getInfo() {
|
public UriInfo getInfo() {
|
||||||
return info;
|
return theUriInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the info
|
* Get the headers
|
||||||
* @param info the info to set
|
* @return the headers
|
||||||
*/
|
*/
|
||||||
public void setInfo(UriInfo info) {
|
public HttpHeaders getHeaders() {
|
||||||
this.info = info;
|
return theHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DEFAULT VALUES
|
* DEFAULT VALUES
|
||||||
*/
|
*/
|
||||||
public EncodingEnum getDefaultResponseEncoding() {
|
@Override
|
||||||
|
public EncodingEnum getDefaultResponseEncoding() {
|
||||||
return EncodingEnum.JSON;
|
return EncodingEnum.JSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,5 +114,6 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
|
||||||
@Override
|
@Override
|
||||||
public boolean isUseBrowserFriendlyContentTypes() {
|
public boolean isUseBrowserFriendlyContentTypes() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package ca.uhn.fhir.jaxrs.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.interceptor.Interceptors;
|
import javax.interceptor.Interceptors;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -18,7 +20,7 @@ import javax.ws.rs.core.Response;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequestDetails;
|
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||||
import ca.uhn.fhir.jaxrs.server.util.MethodBindings;
|
import ca.uhn.fhir.jaxrs.server.util.MethodBindings;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
@ -26,9 +28,12 @@ import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,22 +45,18 @@ import ca.uhn.fhir.util.UrlUtil;
|
||||||
@Consumes({MediaType.APPLICATION_FORM_URLENCODED,MediaType.APPLICATION_JSON, "application/json+fhir", "application/xml+fhir"})
|
@Consumes({MediaType.APPLICATION_FORM_URLENCODED,MediaType.APPLICATION_JSON, "application/json+fhir", "application/xml+fhir"})
|
||||||
public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends AbstractJaxRsProvider implements IJaxRsResourceProvider<R> {
|
public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends AbstractJaxRsProvider implements IJaxRsResourceProvider<R> {
|
||||||
|
|
||||||
private static MethodBindings bindings;
|
private final MethodBindings bindings;
|
||||||
|
|
||||||
|
protected AbstractJaxRsResourceProvider() {
|
||||||
|
bindings = MethodBindings.getMethodBindings(this, getClass());
|
||||||
|
}
|
||||||
|
|
||||||
public AbstractJaxRsResourceProvider(Class<?> subclass) {
|
protected AbstractJaxRsResourceProvider(Class<?> subclass) {
|
||||||
initBindings(subclass);
|
bindings = MethodBindings.getMethodBindings(this, subclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initBindings(Class<?> subclass) {
|
|
||||||
if(bindings == null) {
|
|
||||||
MethodBindings methodBindings = new MethodBindings();
|
|
||||||
methodBindings.findMethods(this, subclass, getFhirContext());
|
|
||||||
bindings = methodBindings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getBaseUri() {
|
public String getBaseUri() {
|
||||||
try {
|
try {
|
||||||
return new URL(getInfo().getBaseUri().toURL(), getResourceType().getSimpleName()).toExternalForm();
|
return new URL(getInfo().getBaseUri().toURL(), getResourceType().getSimpleName()).toExternalForm();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
@ -115,7 +116,7 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
||||||
|
|
||||||
protected Response customOperation(final String resource, RequestTypeEnum requestType, String id, String operationName, RestOperationTypeEnum operationType)
|
protected Response customOperation(final String resource, RequestTypeEnum requestType, String id, String operationName, RestOperationTypeEnum operationType)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return executeMethod(resource, requestType, operationType, id, bindings.getBinding(operationType, operationName));
|
return executeMethod(resource, requestType, operationType, id, getBindings().getBinding(operationType, operationName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@ -124,7 +125,7 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
||||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||||
public Response findHistory(@PathParam("id") final String id, @PathParam("version") final String versionString)
|
public Response findHistory(@PathParam("id") final String id, @PathParam("version") final String versionString)
|
||||||
throws BaseServerResponseException, IOException {
|
throws BaseServerResponseException, IOException {
|
||||||
BaseMethodBinding<?> method = bindings.getBinding(RestOperationTypeEnum.VREAD);
|
BaseMethodBinding<?> method = getBindings().getBinding(RestOperationTypeEnum.VREAD);
|
||||||
final RequestDetails theRequest = createRequestDetails(null, RequestTypeEnum.GET, RestOperationTypeEnum.VREAD);
|
final RequestDetails theRequest = createRequestDetails(null, RequestTypeEnum.GET, RestOperationTypeEnum.VREAD);
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
throw new InvalidRequestException("Don't know how to handle request path: " + getInfo().getRequestUri().toASCIIString());
|
throw new InvalidRequestException("Don't know how to handle request path: " + getInfo().getRequestUri().toASCIIString());
|
||||||
|
@ -138,7 +139,7 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
||||||
@Path("/{id}/{compartment}")
|
@Path("/{id}/{compartment}")
|
||||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||||
public Response findCompartment(@PathParam("id") final String id, @PathParam("compartment") final String compartment) throws BaseServerResponseException, IOException {
|
public Response findCompartment(@PathParam("id") final String id, @PathParam("compartment") final String compartment) throws BaseServerResponseException, IOException {
|
||||||
BaseMethodBinding<?> method = bindings.getBinding(RestOperationTypeEnum.SEARCH_TYPE, compartment);
|
BaseMethodBinding<?> method = getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE, compartment);
|
||||||
final RequestDetails theRequest = createRequestDetails(null, RequestTypeEnum.GET, RestOperationTypeEnum.VREAD);
|
final RequestDetails theRequest = createRequestDetails(null, RequestTypeEnum.GET, RestOperationTypeEnum.VREAD);
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
throw new InvalidRequestException("Don't know how to handle request path: " + getInfo().getRequestUri().toASCIIString());
|
throw new InvalidRequestException("Don't know how to handle request path: " + getInfo().getRequestUri().toASCIIString());
|
||||||
|
@ -150,7 +151,7 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
||||||
|
|
||||||
private <T extends BaseMethodBinding<?>> Response executeMethod(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation, String id)
|
private <T extends BaseMethodBinding<?>> Response executeMethod(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation, String id)
|
||||||
throws BaseServerResponseException, IOException {
|
throws BaseServerResponseException, IOException {
|
||||||
BaseMethodBinding<?> method = bindings.getBinding(restOperation);
|
BaseMethodBinding<?> method = getBindings().getBinding(restOperation);
|
||||||
return executeMethod(resourceString, requestType, restOperation, id, method);
|
return executeMethod(resourceString, requestType, restOperation, id, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +163,8 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected JaxRsRequestDetails createRequestDetails(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation, String id) {
|
protected JaxRsRequest createRequestDetails(final String resourceString, RequestTypeEnum requestType, RestOperationTypeEnum restOperation, String id) {
|
||||||
JaxRsRequestDetails theRequest = super.createRequestDetails(resourceString, requestType, restOperation);
|
JaxRsRequest theRequest = super.createRequestDetails(resourceString, requestType, restOperation);
|
||||||
theRequest.setId(StringUtils.isBlank(id) ? null : new IdDt(getResourceType().getName(), UrlUtil.unescape(id)));
|
theRequest.setId(StringUtils.isBlank(id) ? null : new IdDt(getResourceType().getName(), UrlUtil.unescape(id)));
|
||||||
if(restOperation == RestOperationTypeEnum.UPDATE) {
|
if(restOperation == RestOperationTypeEnum.UPDATE) {
|
||||||
String contentLocation = theRequest.getHeader(Constants.HEADER_CONTENT_LOCATION);
|
String contentLocation = theRequest.getHeader(Constants.HEADER_CONTENT_LOCATION);
|
||||||
|
@ -173,8 +174,27 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
||||||
}
|
}
|
||||||
return theRequest;
|
return theRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IServerInterceptor> getInterceptors() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPagingProvider getPagingProvider() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BundleInclusionRule getBundleInclusionRule() {
|
||||||
|
return BundleInclusionRule.BASED_ON_INCLUDES;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract Class<R> getResourceType();
|
public abstract Class<R> getResourceType();
|
||||||
|
|
||||||
|
public MethodBindings getBindings() {
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ import java.io.IOException;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequestDetails;
|
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.IRestfulServer;
|
import ca.uhn.fhir.rest.server.IRestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
|
|
||||||
public interface IJaxRsResourceProvider<T> extends IRestfulServer<JaxRsRequestDetails>, IResourceProvider {
|
public interface IJaxRsResourceProvider<T> extends IRestfulServer<JaxRsRequest>, IResourceProvider {
|
||||||
|
|
||||||
Response search()
|
Response search()
|
||||||
throws Exception;
|
throws Exception;
|
||||||
|
|
|
@ -9,17 +9,34 @@ import java.util.List;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsProvider;
|
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsProvider;
|
||||||
import ca.uhn.fhir.jaxrs.server.JaxRsResponse;
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.param.ResourceParameter;
|
import ca.uhn.fhir.rest.param.ResourceParameter;
|
||||||
|
import ca.uhn.fhir.rest.server.IRestfulResponse;
|
||||||
|
|
||||||
public class JaxRsRequestDetails extends RequestDetails {
|
public class JaxRsRequest extends RequestDetails {
|
||||||
|
|
||||||
private String theResourceString;
|
private String theResourceString;
|
||||||
private HttpHeaders headers;
|
private HttpHeaders headers;
|
||||||
private AbstractJaxRsProvider myServer;
|
private AbstractJaxRsProvider myServer;
|
||||||
|
|
||||||
public AbstractJaxRsProvider getServer() {
|
public JaxRsRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public JaxRsRequest(AbstractJaxRsProvider server, String resourceString,
|
||||||
|
RequestTypeEnum requestType, RestOperationTypeEnum restOperation) {
|
||||||
|
this.headers = server.getHeaders();
|
||||||
|
this.theResourceString = resourceString;
|
||||||
|
this.setRestOperationType(restOperation);
|
||||||
|
setServer(server);
|
||||||
|
setFhirServerBase(server.getBaseUri());
|
||||||
|
setParameters(server.getQueryMap());
|
||||||
|
setRequestType(requestType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractJaxRsProvider getServer() {
|
||||||
return myServer;
|
return myServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,16 +44,10 @@ public class JaxRsRequestDetails extends RequestDetails {
|
||||||
this.myServer = theServer;
|
this.myServer = theServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JaxRsRequestDetails(HttpHeaders headers, String resourceString) {
|
|
||||||
this.headers = headers;
|
|
||||||
this.theResourceString = resourceString;
|
|
||||||
setResponse(new JaxRsResponse(resourceString, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHeader(String headerIfNoneExist) {
|
public String getHeader(String headerKey) {
|
||||||
List<String> requestHeader = headers.getRequestHeader(headerIfNoneExist);
|
List<String> requestHeader = getHeaders(headerKey);
|
||||||
return (requestHeader == null || requestHeader.size() == 0) ? null : requestHeader.get(0);
|
return requestHeader.isEmpty() ? null : requestHeader.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,14 +66,24 @@ public class JaxRsRequestDetails extends RequestDetails {
|
||||||
return theResourceString.getBytes(ResourceParameter.determineRequestCharset(this));
|
return theResourceString.getBytes(ResourceParameter.determineRequestCharset(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IRestfulResponse getResponse() {
|
||||||
|
if(super.getResponse() == null) {
|
||||||
|
setResponse(new JaxRsResponse(this));
|
||||||
|
}
|
||||||
|
return super.getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Reader getReader()
|
public Reader getReader()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
// not yet implemented
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getInputStream() {
|
public InputStream getInputStream() {
|
||||||
|
// not yet implemented
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package ca.uhn.fhir.jaxrs.server;
|
package ca.uhn.fhir.jaxrs.server.util;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -15,7 +15,6 @@ import javax.ws.rs.core.Response.ResponseBuilder;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||||
|
|
||||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequestDetails;
|
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.method.ParseAction;
|
import ca.uhn.fhir.rest.method.ParseAction;
|
||||||
|
@ -24,9 +23,9 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.RestfulResponse;
|
import ca.uhn.fhir.rest.server.RestfulResponse;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||||
|
|
||||||
public class JaxRsResponse extends RestfulResponse<JaxRsRequestDetails> {
|
public class JaxRsResponse extends RestfulResponse<JaxRsRequest> {
|
||||||
|
|
||||||
public JaxRsResponse(String resourceString, JaxRsRequestDetails jaxRsRequestDetails) {
|
public JaxRsResponse(JaxRsRequest jaxRsRequestDetails) {
|
||||||
super(jaxRsRequestDetails);
|
super(jaxRsRequestDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +42,13 @@ public class JaxRsResponse extends RestfulResponse<JaxRsRequestDetails> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response sendWriterResponse(int status, String contentType, String charset, Writer writer) {
|
public Response sendWriterResponse(int status, String contentType, String charset, Writer writer) {
|
||||||
return Response.status(status)/*.header(HttpHeaders.CONTENT_TYPE, charset)*/.header(Constants.HEADER_CONTENT_TYPE, contentType).entity(writer.toString()).build();
|
Object entity = writer instanceof StringWriter ? writer.toString() : writer;
|
||||||
|
return buildResponse(status)/*.header(HttpHeaders.CONTENT_TYPE, charset)*/.header(Constants.HEADER_CONTENT_TYPE, contentType).entity(entity).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object sendAttachmentResponse(IBaseBinary bin, int statusCode, String contentType) throws IOException {
|
public Response sendAttachmentResponse(IBaseBinary bin, int statusCode, String contentType) throws IOException {
|
||||||
ResponseBuilder response = Response.status(statusCode);
|
ResponseBuilder response = buildResponse(statusCode);
|
||||||
for (Entry<String, String> header : getHeaders().entrySet()) {
|
|
||||||
response.header(header.getKey(), header.getValue());
|
|
||||||
}
|
|
||||||
if (bin.getContent() != null && bin.getContent().length > 0) {
|
if (bin.getContent() != null && bin.getContent().length > 0) {
|
||||||
response.header(Constants.HEADER_CONTENT_TYPE, contentType).entity(bin.getContent());
|
response.header(Constants.HEADER_CONTENT_TYPE, contentType).entity(bin.getContent());
|
||||||
}
|
}
|
||||||
|
@ -59,20 +56,28 @@ public class JaxRsResponse extends RestfulResponse<JaxRsRequestDetails> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object returnResponse(ParseAction<?> outcome, int operationStatus, boolean allowPrefer, MethodOutcome response,
|
public Response returnResponse(ParseAction<?> outcome, int operationStatus, boolean allowPrefer, MethodOutcome response,
|
||||||
String resourceName)
|
String resourceName)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Writer writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
IParser parser = RestfulServerUtils.getNewParser(getRequestDetails().getServer().getFhirContext(), getRequestDetails());
|
|
||||||
if(outcome != null) {
|
if(outcome != null) {
|
||||||
|
IParser parser = RestfulServerUtils.getNewParser(getRequestDetails().getServer().getFhirContext(), getRequestDetails());
|
||||||
outcome.execute(parser, writer);
|
outcome.execute(parser, writer);
|
||||||
}
|
}
|
||||||
return Response.status(operationStatus).header(Constants.HEADER_CONTENT_TYPE, getParserType()).entity(writer.toString()).build();
|
return sendWriterResponse(operationStatus, getParserType(), null, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getParserType() {
|
protected String getParserType() {
|
||||||
EncodingEnum encodingEnum = RestfulServerUtils.determineResponseEncodingWithDefault(getRequestDetails());
|
EncodingEnum encodingEnum = RestfulServerUtils.determineResponseEncodingWithDefault(getRequestDetails());
|
||||||
return encodingEnum == EncodingEnum.JSON ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML;
|
return encodingEnum == EncodingEnum.JSON ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ResponseBuilder buildResponse(int statusCode) {
|
||||||
|
ResponseBuilder response = Response.status(statusCode);
|
||||||
|
for (Entry<String, String> header : getHeaders().entrySet()) {
|
||||||
|
response.header(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,7 +5,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||||
import ca.uhn.fhir.rest.annotation.Search;
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
@ -14,55 +13,73 @@ import ca.uhn.fhir.rest.method.OperationMethodBinding;
|
||||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||||
import ca.uhn.fhir.util.ReflectionUtil;
|
import ca.uhn.fhir.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Peter Van Houte
|
||||||
|
* Class that contains the method bindings defined by a ResourceProvider
|
||||||
|
*/
|
||||||
public class MethodBindings {
|
public class MethodBindings {
|
||||||
|
|
||||||
/** ALL METHOD BINDINGS */
|
/** Static collection of bindings mapped to a class*/
|
||||||
ConcurrentHashMap<RestOperationTypeEnum, ConcurrentHashMap<String, BaseMethodBinding<?>>> allBindings = new ConcurrentHashMap<RestOperationTypeEnum, ConcurrentHashMap<String,BaseMethodBinding<?>>>();
|
private static final ConcurrentHashMap<Class<?>, MethodBindings> classBindings = new ConcurrentHashMap<Class<?>, MethodBindings>();
|
||||||
|
/** Static collection of operationBindings mapped to a class */
|
||||||
|
private ConcurrentHashMap<RestOperationTypeEnum, ConcurrentHashMap<String, BaseMethodBinding<?>>> operationBindings = new ConcurrentHashMap<RestOperationTypeEnum, ConcurrentHashMap<String,BaseMethodBinding<?>>>();
|
||||||
|
|
||||||
public <T extends AbstractJaxRsResourceProvider<?>> void findMethods(T theProvider, Class<?> subclass, FhirContext fhirContext) {
|
public <T extends AbstractJaxRsResourceProvider<?>> MethodBindings(T theProvider, Class<?> clazz) {
|
||||||
for (final Method m : ReflectionUtil.getDeclaredMethods(subclass)) {
|
for (final Method m : ReflectionUtil.getDeclaredMethods(clazz)) {
|
||||||
final BaseMethodBinding<?> foundMethodBinding = BaseMethodBinding.bindMethod(m, fhirContext, theProvider);
|
final BaseMethodBinding<?> foundMethodBinding = BaseMethodBinding.bindMethod(m, theProvider.getFhirContext(), theProvider);
|
||||||
if (foundMethodBinding == null) {
|
if (foundMethodBinding == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ConcurrentHashMap<String, BaseMethodBinding<?>> map = getAllBindingsMap(foundMethodBinding.getRestOperationType());
|
String bindingKey = getBindingKey(foundMethodBinding);
|
||||||
if (foundMethodBinding instanceof OperationMethodBinding) {
|
putIfAbsent(bindingKey, foundMethodBinding);
|
||||||
OperationMethodBinding binding = (OperationMethodBinding) foundMethodBinding;
|
|
||||||
putIfAbsent(map, binding.getName(), binding);
|
|
||||||
} else if (foundMethodBinding instanceof SearchMethodBinding) {
|
|
||||||
Search search = m.getAnnotation(Search.class);
|
|
||||||
String compartmentName = StringUtils.defaultIfBlank(search.compartmentName(), "");
|
|
||||||
putIfAbsent(map, compartmentName, foundMethodBinding);
|
|
||||||
} else {
|
|
||||||
putIfAbsent(map, "", foundMethodBinding);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putIfAbsent(ConcurrentHashMap<String, BaseMethodBinding<?>> map, String key, BaseMethodBinding binding) {
|
private String getBindingKey(final BaseMethodBinding<?> foundMethodBinding) {
|
||||||
|
if (foundMethodBinding instanceof OperationMethodBinding) {
|
||||||
|
return ((OperationMethodBinding) foundMethodBinding).getName();
|
||||||
|
} else if (foundMethodBinding instanceof SearchMethodBinding) {
|
||||||
|
Search search = foundMethodBinding.getMethod().getAnnotation(Search.class);
|
||||||
|
return search.compartmentName();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putIfAbsent(String key, BaseMethodBinding<?> binding) {
|
||||||
|
operationBindings.putIfAbsent(binding.getRestOperationType(), new ConcurrentHashMap<String, BaseMethodBinding<?>>());
|
||||||
|
ConcurrentHashMap<String, BaseMethodBinding<?>> map = operationBindings.get(binding.getRestOperationType());
|
||||||
if (map.containsKey(key)) {
|
if (map.containsKey(key)) {
|
||||||
throw new IllegalArgumentException("Multiple Search Method Bindings Found : " + map.get(key) + " -- " + binding.getMethod());
|
throw new IllegalArgumentException("Multiple Search Method Bindings Found : " + map.get(key) + " -- " + binding.getMethod());
|
||||||
}
|
}
|
||||||
map.put(key, binding);
|
map.put(key, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConcurrentHashMap<String,BaseMethodBinding<?>> getAllBindingsMap(final RestOperationTypeEnum restOperationTypeEnum) {
|
public BaseMethodBinding<?> getBinding(RestOperationTypeEnum operationType) {
|
||||||
allBindings.putIfAbsent(restOperationTypeEnum, new ConcurrentHashMap<String, BaseMethodBinding<?>>());
|
return getBinding(operationType, "");
|
||||||
return allBindings.get(restOperationTypeEnum);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public BaseMethodBinding<?> getBinding(RestOperationTypeEnum operationType, String qualifier) {
|
public BaseMethodBinding<?> getBinding(RestOperationTypeEnum operationType, String qualifier) {
|
||||||
String nonEmptyQualifier = StringUtils.defaultIfBlank(qualifier, "");
|
String nonEmptyQualifier = StringUtils.defaultIfBlank(qualifier, "");
|
||||||
ConcurrentHashMap<String, BaseMethodBinding<?>> map = getAllBindingsMap(operationType);
|
ConcurrentHashMap<String, BaseMethodBinding<?>> map = operationBindings.get(operationType);
|
||||||
if(!map.containsKey(nonEmptyQualifier)) {
|
if(map == null || !map.containsKey(nonEmptyQualifier)) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
} else {
|
} else {
|
||||||
return map.get(nonEmptyQualifier);
|
return map.get(nonEmptyQualifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseMethodBinding<?> getBinding(RestOperationTypeEnum operationType) {
|
public static <T extends AbstractJaxRsResourceProvider<?>> MethodBindings getMethodBindings(T theProvider, Class<?> clazz) {
|
||||||
return getBinding(operationType, "");
|
if(!getClassBindings().containsKey(clazz)) {
|
||||||
}
|
MethodBindings foundBindings = new MethodBindings(theProvider, clazz);
|
||||||
|
getClassBindings().putIfAbsent(clazz, foundBindings);
|
||||||
|
}
|
||||||
|
return getClassBindings().get(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConcurrentHashMap<Class<?>, MethodBindings> getClassBindings() {
|
||||||
|
return classBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,318 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.jaxrs.server.example.JaxRsPatientRestProvider;
|
||||||
|
import ca.uhn.fhir.jaxrs.server.example.RandomServerPortProvider;
|
||||||
|
import ca.uhn.fhir.model.api.BundleEntry;
|
||||||
|
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.DateDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||||
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
|
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||||
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.method.SearchStyleEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
|
|
||||||
|
public class JaxRsPatientProviderTest {
|
||||||
|
|
||||||
|
private static IGenericClient client;
|
||||||
|
private static final FhirContext ourCtx = FhirContext.forDstu2();
|
||||||
|
private static final String PATIENT_NAME = "Van Houte";
|
||||||
|
private static int ourPort;
|
||||||
|
private static Server jettyServer;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass()
|
||||||
|
throws Exception {
|
||||||
|
ourPort = RandomServerPortProvider.findFreePort();
|
||||||
|
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
|
context.setContextPath("/");
|
||||||
|
System.out.println(ourPort);
|
||||||
|
jettyServer = new Server(ourPort);
|
||||||
|
jettyServer.setHandler(context);
|
||||||
|
ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
|
||||||
|
jerseyServlet.setInitOrder(0);
|
||||||
|
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", JaxRsPatientRestProvider.class.getCanonicalName());
|
||||||
|
jettyServer.start();
|
||||||
|
|
||||||
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
|
client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/");
|
||||||
|
client.setEncoding(EncodingEnum.JSON);
|
||||||
|
client.registerInterceptor(new LoggingInterceptor(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass()
|
||||||
|
throws Exception {
|
||||||
|
try {
|
||||||
|
jettyServer.destroy();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search/Query - Type */
|
||||||
|
@Test
|
||||||
|
public void findUsingGenericClientBySearch() {
|
||||||
|
// Perform a search
|
||||||
|
final ca.uhn.fhir.model.api.Bundle results = client.search().forResource(Patient.class)
|
||||||
|
.where(Patient.NAME.matchesExactly().value(PATIENT_NAME)).execute();
|
||||||
|
System.out.println(results.getEntries().get(0));
|
||||||
|
assertEquals(results.getEntries().size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search - Multi-valued Parameters (ANY/OR) */
|
||||||
|
@Test
|
||||||
|
public void findUsingGenericClientBySearchWithMultiValues() {
|
||||||
|
final ca.uhn.fhir.model.api.Bundle response = client.search().forResource(Patient.class)
|
||||||
|
.where(Patient.ADDRESS.matches().values("Toronto")).and(Patient.ADDRESS.matches().values("Ontario"))
|
||||||
|
.and(Patient.ADDRESS.matches().values("Canada"))
|
||||||
|
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("SHORTNAME", "TOYS")).execute();
|
||||||
|
System.out.println(response.getEntries().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search - Paging */
|
||||||
|
@Test
|
||||||
|
public void findWithPaging() {
|
||||||
|
// Perform a search
|
||||||
|
final Bundle results = client.search().forResource(Patient.class).limitTo(8).returnBundle(Bundle.class).execute();
|
||||||
|
System.out.println(results.getEntry().size());
|
||||||
|
|
||||||
|
if (results.getLink(Bundle.LINK_NEXT) != null) {
|
||||||
|
|
||||||
|
// load next page
|
||||||
|
final Bundle nextPage = client.loadPage().next(results).execute();
|
||||||
|
System.out.println(nextPage.getEntry().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search using other query options */
|
||||||
|
public void testOther() {
|
||||||
|
//missing
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
@Test
|
||||||
|
public void testSearchPost() {
|
||||||
|
Bundle response = client.search()
|
||||||
|
.forResource("Patient")
|
||||||
|
.usingStyle(SearchStyleEnum.POST)
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
assertTrue(response.getEntry().size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search - Compartments */
|
||||||
|
@Test
|
||||||
|
public void testSearchCompartements() {
|
||||||
|
Bundle response = client.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.withIdAndCompartment("1", "Condition")
|
||||||
|
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||||
|
.execute();
|
||||||
|
assertTrue(response.getEntry().size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Search - Subsetting (_summary and _elements) */
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testSummary() {
|
||||||
|
Object response = client.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreatePatient() {
|
||||||
|
final Patient existing = new Patient();
|
||||||
|
existing.setId((IdDt) null);
|
||||||
|
existing.getNameFirstRep().addFamily("Created Patient 54");
|
||||||
|
client.setEncoding(EncodingEnum.JSON);
|
||||||
|
final MethodOutcome results = client.create().resource(existing).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||||
|
System.out.println(results.getId());
|
||||||
|
final Patient patient = (Patient) results.getResource();
|
||||||
|
System.out.println(patient);
|
||||||
|
assertNotNull(client.read(patient.getId()));
|
||||||
|
client.setEncoding(EncodingEnum.JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Conditional Creates */
|
||||||
|
@Test
|
||||||
|
public void testConditionalCreate() {
|
||||||
|
final Patient existing = new Patient();
|
||||||
|
existing.setId((IdDt) null);
|
||||||
|
existing.getNameFirstRep().addFamily("Created Patient 54");
|
||||||
|
client.setEncoding(EncodingEnum.XML);
|
||||||
|
final MethodOutcome results = client.create().resource(existing).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||||
|
System.out.println(results.getId());
|
||||||
|
final Patient patient = (Patient) results.getResource();
|
||||||
|
|
||||||
|
client.create()
|
||||||
|
.resource(patient)
|
||||||
|
.conditional()
|
||||||
|
.where(Patient.IDENTIFIER.exactly().identifier(patient.getIdentifierFirstRep()))
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Find By Id */
|
||||||
|
@Test
|
||||||
|
public void findUsingGenericClientById() {
|
||||||
|
final Patient results = client.read(Patient.class, "1");
|
||||||
|
assertEquals(results.getId().getIdPartAsLong().longValue(), 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateById() {
|
||||||
|
final Patient existing = client.read(Patient.class, "1");
|
||||||
|
final List<HumanNameDt> name = existing.getName();
|
||||||
|
name.get(0).addSuffix("The Second");
|
||||||
|
existing.setName(name);
|
||||||
|
client.setEncoding(EncodingEnum.XML);
|
||||||
|
final MethodOutcome results = client.update("1", existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePatient() {
|
||||||
|
final Patient existing = new Patient();
|
||||||
|
existing.getNameFirstRep().addFamily("Created Patient XYZ");
|
||||||
|
final MethodOutcome results = client.create().resource(existing).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||||
|
System.out.println(results.getId());
|
||||||
|
final Patient patient = (Patient) results.getResource();
|
||||||
|
client.delete(Patient.class, patient.getId());
|
||||||
|
try {
|
||||||
|
client.read(patient.getId());
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (final Exception e) {
|
||||||
|
//assertEquals(e.getStatusCode(), Constants.STATUS_HTTP_404_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Transaction - Server */
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void testTransaction() {
|
||||||
|
ca.uhn.fhir.model.api.Bundle bundle = new ca.uhn.fhir.model.api.Bundle();
|
||||||
|
BundleEntry entry = bundle.addEntry();
|
||||||
|
final Patient existing = new Patient();
|
||||||
|
existing.getNameFirstRep().addFamily("Created with bundle");
|
||||||
|
entry.setResource(existing);
|
||||||
|
|
||||||
|
BoundCodeDt<BundleEntryTransactionMethodEnum> theTransactionOperation =
|
||||||
|
new BoundCodeDt(
|
||||||
|
BundleEntryTransactionMethodEnum.VALUESET_BINDER,
|
||||||
|
BundleEntryTransactionMethodEnum.POST);
|
||||||
|
entry.setTransactionMethod(theTransactionOperation);
|
||||||
|
ca.uhn.fhir.model.api.Bundle response = client.transaction().withBundle(bundle).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Conformance - Server */
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testConformance() {
|
||||||
|
final Conformance conf = client.fetchConformance().ofType(Conformance.class).execute();
|
||||||
|
System.out.println(conf.getRest().get(0).getResource().get(0).getType());
|
||||||
|
assertEquals(conf.getRest().get(0).getResource().get(0).getType().toString(), "Patient");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extended Operations */
|
||||||
|
// Create a client to talk to the HeathIntersections server
|
||||||
|
@Test
|
||||||
|
public void testExtendedOperations() {
|
||||||
|
client.registerInterceptor(new LoggingInterceptor(true));
|
||||||
|
|
||||||
|
// Create the input parameters to pass to the server
|
||||||
|
Parameters inParams = new Parameters();
|
||||||
|
inParams.addParameter().setName("start").setValue(new DateDt("2001-01-01"));
|
||||||
|
inParams.addParameter().setName("end").setValue(new DateDt("2015-03-01"));
|
||||||
|
inParams.addParameter().setName("dummy").setValue(new StringDt("myAwesomeDummyValue"));
|
||||||
|
|
||||||
|
// Invoke $everything on "Patient/1"
|
||||||
|
Parameters outParams = client
|
||||||
|
.operation()
|
||||||
|
.onInstance(new IdDt("Patient", "1"))
|
||||||
|
.named("$last")
|
||||||
|
.withParameters(inParams)
|
||||||
|
//.useHttpGet() // Use HTTP GET instead of POST
|
||||||
|
.execute();
|
||||||
|
String resultValue = outParams.getParameter().get(0).getValue().toString();
|
||||||
|
System.out.println(resultValue);
|
||||||
|
assertEquals("expected but found : "+ resultValue, resultValue.contains("myAwesomeDummyValue"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtendedOperationsUsingGet() {
|
||||||
|
client.registerInterceptor(new LoggingInterceptor(true));
|
||||||
|
|
||||||
|
// Create the input parameters to pass to the server
|
||||||
|
Parameters inParams = new Parameters();
|
||||||
|
inParams.addParameter().setName("start").setValue(new DateDt("2001-01-01"));
|
||||||
|
inParams.addParameter().setName("end").setValue(new DateDt("2015-03-01"));
|
||||||
|
inParams.addParameter().setName("dummy").setValue(new StringDt("myAwesomeDummyValue"));
|
||||||
|
|
||||||
|
// Invoke $everything on "Patient/1"
|
||||||
|
Parameters outParams = client
|
||||||
|
.operation()
|
||||||
|
.onInstance(new IdDt("Patient", "1"))
|
||||||
|
.named("$last")
|
||||||
|
.withParameters(inParams)
|
||||||
|
.useHttpGet() // Use HTTP GET instead of POST
|
||||||
|
.execute();
|
||||||
|
String resultValue = outParams.getParameter().get(0).getValue().toString();
|
||||||
|
System.out.println(resultValue);
|
||||||
|
assertEquals("expected but found : "+ resultValue, resultValue.contains("myAwesomeDummyValue"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindUnknownPatient() {
|
||||||
|
try {
|
||||||
|
final Patient existing = client.read(Patient.class, "999955541264");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
//assertEquals(e.getStatusCode(), 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVRead() {
|
||||||
|
final Patient patient = client.vread(Patient.class, "1", "1");
|
||||||
|
System.out.println(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRead() {
|
||||||
|
final Patient patient = client.read(Patient.class, "1");
|
||||||
|
System.out.println(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,269 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server.example;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.interceptor.Interceptors;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||||
|
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Condition;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Delete;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Read;
|
||||||
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Update;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
|
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||||
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fhir Physician Rest Service
|
||||||
|
* @author axmpm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Path(JaxRsPatientRestProvider.PATH)
|
||||||
|
@Stateless
|
||||||
|
@Produces({MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML})
|
||||||
|
public class JaxRsPatientRestProvider extends AbstractJaxRsResourceProvider<Patient> /*implements IJaxRsPatientProvider*/ {
|
||||||
|
|
||||||
|
static final String PATH = "/Patient";
|
||||||
|
|
||||||
|
private static Long counter = 1L;
|
||||||
|
private static final ConcurrentHashMap<String, List<Patient>> patients = new ConcurrentHashMap<String, List<Patient>>();
|
||||||
|
|
||||||
|
public JaxRsPatientRestProvider() throws Exception {
|
||||||
|
super(JaxRsPatientRestProvider.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
patients.put(""+counter, createPatient("Van Houte"));
|
||||||
|
patients.put(""+(counter), createPatient("Agnew"));
|
||||||
|
for(int i = 0 ; i<20 ; i++) {
|
||||||
|
patients.put(""+(counter), createPatient("Random Patient " + counter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Patient> createPatient(final String name) {
|
||||||
|
final Patient patient = new Patient();
|
||||||
|
patient.getNameFirstRep().addFamily(name);
|
||||||
|
return createPatient(patient);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Patient> createPatient(final Patient patient) {
|
||||||
|
patient.setId(createId(counter, 1L));
|
||||||
|
final LinkedList<Patient> list = new LinkedList<Patient>();
|
||||||
|
list.add(patient);
|
||||||
|
counter++;
|
||||||
|
return list ;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IdDt createId(final Long id, final Long theVersionId) {
|
||||||
|
return new IdDt("Patient", "" + id, "" + theVersionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||||
|
final List<Patient> result = new LinkedList<Patient>();
|
||||||
|
for (final List<Patient> patientIterator : patients.values()) {
|
||||||
|
Patient single = null;
|
||||||
|
for (Patient patient : patientIterator) {
|
||||||
|
if (name == null || patient.getNameFirstRep().getFamilyFirstRep().getValueNotNull().equals(name.getValueNotNull())) {
|
||||||
|
single = patient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (single != null) {
|
||||||
|
result.add(single);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Update
|
||||||
|
public MethodOutcome update(@IdParam final IdDt theId, @ResourceParam final Patient patient)
|
||||||
|
throws Exception {
|
||||||
|
final String idPart = theId.getIdPart();
|
||||||
|
if(patients.containsKey(idPart)) {
|
||||||
|
final List<Patient> patientList = patients.get(idPart);
|
||||||
|
final Patient lastPatient = getLast(patientList);
|
||||||
|
patient.setId(createId(theId.getIdPartAsLong(), lastPatient.getId().getVersionIdPartAsLong()+1));
|
||||||
|
patientList.add(patient);
|
||||||
|
final MethodOutcome result = new MethodOutcome().setCreated(false);
|
||||||
|
result.setResource(patient);
|
||||||
|
result.setId(patient.getId());
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
throw new ResourceNotFoundException(theId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Read
|
||||||
|
public Patient find(@IdParam final IdDt theId) {
|
||||||
|
if(patients.containsKey(theId.getIdPart())) {
|
||||||
|
return getLast(patients.get(theId.getIdPart()));
|
||||||
|
} else {
|
||||||
|
throw new ResourceNotFoundException(theId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Patient getLast(final List<Patient> list) {
|
||||||
|
return list.get(list.size()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Read(version = true)
|
||||||
|
public Patient findHistory(@IdParam final IdDt theId) {
|
||||||
|
if (patients.containsKey(theId.getIdPart())) {
|
||||||
|
final List<Patient> list = patients.get(theId.getIdPart());
|
||||||
|
for (final Patient patient : list) {
|
||||||
|
if (patient.getId().getVersionIdPartAsLong().equals(theId.getVersionIdPartAsLong())) {
|
||||||
|
return patient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new ResourceNotFoundException(theId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional)
|
||||||
|
throws Exception {
|
||||||
|
patients.put(""+counter, createPatient(patient));
|
||||||
|
final MethodOutcome result = new MethodOutcome().setCreated(true);
|
||||||
|
result.setResource(patient);
|
||||||
|
result.setId(patient.getId());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
public MethodOutcome delete(@IdParam final IdDt theId) {
|
||||||
|
final Patient deletedPatient = find(theId);
|
||||||
|
patients.remove(deletedPatient.getId().getIdPart());
|
||||||
|
final MethodOutcome result = new MethodOutcome().setCreated(true);
|
||||||
|
result.setResource(deletedPatient);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{id}/$last")
|
||||||
|
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||||
|
public Response operationLastGet(@PathParam("id") String id)
|
||||||
|
throws Exception {
|
||||||
|
return customOperation(null, RequestTypeEnum.GET, id, "$last", RestOperationTypeEnum.EXTENDED_OPERATION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search(compartmentName="Condition")
|
||||||
|
public List<IResource> searchCompartment(@IdParam IdDt thePatientId) {
|
||||||
|
List<IResource> retVal=new ArrayList<IResource>();
|
||||||
|
Condition condition = new Condition();
|
||||||
|
condition.setId(new IdDt("665577"));
|
||||||
|
retVal.add(condition);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{id}/$last")
|
||||||
|
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||||
|
public Response operationLast(final String resource)
|
||||||
|
throws Exception {
|
||||||
|
return customOperation(resource, RequestTypeEnum.POST, null, "$last", RestOperationTypeEnum.EXTENDED_OPERATION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ca.uhn.fhir.rest.annotation.Validate
|
||||||
|
// public MethodOutcome validate(
|
||||||
|
// @ResourceParam T theResource,
|
||||||
|
// @ResourceParam String theRawResource,
|
||||||
|
// @ResourceParam EncodingEnum theEncoding,
|
||||||
|
// @ca.uhn.fhir.rest.annotation.Validate.Mode ValidationModeEnum theMode,
|
||||||
|
// @ca.uhn.fhir.rest.annotation.Validate.Profile String theProfile) {
|
||||||
|
// return validate(theResource, null, theRawResource, theEncoding, theMode, theProfile);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Operation(name="last", idempotent=true, returnParameters= {
|
||||||
|
@OperationParam(name="return", type=StringDt.class)
|
||||||
|
})
|
||||||
|
public Parameters last(@OperationParam(name = "dummy") StringDt dummyInput) {
|
||||||
|
System.out.println("inputparameter");
|
||||||
|
Parameters parameters = new Parameters();
|
||||||
|
Patient patient = find(new IdDt(counter.intValue()-1));
|
||||||
|
parameters
|
||||||
|
.addParameter()
|
||||||
|
.setName("return")
|
||||||
|
.setResource(patient)
|
||||||
|
.setValue(new StringDt((counter-1)+"" + "inputVariable [ " + dummyInput.getValue()+ "]"));
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Patient> getResourceType() {
|
||||||
|
return Patient.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** THE DEFAULTS */
|
||||||
|
@Override
|
||||||
|
public List<IServerInterceptor> getInterceptors() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ETagSupportEnum getETagSupport() {
|
||||||
|
return ETagSupportEnum.DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDefaultPrettyPrint() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AddProfileTagEnum getAddProfileTag() {
|
||||||
|
return AddProfileTagEnum.NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUseBrowserFriendlyContentTypes() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPagingProvider getPagingProvider() {
|
||||||
|
return new FifoMemoryPagingProvider(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BundleInclusionRule getBundleInclusionRule() {
|
||||||
|
return BundleInclusionRule.BASED_ON_INCLUDES;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server.example;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides server ports
|
||||||
|
*/
|
||||||
|
public class RandomServerPortProvider {
|
||||||
|
|
||||||
|
private static List<Integer> ourPorts = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
public static int findFreePort() {
|
||||||
|
ServerSocket server;
|
||||||
|
try {
|
||||||
|
server = new ServerSocket(0);
|
||||||
|
int port = server.getLocalPort();
|
||||||
|
ourPorts.add(port);
|
||||||
|
server.close();
|
||||||
|
Thread.sleep(500);
|
||||||
|
return port;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Integer> list() {
|
||||||
|
return ourPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server.example;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
|
||||||
|
public class TestDummyPatientProvider extends AbstractJaxRsResourceProvider<Patient> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Patient> getResourceType() {
|
||||||
|
return Patient.class;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import javax.ws.rs.core.MultivaluedHashMap;
|
||||||
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.glassfish.jersey.internal.MapPropertiesDelegate;
|
||||||
|
import org.glassfish.jersey.server.ContainerRequest;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jaxrs.server.example.TestDummyPatientProvider;
|
||||||
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
|
||||||
|
public class JaxRsRequestTest {
|
||||||
|
|
||||||
|
private static final String RESOURCE_STRING = "</Patient>";
|
||||||
|
private static final String BASEURI = "http://baseuri";
|
||||||
|
private static final String REQUESTURI = "http://baseuri/test";
|
||||||
|
|
||||||
|
private JaxRsRequest details;
|
||||||
|
private MultivaluedMap<String, String> queryParameters = new MultivaluedHashMap<String, String>();
|
||||||
|
private ContainerRequest headers;
|
||||||
|
private TestDummyPatientProvider provider;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws URISyntaxException {
|
||||||
|
details = createRequestDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetHeader() {
|
||||||
|
String headerKey = "key";
|
||||||
|
String headerValue = "location_value";
|
||||||
|
String headerValue2 = "location_value_2";
|
||||||
|
assertTrue(StringUtils.isBlank(details.getHeader(headerKey)));
|
||||||
|
headers.header(headerKey, headerValue);
|
||||||
|
assertEquals(headerValue, details.getHeader(headerKey));
|
||||||
|
assertEquals(Arrays.asList(headerValue), details.getHeaders(headerKey));
|
||||||
|
|
||||||
|
headers.header(headerKey, headerValue2);
|
||||||
|
assertEquals(headerValue, details.getHeader(headerKey));
|
||||||
|
assertEquals(Arrays.asList(headerValue, headerValue2), details.getHeaders(headerKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetByteStreamRequestContents() {
|
||||||
|
assertEquals(RESOURCE_STRING, new String(details.getByteStreamRequestContents()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServerBaseForRequest() {
|
||||||
|
assertEquals(BASEURI, new String(details.getServerBaseForRequest()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResponse() {
|
||||||
|
JaxRsResponse response = (JaxRsResponse) details.getResponse();
|
||||||
|
assertEquals(details, response.getRequestDetails());
|
||||||
|
assertTrue(response == details.getResponse());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void testGetReader() throws IOException {
|
||||||
|
details.getReader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void testGetInputStream() {
|
||||||
|
details.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetServerBaseForRequest() {
|
||||||
|
assertEquals(JaxRsRequestTest.BASEURI, details.getFhirServerBase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetServer() {
|
||||||
|
assertEquals(this.provider, details.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJaxRsRequestDetails() {
|
||||||
|
Validate.notNull(new JaxRsRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
public JaxRsRequest createRequestDetails() throws URISyntaxException {
|
||||||
|
//headers
|
||||||
|
headers = new ContainerRequest(new URI(BASEURI), new URI(REQUESTURI), HttpMethod.GET, null, new MapPropertiesDelegate());
|
||||||
|
|
||||||
|
//uri info
|
||||||
|
UriInfo uriInfo = mock(UriInfo.class);
|
||||||
|
when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
|
||||||
|
|
||||||
|
//mocks
|
||||||
|
provider = spy(TestDummyPatientProvider.class);
|
||||||
|
doReturn(uriInfo).when(provider).getInfo();
|
||||||
|
doReturn(BASEURI).when(provider).getBaseUri();
|
||||||
|
doReturn(headers).when(provider).getHeaders();
|
||||||
|
|
||||||
|
return new JaxRsRequest(provider, RESOURCE_STRING, RequestTypeEnum.GET, RestOperationTypeEnum.HISTORY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,196 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Binary;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||||
|
import ca.uhn.fhir.rest.method.ParseAction;
|
||||||
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||||
|
|
||||||
|
public class JaxRsResponseTest {
|
||||||
|
|
||||||
|
private JaxRsResponse response;
|
||||||
|
private JaxRsRequest request;
|
||||||
|
private Bundle bundle;
|
||||||
|
private Set<SummaryEnum> theSummaryMode;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws URISyntaxException {
|
||||||
|
request = new JaxRsRequestTest().createRequestDetails();
|
||||||
|
this.response = (JaxRsResponse) request.getResponse();
|
||||||
|
bundle = getSinglePatientResource();
|
||||||
|
theSummaryMode = Collections.<SummaryEnum>emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResponseWriterNoZipNoBrowser() throws IOException {
|
||||||
|
boolean theRequestIsBrowser = false;
|
||||||
|
boolean respondGzip = false;
|
||||||
|
Set<SummaryEnum> theSummaryMode = Collections.<SummaryEnum>emptySet();
|
||||||
|
Response result = (Response) RestfulServerUtils.streamResponseAsBundle(request.getServer(), bundle, theSummaryMode, theRequestIsBrowser, respondGzip, request);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(Constants.CT_FHIR_JSON, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertTrue(result.getEntity().toString().contains("Patient"));
|
||||||
|
assertTrue(result.getEntity().toString().contains("15"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResponseWriterBrowserNoZip() throws IOException {
|
||||||
|
boolean theRequestIsBrowser = true;
|
||||||
|
boolean respondGzip = false;
|
||||||
|
Response result = (Response) RestfulServerUtils.streamResponseAsBundle(request.getServer(), bundle, theSummaryMode, theRequestIsBrowser, respondGzip, request);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(Constants.CT_JSON, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertTrue(result.getEntity().toString().contains("Patient"));
|
||||||
|
assertTrue(result.getEntity().toString().contains("15"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetResponseWriterWithZip() throws IOException {
|
||||||
|
boolean theRequestIsBrowser = true;
|
||||||
|
boolean respondGzip = true;
|
||||||
|
Response result = (Response) RestfulServerUtils.streamResponseAsBundle(request.getServer(), bundle, theSummaryMode, theRequestIsBrowser, respondGzip, request);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(Constants.CT_JSON, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertEquals(Constants.ENCODING_GZIP, result.getHeaderString(Constants.HEADER_CONTENT_ENCODING));
|
||||||
|
// assertTrue(unzip(result.getEntity()).contains("Patient"));
|
||||||
|
// assertTrue(result.getEntity().toString().contains("15"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendAttachmentResponse() throws IOException {
|
||||||
|
boolean theRequestIsBrowser = true;
|
||||||
|
boolean respondGzip = true;
|
||||||
|
IBaseBinary binary = new Binary();
|
||||||
|
String contentType = "foo";
|
||||||
|
byte[] content = new byte[] { 1, 2, 3, 4 };
|
||||||
|
binary.setContentType(contentType);
|
||||||
|
binary.setContent(content);
|
||||||
|
boolean theAddContentLocationHeader = false;
|
||||||
|
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theRequestIsBrowser, theSummaryMode, 200, respondGzip, theAddContentLocationHeader, respondGzip, this.request);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(contentType, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertEquals(content, result.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendAttachmentResponseNoContent() throws IOException {
|
||||||
|
boolean theRequestIsBrowser = true;
|
||||||
|
boolean respondGzip = true;
|
||||||
|
IBaseBinary binary = new Binary();
|
||||||
|
binary.setContent(new byte[]{});
|
||||||
|
boolean theAddContentLocationHeader = false;
|
||||||
|
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theRequestIsBrowser, theSummaryMode, 200, respondGzip, theAddContentLocationHeader, respondGzip, this.request);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(null, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertEquals(null, result.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendAttachmentResponseEmptyContent() throws IOException {
|
||||||
|
boolean theRequestIsBrowser = true;
|
||||||
|
boolean respondGzip = true;
|
||||||
|
IBaseBinary binary = new Binary();
|
||||||
|
boolean theAddContentLocationHeader = false;
|
||||||
|
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theRequestIsBrowser, theSummaryMode, 200, respondGzip, theAddContentLocationHeader, respondGzip, this.request);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(null, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertEquals(null, result.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReturnResponse() throws IOException {
|
||||||
|
IdDt theId = new IdDt(15L);
|
||||||
|
ParseAction<?> outcome = ParseAction.create(createPatient());
|
||||||
|
int operationStatus = 200;
|
||||||
|
boolean allowPrefer = true;
|
||||||
|
String resourceName = "Patient";
|
||||||
|
MethodOutcome methodOutcome = new MethodOutcome(theId);
|
||||||
|
Response result = response.returnResponse(outcome, operationStatus, allowPrefer, methodOutcome, resourceName);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(Constants.CT_JSON, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
System.out.println(result.getEntity().toString());
|
||||||
|
assertTrue(result.getEntity().toString().contains("resourceType\":\"Patient"));
|
||||||
|
assertTrue(result.getEntity().toString().contains("15"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReturnResponseAsXml() throws IOException {
|
||||||
|
IdDt theId = new IdDt(15L);
|
||||||
|
ParseAction<?> outcome = ParseAction.create(createPatient());
|
||||||
|
int operationStatus = 200;
|
||||||
|
boolean allowPrefer = true;
|
||||||
|
String resourceName = "Patient";
|
||||||
|
MethodOutcome methodOutcome = new MethodOutcome(theId);
|
||||||
|
response.getRequestDetails().getParameters().put(Constants.PARAM_FORMAT, new String[]{Constants.CT_XML});
|
||||||
|
Response result = response.returnResponse(outcome, operationStatus, allowPrefer, methodOutcome, resourceName);
|
||||||
|
assertEquals(200, result.getStatus());
|
||||||
|
assertEquals(Constants.CT_XML, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
assertTrue(result.getEntity().toString().contains("<Patient"));
|
||||||
|
assertTrue(result.getEntity().toString().contains("15"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoOutcomeXml() throws IOException {
|
||||||
|
ParseAction<?> outcome = ParseAction.create((IBaseResource) null);
|
||||||
|
int operationStatus = Constants.STATUS_HTTP_204_NO_CONTENT;
|
||||||
|
boolean allowPrefer = true;
|
||||||
|
String resourceName = "Patient";
|
||||||
|
MethodOutcome methodOutcome = new MethodOutcome(null);
|
||||||
|
response.getRequestDetails().getParameters().put(Constants.PARAM_FORMAT, new String[]{Constants.CT_XML});
|
||||||
|
Response result = response.returnResponse(outcome, operationStatus, allowPrefer, methodOutcome, resourceName);
|
||||||
|
assertEquals(204, result.getStatus());
|
||||||
|
assertEquals(Constants.CT_XML, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unzip(Object entity) throws IOException {
|
||||||
|
byte[] compressed = ((String) entity).getBytes(Constants.CHARSET_NAME_UTF8);
|
||||||
|
final int BUFFER_SIZE = 32;
|
||||||
|
ByteArrayInputStream is = new ByteArrayInputStream(compressed);
|
||||||
|
GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);
|
||||||
|
StringBuilder string = new StringBuilder();
|
||||||
|
byte[] data = new byte[BUFFER_SIZE];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = gis.read(data)) != -1) {
|
||||||
|
string.append(new String(data, 0, bytesRead));
|
||||||
|
}
|
||||||
|
gis.close();
|
||||||
|
is.close();
|
||||||
|
return string.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bundle getSinglePatientResource() {
|
||||||
|
Patient theResource = createPatient();
|
||||||
|
Bundle bundle = Bundle.withSingleResource(theResource);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Patient createPatient() {
|
||||||
|
Patient theResource = new Patient();
|
||||||
|
theResource.setId(new IdDt(15L));
|
||||||
|
return theResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
package ca.uhn.fhir.jaxrs.server.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jaxrs.server.example.TestDummyPatientProvider;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Update;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.DEFAULT)
|
||||||
|
public class MethodBindingsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MethodBindings.getClassBindings().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void testFindMethodsForProviderNotDefinedMappingMethods() {
|
||||||
|
new TestDummyPatientProvider().getBindings().getBinding(RestOperationTypeEnum.UPDATE, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindMethodsForProviderWithMethods() {
|
||||||
|
class TestFindPatientProvider extends TestDummyPatientProvider {
|
||||||
|
@Search
|
||||||
|
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new TestFindPatientProvider();
|
||||||
|
assertEquals(TestFindPatientProvider.class, new TestFindPatientProvider().getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE).getMethod().getDeclaringClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindMethodsFor2ProvidersWithMethods() {
|
||||||
|
class TestFindPatientProvider extends TestDummyPatientProvider {
|
||||||
|
@Search
|
||||||
|
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class TestUpdatePatientProvider extends TestDummyPatientProvider {
|
||||||
|
@Update
|
||||||
|
public MethodOutcome update(@IdParam final IdDt theId, @ResourceParam final Patient patient) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(TestFindPatientProvider.class, new TestFindPatientProvider().getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE).getMethod().getDeclaringClass());
|
||||||
|
assertEquals(TestUpdatePatientProvider.class, new TestUpdatePatientProvider().getBindings().getBinding(RestOperationTypeEnum.UPDATE).getMethod().getDeclaringClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindMethodsWithDoubleMethodsDeclaration() {
|
||||||
|
class TestDoubleSearchProvider extends TestDummyPatientProvider {
|
||||||
|
@Search
|
||||||
|
public List<Patient> search1(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public List<Patient> search2(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new TestDoubleSearchProvider();
|
||||||
|
fail();
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
assertTrue(e.getMessage().contains("search1"));
|
||||||
|
assertTrue(e.getMessage().contains("search2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindMethodsWithMultipleMethods() {
|
||||||
|
class TestFindPatientProvider extends TestDummyPatientProvider {
|
||||||
|
@Search
|
||||||
|
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Update
|
||||||
|
public MethodOutcome update(@IdParam final IdDt theId, @ResourceParam final Patient patient) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Operation(name = "firstMethod", idempotent = true, returnParameters = { @OperationParam(name = "return", type = StringDt.class) })
|
||||||
|
public Parameters firstMethod(@OperationParam(name = "dummy") StringDt dummyInput) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Operation(name = "secondMethod", returnParameters = { @OperationParam(name = "return", type = StringDt.class) })
|
||||||
|
public Parameters secondMethod(@OperationParam(name = "dummy") StringDt dummyInput) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MethodBindings bindings = new TestFindPatientProvider().getBindings();
|
||||||
|
assertEquals("search", bindings.getBinding(RestOperationTypeEnum.SEARCH_TYPE).getMethod().getName());
|
||||||
|
assertEquals("update", bindings.getBinding(RestOperationTypeEnum.UPDATE).getMethod().getName());
|
||||||
|
assertEquals("firstMethod", bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$firstMethod").getMethod().getName());
|
||||||
|
assertEquals("secondMethod", bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$secondMethod").getMethod().getName());
|
||||||
|
try {
|
||||||
|
bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$thirdMethod");
|
||||||
|
fail();
|
||||||
|
} catch(UnsupportedOperationException e){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue