This is an automated email from the ASF dual-hosted git repository. bdelacretaz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-site.git
commit a5225ad87d34a4a5c52d5ddbdce48cea3e977654 Author: Bertrand Delacretaz <[email protected]> AuthorDate: Tue Jun 16 17:11:33 2020 +0200 Add internal request helpers documentation --- .../documentation/bundles/servlet-helpers.md | 101 +++++++++++++++++++-- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/src/main/jbake/content/documentation/bundles/servlet-helpers.md b/src/main/jbake/content/documentation/bundles/servlet-helpers.md index e8f538d..23b6492 100644 --- a/src/main/jbake/content/documentation/bundles/servlet-helpers.md +++ b/src/main/jbake/content/documentation/bundles/servlet-helpers.md @@ -1,21 +1,103 @@ -title=Sling Servlet Helpers +title=Sling Servlet Helpers and Internal Requests type=page status=published -tags=servlets +tags=servlets,requests ~~~~~~ -The Sling Servlet Helpers bundle provides mock implementations of the -`SlingHttpServletRequest`, `SlingHttpServletResponse` and related classes. +The [Sling Servlet Helpers](https://github.com/apache/sling-org-apache-sling-servlet-helpers) +bundle provides mock implementations of the `SlingHttpServletRequest`, `SlingHttpServletResponse` +and related classes, along with fluent `SlingInternalRequest` and `ServletInternalRequest` +helpers for internal requests. -Those mock implementations are meant to be used in tests and also with services -like the `SlingRequestProcessor` when making requests to that service outside of -an HTTP request processing context. +The mock request/response implementations are meant to be used in tests and +also with services like the `SlingRequestProcessor` when making requests to +that service outside of an HTTP request processing context. + +They are used under the hood by the `SlingInternalRequest` and +`ServletInternalRequest` helpers to provide a simple and foolproof way +of executing internal Sling requests. + +The [GraphQL Core](https://github.com/apache/sling-org-apache-sling-graphql-core/) module, +for example, uses them for internal requests that retrieve a GraphQL schema dynamically, +taking into account the current Resource and request selectors. See the [automated tests](https://github.com/apache/sling-org-apache-sling-servlet-helpers) -of the `servlet-helpers` module for more info. +of the `servlet-helpers` module for more info, besides the general +descriptions found below. + + +## InternalRequest helpers + +The internal request helpers use either a `SlingRequestProcessor` to execute internal requests using +the full Sling request processing pipeline, or a `ServletResolver` to resolve and call a Servlet or Script +directly. The necessary "mocking" of requests are responses happens under the hood which leads to much +simpler code than using the mock request/response classes directly. + +The latter direct-to-servlet (or script) mode is more efficient but less faithful to the way HTTP requests +are processed, as it bypasses all Servlet Filters, in particular. + +Here's an example using the `SlingInternalRequest` helper - see the test code for more. The +`ServletInternalRequest` API is very similar but takes a `ServletResolver` and an actual `Resource` +as its starting points. + + OutputStream os = new SlingInternalRequest(resourceResolver, slingRequestProcessor, path) + .withResourceType("website/article/news") + .withResourceSuperType("website/article") + .withSelectors("print", "a4") + .withExtension("pdf") + .execute() + .checkStatus(200) + .checkResponseContentType("application/pdf") + .getResponse() + .getOutputStream() + +Not all servlets and scripts are suitable to be called by the `ServletInternalRequest`, depending +on their "environmental" requirements like `Request` attributes for example. + + +In case of doubt you can start with the `SlingInternalRequest` helper which uses the `SlingRequestProcessor` +so that servlets or scripts should see no difference compared to HTTP requests. And once that works you can +try the more efficient `ServletInternalRequest` helper to check if your scripts and servlets support +that mode. + +In both cases, the standard [Sling Servlet/Script resolution mechanism](/documentation/the-sling-engine/servlets.html) +is used, which can be useful to execute scripts that are resolved based on the current resource type, for non-HTTP +operations. Inventing HTTP method names for this is fine and allows for reusing this powerful resolution mechanism +in other contexts. + +### Troubleshooting internal requests + +To help map log messages to internal requests, as several of those might be used to handle a single +HTTP request, the `InternalRequest` parent class of the helpers discussed above sets a log4j +_Mapped Diagnostic Context_ (MDC) value with the `sling.InternalRequest`key. + +The value of that key provides the essential attributes of the current request, so that using a log +formatting pattern that displays it, like: + + %-5level [%-50logger{50}] %message ## %mdc{sling.InternalRequest} %n + +Causes the internal request information to be logged, like in this example (lines folded +for readability): + + DEBUG [o.a.s.s.internalrequests.SlingInternalRequest ] + Executing request using the SlingRequestProcessor + ## GET P=/content/tags/monitor+array S=null EXT=json RT=samples/tag(null) + WARN [org.apache.sling.engine.impl.request.RequestData ] + SlingRequestProgressTracker not found in request attributes + ## GET P=/content/tags/monitor+array S=null EXT=json RT=samples/tag(null) + DEBUG [o.a.s.s.resolver.internal.SlingServletResolver ] + Using cached servlet /apps/samples/tag/json.gql + ## GET P=/content/tags/monitor+array S=null EXT=json RT=samples/tag(null) + +In these log messages, `GET P=/content/tags/monitor+array S=null EXT=json RT=samples/tag(null)` points +to the current internal request, showing its method, path, selectors, extension, resource type and +resource supertype. + +## Mock Request/Response classes -## Usage +These are useful for testing or if you need to do something that the internal request helpers +do not support. ### SlingHttpServletRequest @@ -82,3 +164,4 @@ Example for preparing a sling response which can collect the data that was writt // validate response body as binary data assertArrayEquals(TEST_DATA, response.getOutput()); +
