Fix responsehighlighterinterceptor to work with graphql
This commit is contained in:
parent
33767b5399
commit
b127867ef7
|
@ -400,6 +400,12 @@ public enum Pointcut {
|
|||
* <li>
|
||||
* java.lang.String - The GraphQL response
|
||||
* </li>
|
||||
* <li>
|
||||
* javax.servlet.http.HttpServletRequest - The servlet request, when running in a servlet environment
|
||||
* </li>
|
||||
* <li>
|
||||
* javax.servlet.http.HttpServletResponse - The servlet response, when running in a servlet environment
|
||||
* </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
|
@ -417,7 +423,9 @@ public enum Pointcut {
|
|||
"ca.uhn.fhir.rest.api.server.RequestDetails",
|
||||
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails",
|
||||
"java.lang.String",
|
||||
"java.lang.String"
|
||||
"java.lang.String",
|
||||
"javax.servlet.http.HttpServletRequest",
|
||||
"javax.servlet.http.HttpServletResponse"
|
||||
),
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.server.interceptor;
|
|||
public class InterceptorOrders {
|
||||
|
||||
public static final int SERVE_MEDIA_RESOURCE_RAW_INTERCEPTOR = 1000;
|
||||
|
||||
public static final int RESPONSE_HIGHLIGHTER_INTERCEPTOR = 10000;
|
||||
|
||||
/** Non instantiable */
|
||||
|
|
|
@ -268,7 +268,7 @@ public class ResponseHighlighterInterceptor {
|
|||
responseDetails.setResponseCode(theException.getStatusCode());
|
||||
|
||||
BaseResourceReturningMethodBinding.callOutgoingFailureOperationOutcomeHook(theRequestDetails, oo);
|
||||
streamResponse(theRequestDetails, theServletResponse, responseDetails.getResponseResource(), theServletRequest, responseDetails.getResponseCode());
|
||||
streamResponse(theRequestDetails, theServletResponse, responseDetails.getResponseResource(), null, theServletRequest, responseDetails.getResponseCode());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -313,10 +313,39 @@ public class ResponseHighlighterInterceptor {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Hook(value = Pointcut.SERVER_OUTGOING_GRAPHQL_RESPONSE, order = InterceptorOrders.RESPONSE_HIGHLIGHTER_INTERCEPTOR)
|
||||
public boolean outgoingGraphqlResponse(RequestDetails theRequestDetails, String theRequest, String theResponse, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
|
||||
throws AuthenticationException {
|
||||
|
||||
/*
|
||||
* Return true here so that we still fire SERVER_OUTGOING_GRAPHQL_RESPONSE!
|
||||
*/
|
||||
|
||||
if (handleOutgoingResponse(theRequestDetails, null, theServletRequest, theServletResponse, theResponse, null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
theRequestDetails.setAttribute("ResponseHighlighterInterceptorHandled", Boolean.TRUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Hook(value = Pointcut.SERVER_OUTGOING_RESPONSE, order = InterceptorOrders.RESPONSE_HIGHLIGHTER_INTERCEPTOR)
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, ResponseDetails theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
|
||||
throws AuthenticationException {
|
||||
|
||||
if (!Boolean.TRUE.equals(theRequestDetails.getAttribute("ResponseHighlighterInterceptorHandled"))) {
|
||||
String graphqlResponse = null;
|
||||
IBaseResource resourceResponse = theResponseObject.getResponseResource();
|
||||
if (handleOutgoingResponse(theRequestDetails, theResponseObject, theServletRequest, theServletResponse, graphqlResponse, resourceResponse)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean handleOutgoingResponse(RequestDetails theRequestDetails, ResponseDetails theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse, String theGraphqlResponse, IBaseResource theResourceResponse) {
|
||||
/*
|
||||
* Request for _raw
|
||||
*/
|
||||
|
@ -380,12 +409,11 @@ public class ResponseHighlighterInterceptor {
|
|||
/*
|
||||
* Not binary
|
||||
*/
|
||||
if (!force && (theResponseObject.getResponseResource() instanceof IBaseBinary)) {
|
||||
if (!force && theResponseObject != null && (theResponseObject.getResponseResource() instanceof IBaseBinary)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
streamResponse(theRequestDetails, theServletResponse, theResponseObject.getResponseResource(), theServletRequest, 200);
|
||||
|
||||
streamResponse(theRequestDetails, theServletResponse, theResourceResponse, theGraphqlResponse, theServletRequest, 200);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -407,40 +435,51 @@ public class ResponseHighlighterInterceptor {
|
|||
}
|
||||
}
|
||||
|
||||
private void streamResponse(RequestDetails theRequestDetails, HttpServletResponse theServletResponse, IBaseResource theResource, ServletRequest theServletRequest, int theStatusCode) {
|
||||
private void streamResponse(RequestDetails theRequestDetails, HttpServletResponse theServletResponse, IBaseResource theResource, String theGraphqlResponse, ServletRequest theServletRequest, int theStatusCode) {
|
||||
EncodingEnum encoding;
|
||||
String encoded;
|
||||
Map<String, String[]> parameters = theRequestDetails.getParameters();
|
||||
|
||||
if (isNotBlank(theGraphqlResponse)) {
|
||||
|
||||
encoded = theGraphqlResponse;
|
||||
encoding = EncodingEnum.JSON;
|
||||
|
||||
} else {
|
||||
|
||||
IParser p;
|
||||
if (parameters.containsKey(Constants.PARAM_FORMAT)) {
|
||||
FhirVersionEnum forVersion = theResource.getStructureFhirVersionEnum();
|
||||
p = RestfulServerUtils.getNewParser(theRequestDetails.getServer().getFhirContext(), forVersion, theRequestDetails);
|
||||
} else {
|
||||
EncodingEnum defaultResponseEncoding = theRequestDetails.getServer().getDefaultResponseEncoding();
|
||||
p = defaultResponseEncoding.newParser(theRequestDetails.getServer().getFhirContext());
|
||||
RestfulServerUtils.configureResponseParser(theRequestDetails, p);
|
||||
}
|
||||
|
||||
// This interceptor defaults to pretty printing unless the user
|
||||
// has specifically requested us not to
|
||||
boolean prettyPrintResponse = true;
|
||||
String[] prettyParams = parameters.get(Constants.PARAM_PRETTY);
|
||||
if (prettyParams != null && prettyParams.length > 0) {
|
||||
if (Constants.PARAM_PRETTY_VALUE_FALSE.equals(prettyParams[0])) {
|
||||
prettyPrintResponse = false;
|
||||
}
|
||||
}
|
||||
if (prettyPrintResponse) {
|
||||
p.setPrettyPrint(true);
|
||||
}
|
||||
|
||||
encoding = p.getEncoding();
|
||||
encoded = p.encodeResourceToString(theResource);
|
||||
|
||||
}
|
||||
|
||||
if (theRequestDetails.getServer() instanceof RestfulServer) {
|
||||
RestfulServer rs = (RestfulServer) theRequestDetails.getServer();
|
||||
rs.addHeadersToResponse(theServletResponse);
|
||||
}
|
||||
|
||||
IParser p;
|
||||
Map<String, String[]> parameters = theRequestDetails.getParameters();
|
||||
if (parameters.containsKey(Constants.PARAM_FORMAT)) {
|
||||
FhirVersionEnum forVersion = theResource.getStructureFhirVersionEnum();
|
||||
p = RestfulServerUtils.getNewParser(theRequestDetails.getServer().getFhirContext(), forVersion, theRequestDetails);
|
||||
} else {
|
||||
EncodingEnum defaultResponseEncoding = theRequestDetails.getServer().getDefaultResponseEncoding();
|
||||
p = defaultResponseEncoding.newParser(theRequestDetails.getServer().getFhirContext());
|
||||
RestfulServerUtils.configureResponseParser(theRequestDetails, p);
|
||||
}
|
||||
|
||||
// This interceptor defaults to pretty printing unless the user
|
||||
// has specifically requested us not to
|
||||
boolean prettyPrintResponse = true;
|
||||
String[] prettyParams = parameters.get(Constants.PARAM_PRETTY);
|
||||
if (prettyParams != null && prettyParams.length > 0) {
|
||||
if (Constants.PARAM_PRETTY_VALUE_FALSE.equals(prettyParams[0])) {
|
||||
prettyPrintResponse = false;
|
||||
}
|
||||
}
|
||||
if (prettyPrintResponse) {
|
||||
p.setPrettyPrint(true);
|
||||
}
|
||||
|
||||
EncodingEnum encoding = p.getEncoding();
|
||||
String encoded = p.encodeResourceToString(theResource);
|
||||
|
||||
try {
|
||||
|
||||
if (theStatusCode > 299) {
|
||||
|
@ -545,27 +584,30 @@ public class ResponseHighlighterInterceptor {
|
|||
outputBuffer.append(" <body>");
|
||||
|
||||
outputBuffer.append("<p>");
|
||||
outputBuffer.append("This result is being rendered in HTML for easy viewing. ");
|
||||
outputBuffer.append("You may access this content as ");
|
||||
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMAT_JSON));
|
||||
outputBuffer.append("\">Raw JSON</a> or ");
|
||||
if (isBlank(theGraphqlResponse)) {
|
||||
outputBuffer.append("This result is being rendered in HTML for easy viewing. ");
|
||||
outputBuffer.append("You may access this content as ");
|
||||
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMAT_XML));
|
||||
outputBuffer.append("\">Raw XML</a>, ");
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMAT_JSON));
|
||||
outputBuffer.append("\">Raw JSON</a> or ");
|
||||
|
||||
outputBuffer.append(" or view this content in ");
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMAT_XML));
|
||||
outputBuffer.append("\">Raw XML</a>, ");
|
||||
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMATS_HTML_JSON));
|
||||
outputBuffer.append("\">HTML JSON</a> ");
|
||||
outputBuffer.append(" or view this content in ");
|
||||
|
||||
outputBuffer.append("or ");
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMATS_HTML_XML));
|
||||
outputBuffer.append("\">HTML XML</a>.");
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMATS_HTML_JSON));
|
||||
outputBuffer.append("\">HTML JSON</a> ");
|
||||
|
||||
outputBuffer.append("or ");
|
||||
outputBuffer.append("<a href=\"");
|
||||
outputBuffer.append(createLinkHref(parameters, Constants.FORMATS_HTML_XML));
|
||||
outputBuffer.append("\">HTML XML</a>.");
|
||||
}
|
||||
|
||||
Date startTime = (Date) theServletRequest.getAttribute(RestfulServer.REQUEST_START_TIME);
|
||||
if (startTime != null) {
|
||||
|
|
|
@ -106,7 +106,9 @@ public class GraphQLMethodBinding extends BaseMethodBinding<String> {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(String.class, theRequest.getParameters().get(Constants.PARAM_GRAPHQL_QUERY)[0])
|
||||
.add(String.class, responseString);
|
||||
.add(String.class, responseString)
|
||||
.add(HttpServletRequest.class, servletRequest)
|
||||
.add(HttpServletResponse.class, servletResponse);
|
||||
if (!theRequest.getInterceptorBroadcaster().callHooks(Pointcut.SERVER_OUTGOING_GRAPHQL_RESPONSE, params)) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.servlet.ServletHandler;
|
|||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
|
@ -387,6 +388,21 @@ public class ResponseHighlightingInterceptorTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHighlightGraphQLResponse() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/A/$graphql?query=" + UrlUtil.escapeUrlParam("{name}"));
|
||||
httpGet.addHeader("Accept", "text/html");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8);
|
||||
status.close();
|
||||
|
||||
ourLog.info("Resp: {}", responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertThat(responseContent, stringContainsInOrder(""foo""));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHighlightException() throws Exception {
|
||||
ResponseHighlighterInterceptor ic = ourInterceptor;
|
||||
|
@ -799,6 +815,14 @@ public class ResponseHighlightingInterceptorTest {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
|
||||
public static class GraphQLProvider {
|
||||
@GraphQL
|
||||
public String processGraphQlRequest(ServletRequestDetails theRequestDetails, @IdParam IIdType theId, @GraphQLQuery String theQuery) {
|
||||
return "{\"foo\":\"bar\"}";
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourServer = new Server(0);
|
||||
|
@ -827,7 +851,7 @@ public class ResponseHighlightingInterceptorTest {
|
|||
ourServlet.registerInterceptor(corsInterceptor);
|
||||
|
||||
ourServlet.registerInterceptor(ourInterceptor);
|
||||
ourServlet.setResourceProviders(patientProvider, new DummyBinaryResourceProvider());
|
||||
ourServlet.registerProviders(patientProvider, new DummyBinaryResourceProvider(), new GraphQLProvider());
|
||||
ourServlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE);
|
||||
ServletHolder servletHolder = new ServletHolder(ourServlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
|
|
Loading…
Reference in New Issue