Don't return a Content-Location header when returning the new bundle

format
This commit is contained in:
James Agnew 2015-04-20 17:32:20 -04:00
parent 4f1d2a3c75
commit 91167733c6
11 changed files with 90 additions and 44 deletions

View File

@ -64,18 +64,21 @@
<artifactId>slf4j-android</artifactId>
<version>${slf4j_version}</version>
</dependency>
<!-- <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>stax2-api</artifactId>
<version>3.1.4</version> </dependency> -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons_io_version}</version>
<scope>test</scope>
</dependency>
<!--
Android does not come with the Servlet API bundled, and MethodUtil requires it
-->
<!-- Android does not come with the Servlet API bundled, and MethodUtil
requires it -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
@ -138,7 +141,6 @@
<artifactSet>
<includes>
<include>commons-codec:commons-codec</include>
<include>commons-io:commons-io</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-base</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</include>

View File

@ -0,0 +1,14 @@
package ca.uhn.fhir.android;
import ca.uhn.fhir.context.FhirContext;
public class AndroidLoader {
public static void main(String[] theArgs) {
FhirContext ctx = FhirContext.forDstu2();
ctx.newJsonParser();
ctx.newXmlParser();
ctx.newRestfulGenericClient("");
}
}

View File

@ -279,7 +279,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
return;
}
}
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase());
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, respondGzip, theRequest.getFhirServerBase(), isAddContentLocationHeader());
break;
} else {
Set<Include> includes = getRequestIncludesFromParams(params);
@ -312,7 +312,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
return;
}
}
RestfulServerUtils.streamResponseAsResource(theServer, response, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase());
RestfulServerUtils.streamResponseAsResource(theServer, response, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase(), isAddContentLocationHeader());
}
break;
@ -336,12 +336,19 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
}
}
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase());
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, respondGzip, theRequest.getFhirServerBase(), isAddContentLocationHeader());
break;
}
}
}
/**
* Should the response include a Content-Location header. Search method bunding (and any others?) may override this to disable the content-location, since it doesn't make sense
*/
protected boolean isAddContentLocationHeader() {
return true;
}
/**
* Subclasses may override
*

View File

@ -132,6 +132,11 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
return RestfulOperationTypeEnum.SEARCH_TYPE;
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
@Override
public ReturnTypeEnum getReturnType() {
return ReturnTypeEnum.BUNDLE;
@ -289,13 +294,9 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
}
public void setResourceType(Class<? extends IResource> resourceType) {
this.myDeclaredResourceType = resourceType;
}
@Override
public String toString() {
return getMethod().toString();
protected boolean isAddContentLocationHeader() {
return false;
}
private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) {
@ -313,6 +314,15 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
return retVal;
}
public void setResourceType(Class<? extends IResource> resourceType) {
this.myDeclaredResourceType = resourceType;
}
@Override
public String toString() {
return getMethod().toString();
}
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName,
SearchStyleEnum theSearchStyle) {
SearchStyleEnum searchStyle = theSearchStyle;
@ -473,9 +483,4 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
}

View File

@ -490,7 +490,7 @@ public class RestfulServer extends HttpServlet {
return;
}
}
RestfulServerUtils.streamResponseAsResource(this, theResponse, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase());
RestfulServerUtils.streamResponseAsResource(this, theResponse, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase(), false);
}
}

View File

@ -73,10 +73,10 @@ public class RestfulServerUtils {
}
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase) throws IOException {
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase, boolean theAddContentLocationHeader) throws IOException {
theHttpResponse.setStatus(stausCode);
if (theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
if (theAddContentLocationHeader && theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
String resName = theServer.getFhirContext().getResourceDefinition(theResource).getName();
IdDt fullId = theResource.getId().withServerBase(theServerBase, resName);
theHttpResponse.addHeader(Constants.HEADER_CONTENT_LOCATION, fullId.getValue());
@ -402,12 +402,12 @@ public class RestfulServerUtils {
}
}
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
int stausCode = 200;
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
theServerBase);
}
// public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
// boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
// int stausCode = 200;
// RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
// theServerBase);
// }
public static void validateResourceListNotNull(List<IResource> theResourceList) {
if (theResourceList == null) {

View File

@ -129,7 +129,7 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
String fhirServerBase = ((Request) theRequestDetails).getFhirServerBase();
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase);
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
// theResponse.setStatus(statusCode);
// theRequestDetails.getServer().addHeadersToResponse(theResponse);

View File

@ -4,12 +4,11 @@ import java.util.List;
import javax.servlet.ServletException;
import ca.uhn.fhir.context.FhirVersionEnum;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
@ -23,7 +22,7 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
public class JpaServerDemo extends RestfulServer {
@ -123,12 +122,12 @@ public class JpaServerDemo extends RestfulServer {
setPagingProvider(new FifoMemoryPagingProvider(10));
/*
* Do some fancy logging to create a nice access log that has details about each incoming request.
* Load interceptors for the server from Spring (these are defined in hapi-fhir-server-config.xml
*/
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
loggingInterceptor.setLoggerName("fhir.access");
loggingInterceptor.setMessageFormat("Path[${servletPath}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
this.registerInterceptor(loggingInterceptor);
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
for (IServerInterceptor interceptor : interceptorBeans) {
this.registerInterceptor(interceptor);
}
}

View File

@ -21,4 +21,18 @@
</bean>
<tx:annotation-driven transaction-manager="myTxManager" />
<util:list id="myServerInterceptors">
<ref bean="myLoggingInterceptor"/>
</util:list>
<!--
Do some fancy logging to create a nice access log that has details
about each incoming request.
-->
<bean id="myLoggingInterceptor" class="ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor">
<property name="loggerName" value="fhirtest.access"/>
<property name="messageFormat"
value="Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"/>
</bean>
</beans>

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import java.util.concurrent.TimeUnit;
@ -49,6 +49,7 @@ public class SearchDstu2Test {
Patient patient = (Patient) ourCtx.newXmlParser().parseResource(Bundle.class, responseContent).getEntry().get(0).getResource();
String ref = patient.getManagingOrganization().getReference().getValue();
assertEquals("Organization/555", ref);
assertNull(status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION));
}

View File

@ -136,6 +136,10 @@
Please let us know if this is a big hardship and we can find an alternate way
of making this change.
</action>
<action type="fix">
Prevent server from returning a Content-Location header for search
response when using the DSTU2 bundle format
</action>
</release>
<release version="0.9" date="2015-Mar-14">
<action type="add">