Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
jamesagnew 2019-06-27 18:23:54 -04:00
commit 6d8465abe6
6 changed files with 69 additions and 44 deletions

View File

@ -90,42 +90,6 @@ public abstract class BaseMethodBinding<T> {
myMethod.setAccessible(true);
}
protected IParser createAppropriateParserForParsingResponse(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, List<Class<? extends IBaseResource>> thePreferTypes) {
EncodingEnum encoding = EncodingEnum.forContentType(theResponseMimeType);
if (encoding == null) {
NonFhirResponseException ex = NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
populateException(ex, theResponseReader);
throw ex;
}
IParser parser = encoding.newParser(getContext());
parser.setPreferTypes(thePreferTypes);
return parser;
}
protected IParser createAppropriateParserForParsingServerRequest(RequestDetails theRequest) {
String contentTypeHeader = theRequest.getHeader(Constants.HEADER_CONTENT_TYPE);
EncodingEnum encoding;
if (isBlank(contentTypeHeader)) {
encoding = EncodingEnum.XML;
} else {
int semicolon = contentTypeHeader.indexOf(';');
if (semicolon != -1) {
contentTypeHeader = contentTypeHeader.substring(0, semicolon);
}
encoding = EncodingEnum.forContentType(contentTypeHeader);
}
if (encoding == null) {
throw new InvalidRequestException("Request contins non-FHIR conent-type header value: " + contentTypeHeader);
}
IParser parser = encoding.newParser(getContext());
return parser;
}
protected Object[] createMethodParams(RequestDetails theRequest) {
Object[] params = new Object[getParameters().size()];
for (int i = 0; i < getParameters().size(); i++) {

View File

@ -128,10 +128,16 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
/*
* If the method has no parsed resource parameter, we parse here in order to have something for the interceptor.
*/
IBaseResource resource;
if (myResourceParameterIndex != -1) {
theDetails.setResource((IBaseResource) theMethodParams[myResourceParameterIndex]);
resource = (IBaseResource) theMethodParams[myResourceParameterIndex];
} else {
theDetails.setResource(ResourceParameter.parseResourceFromRequest(theRequestDetails, this, myResourceType));
resource = ResourceParameter.parseResourceFromRequest(theRequestDetails, this, myResourceType);
}
theRequestDetails.setResource(resource);
if (theDetails != null) {
theDetails.setResource(resource);
}
}

View File

@ -238,6 +238,8 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
public IBaseResource doInvokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) {
Object[] params = createMethodParams(theRequest);
Object resultObj = invokeServer(theServer, theRequest, params);
Integer count = RestfulServerUtils.extractCountParameter(theRequest);

View File

@ -285,6 +285,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
theMethodParams[myIdParamIndex] = theRequest.getId();
}
// populateActionRequestDetailsForInterceptor(theRequest); AAAAAA
Object response = invokeServerMethod(theServer, theRequest, theMethodParams);
IBundleProvider retVal = toResourceList(response);
return retVal;
@ -309,7 +311,11 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
@Override
protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) {
super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams);
theDetails.setResource((IBaseResource) theRequestDetails.getUserData().get(OperationParameter.REQUEST_CONTENTS_USERDATA_KEY));
IBaseResource resource = (IBaseResource) theRequestDetails.getUserData().get(OperationParameter.REQUEST_CONTENTS_USERDATA_KEY);
theRequestDetails.setResource(resource);
if (theDetails != null) {
theDetails.setResource(resource);
}
}
public static class ReturnType {

View File

@ -167,11 +167,17 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
/*
* If the method has no parsed resource parameter, we parse here in order to have something for the interceptor.
*/
IBaseResource resource;
if (myTransactionParamIndex != -1) {
theDetails.setResource((IBaseResource) theMethodParams[myTransactionParamIndex]);
resource = (IBaseResource) theMethodParams[myTransactionParamIndex];
} else {
Class<? extends IBaseResource> resourceType = getContext().getResourceDefinition("Bundle").getImplementingClass();
theDetails.setResource(ResourceParameter.parseResourceFromRequest(theRequestDetails, this, resourceType));
resource = ResourceParameter.parseResourceFromRequest(theRequestDetails, this, resourceType);
}
theRequestDetails.setResource(resource);
if (theDetails != null) {
theDetails.setResource(resource);
}
}

View File

@ -1,6 +1,9 @@
package ca.uhn.fhir.rest.server;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IAnonymousInterceptor;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
@ -28,9 +31,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.OperationOutcome;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.*;
import org.mockito.ArgumentCaptor;
@ -40,6 +41,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;
@ -81,6 +83,38 @@ public class InterceptorDstu3Test {
"}";
}
@Test
public void testServerPreHandledOnOperationCapturesResource() throws IOException {
AtomicReference<IBaseResource> resource = new AtomicReference<>();
IAnonymousInterceptor interceptor = new IAnonymousInterceptor() {
@Override
public void invoke(Pointcut thePointcut, HookParams theArgs) {
RequestDetails requestDetails = theArgs.get(RequestDetails.class);
resource.set(requestDetails.getResource());
}
};
ourServlet.getInterceptorService().registerAnonymousInterceptor(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED, interceptor);
try {
Parameters p = new Parameters();
p.addParameter().setName("limit").setValue(new IntegerType(123));
String input = ourCtx.newJsonParser().encodeResourceToString(p);
HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Patient/$postOperation");
post.setEntity(new StringEntity(input, ContentType.create("application/fhir+json", Constants.CHARSET_UTF8)));
try (CloseableHttpResponse status = ourClient.execute(post)) {
assertEquals(200, status.getStatusLine().getStatusCode());
}
} finally {
ourServlet.unregisterInterceptor(interceptor);
}
assertNotNull(resource.get());
}
@Test
public void testModifyResponse() throws IOException {
InterceptorAdapter interceptor = new InterceptorAdapter() {
@ -271,6 +305,13 @@ public class InterceptorDstu3Test {
return new MethodOutcome();
}
@Operation(name="$postOperation")
public Parameters postOperation(
@OperationParam(name = "limit") IntegerType theLimit
) {
return new Parameters();
}
@Override
public Class<Patient> getResourceType() {
return Patient.class;