Understanding & Utilizing Apache Sling Filters in Adobe CQ5 / AEM
Dominik Süß, Senior Developer, pro!vision GmbH
Sling Component Filters in CQ5
1
• The Sling Request Invocation Chain
• Implementing own Sling Filters
• Use Cases and Samples
2
Agenda
!!!WARNING!!!
3
Sling Filters are a very generic and mighty extensionpoint. When
utilizing them you should always have in mind that AEM/CQ Core
functionality relies on the data provided by Sling, manipulation
of this data therefore may break CQ.
The Sling Request Invocation Chain
4
How the Sling Engine processes HTTP Requests
FilterManager
Sling Request Invocation Chain
5
SlingMainServlet
FilterChain
Scope: REQUEST
FilterChain
Scope: COMPONENT
Filter A
Filter B
Filter C
Registered as Services
(preferably via SCR Annotation)
Component Servlet
processRequest()dispatchRequest()
INCLUDE/FORWARD
SlingRequestProcessor
Implementing Sling Filters
6
How to use Filters as Extensionpoint
Registration of Filters
7
• Standard Servlet Filter (javax.servlet.Filter)
– Need to be registered as Service („manually“ or SlingFilter SCR Annotation)
• Order and FilterScopes can be defined
• Order defined by Serviceranking
• Filterscopes
– REQUEST
– COMPONENT
– ERROR
– INCLUDE *
– FORWARD *
* FilterChain executes COMPONENT scope for these scopes as well.
SCR Annotation
8
@SlingFilter(scope = SlingFilterScope.COMPONENT, order = -10000, metatype =
false)
public class MyComponentFilter implements javax.servlet.Filter {
@Override
public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
FilterChain pChain) throws IOException, ServletException {
// Implement Filter
// continue with filter chaining
pChain.doFilter(pRequest, pResponse);
}
}
Filter Order
9
• Existing Filters might use the deprecated „filter.order“ instead
„service.ranking“
• NOTE: SLING-2920 was identified while verifying this behavior – look up the
mailing list for further information how to use it for now
• Existing Filters and their execution ORDER can be inspected via
– http://<instance>:<port>/system/console/status-slingfilter
Check Filterconditions at first place
10
public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
FilterChain pChain) throws IOException, ServletException {
if (!(pRequest instanceof SlingHttpServletRequest)) {
throw new ServletException("Request is not a Sling HTTP request.");
}
if (isFilterEnabled(slingRequest)) {
// Implement Filter-Logic
} else {
// continue with filter chaining
pChain.doFilter(pRequest, pResponse);
}
}
• Check available Information from slingRequest if Filter should do anything.
• Be aware that these checks may be performed a lot especially for COMPONENT scope
Accessing and Using Data in Filter
11
public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
FilterChain pChain) throws IOException, ServletException {
if (!(pRequest instanceof SlingHttpServletRequest)) {
throw new ServletException("Request is not a Sling HTTP request.");
}
if (isFilterEnabled(slingRequest)) {
Resource resource = slingRequest.getResource(); // already resolved
if (null != resource) {
PrintWriter writer = pResponse.getWriter();
writer.write("<component resourceType="" + resource.getResourceType()
"">");
pChain.doFilter(pRequest, pResponse);
writer.write("</component>");
return;
}
}
pChain.doFilter(pRequest, pResponse);
}
Useful Wrapper Objects in Filters
12
• SlingHttpServletRequestWrapper
– Implement to override parts of the request
• E.g. Inject impersonated ResourceResolver*
• SlingHttpServletResponseWrapper
– Implement to inject additional logic to response
• E.g. inject own writer to buffer the response to perform some postprocessing
* Security-Note: Make sure you don’t create security holes this way – the request
should always respect the permissions of the current user!
Dispatch to other Resource
13
RequestDispatcher dispatcher =
slingRequest.getRequestDispatcher(otherResource);
dispatcher.forward(request, response);
Required in any situation where you need to redirect the request.
Note: You should be aware that a Dispatcher Forward or Include will retrigger
the FilterChain. Place such filters early in the Filterchain to prevent other
Filters to be executed twice.
Usecases & Samples
14
Usecases
15
• Logging
• Measuring
• Decoration
• Pre-Processing
• Post-Processing
• Manipulating Inclusions
Logging
16
• Allows to hook in Requestcentric logging at Sling Level
• It is possible to log even requests/includes of components which are not
part of the own application (like foundation components)
• Sample
– org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter
Measuring
17
• Since the Filterchain gets consulted at each call of a component they
provide a natural location to measure the actual usage of the system
• The concrete usecases depend on the goal of the application
• You should just add additional measuring if no other techniques like
loganalysis or available reports are not sufficient.
Decoration
18
• Adding generic but usecasespecific decoration to components
• Sample
– WCMDebugFilter ( for Requestparameter debug=layout)
• Further Usecase
– For specific selector: Metadata for third party systems like
• Search Parsers
• Integrating Systems (e.g. Portals)
Preprocessing
19
• Injecting data that needs to be available within the components
• Sample:
– WCMComponentFilter – generic logic that links CQ Authoring logic with Sling
Components
– I18nFilter – Injecting I18n Resource Bundles
• Further Usecases
– Build Java Bean and place in Request to be used via jsp:useBean and EL within
JSPs (Sepearation of businesslogic)*
* Just a proof of concept, impact of preprocessing on performance yet untested
Postprocessing
20
• Injecting custom writer to postprocess output
• Sample:
– RewriterFilter
• Further Usecases:
– Integration of thirt party markup (e.g. via Velocity or Freemarker)
– Injection of a generic Placeholderlogic (e.g. Personalization)
Manipulating Inclusions
21
• Redirecting , Skipping or manipulating further processing
• Samples:
– Mobile RedirectFilter (trigger Redirect with matching selector for device)
– TimeWarp Filter ( replacing ResourceData & corresponding Objects with Objects at
given Timestamp)
• Further Usecases
– Controlled Impersonation in Author Mode for Permissionpreview
(Publishpermissions)
– Component Level Caching (Record response to cache and answer subsequent
requests from cache)*
* Not yet verified, but might be a solution for partial caching where dispatcher caches
cannot be used
Some last words…
22
• The Apache Sling Stack is the core of CQ5 / AEM
• Apache Sling is an open source project that relies on an active community
• So – be part the community!
– Join the User and/or Dev Mailinglist
– File Bugs and contribute Patches
– Participate in community events to drive evolution of Apache Sling …
… like adaptTo() 2013 in Berlin (http://www.adaptto.org)
;)
Berlin
pro!vision GmbH
Wilmersdorfer Str. 50-51
10627 Berlin
Germany
Tel. +49 (30) 818828-50
E-Mail info@pro-vision.de
Frankfurt
pro!vision GmbH
Löwengasse 27 A
60385 Frankfurt am Main
Germany
Tel. +49 (69) 8700328-0
E-Mail info@pro-vision.de
Karim Khan
Tel. +49 (69) 8700328-0
E-Mail kkhan@pro-vision.de
Contact
23

Sling Component Filters in CQ5

  • 1.
    Understanding & UtilizingApache Sling Filters in Adobe CQ5 / AEM Dominik Süß, Senior Developer, pro!vision GmbH Sling Component Filters in CQ5 1
  • 2.
    • The SlingRequest Invocation Chain • Implementing own Sling Filters • Use Cases and Samples 2 Agenda
  • 3.
    !!!WARNING!!! 3 Sling Filters area very generic and mighty extensionpoint. When utilizing them you should always have in mind that AEM/CQ Core functionality relies on the data provided by Sling, manipulation of this data therefore may break CQ.
  • 4.
    The Sling RequestInvocation Chain 4 How the Sling Engine processes HTTP Requests
  • 5.
    FilterManager Sling Request InvocationChain 5 SlingMainServlet FilterChain Scope: REQUEST FilterChain Scope: COMPONENT Filter A Filter B Filter C Registered as Services (preferably via SCR Annotation) Component Servlet processRequest()dispatchRequest() INCLUDE/FORWARD SlingRequestProcessor
  • 6.
    Implementing Sling Filters 6 Howto use Filters as Extensionpoint
  • 7.
    Registration of Filters 7 •Standard Servlet Filter (javax.servlet.Filter) – Need to be registered as Service („manually“ or SlingFilter SCR Annotation) • Order and FilterScopes can be defined • Order defined by Serviceranking • Filterscopes – REQUEST – COMPONENT – ERROR – INCLUDE * – FORWARD * * FilterChain executes COMPONENT scope for these scopes as well.
  • 8.
    SCR Annotation 8 @SlingFilter(scope =SlingFilterScope.COMPONENT, order = -10000, metatype = false) public class MyComponentFilter implements javax.servlet.Filter { @Override public void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException { // Implement Filter // continue with filter chaining pChain.doFilter(pRequest, pResponse); } }
  • 9.
    Filter Order 9 • ExistingFilters might use the deprecated „filter.order“ instead „service.ranking“ • NOTE: SLING-2920 was identified while verifying this behavior – look up the mailing list for further information how to use it for now • Existing Filters and their execution ORDER can be inspected via – http://<instance>:<port>/system/console/status-slingfilter
  • 10.
    Check Filterconditions atfirst place 10 public void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException { if (!(pRequest instanceof SlingHttpServletRequest)) { throw new ServletException("Request is not a Sling HTTP request."); } if (isFilterEnabled(slingRequest)) { // Implement Filter-Logic } else { // continue with filter chaining pChain.doFilter(pRequest, pResponse); } } • Check available Information from slingRequest if Filter should do anything. • Be aware that these checks may be performed a lot especially for COMPONENT scope
  • 11.
    Accessing and UsingData in Filter 11 public void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException, ServletException { if (!(pRequest instanceof SlingHttpServletRequest)) { throw new ServletException("Request is not a Sling HTTP request."); } if (isFilterEnabled(slingRequest)) { Resource resource = slingRequest.getResource(); // already resolved if (null != resource) { PrintWriter writer = pResponse.getWriter(); writer.write("<component resourceType="" + resource.getResourceType() "">"); pChain.doFilter(pRequest, pResponse); writer.write("</component>"); return; } } pChain.doFilter(pRequest, pResponse); }
  • 12.
    Useful Wrapper Objectsin Filters 12 • SlingHttpServletRequestWrapper – Implement to override parts of the request • E.g. Inject impersonated ResourceResolver* • SlingHttpServletResponseWrapper – Implement to inject additional logic to response • E.g. inject own writer to buffer the response to perform some postprocessing * Security-Note: Make sure you don’t create security holes this way – the request should always respect the permissions of the current user!
  • 13.
    Dispatch to otherResource 13 RequestDispatcher dispatcher = slingRequest.getRequestDispatcher(otherResource); dispatcher.forward(request, response); Required in any situation where you need to redirect the request. Note: You should be aware that a Dispatcher Forward or Include will retrigger the FilterChain. Place such filters early in the Filterchain to prevent other Filters to be executed twice.
  • 14.
  • 15.
    Usecases 15 • Logging • Measuring •Decoration • Pre-Processing • Post-Processing • Manipulating Inclusions
  • 16.
    Logging 16 • Allows tohook in Requestcentric logging at Sling Level • It is possible to log even requests/includes of components which are not part of the own application (like foundation components) • Sample – org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter
  • 17.
    Measuring 17 • Since theFilterchain gets consulted at each call of a component they provide a natural location to measure the actual usage of the system • The concrete usecases depend on the goal of the application • You should just add additional measuring if no other techniques like loganalysis or available reports are not sufficient.
  • 18.
    Decoration 18 • Adding genericbut usecasespecific decoration to components • Sample – WCMDebugFilter ( for Requestparameter debug=layout) • Further Usecase – For specific selector: Metadata for third party systems like • Search Parsers • Integrating Systems (e.g. Portals)
  • 19.
    Preprocessing 19 • Injecting datathat needs to be available within the components • Sample: – WCMComponentFilter – generic logic that links CQ Authoring logic with Sling Components – I18nFilter – Injecting I18n Resource Bundles • Further Usecases – Build Java Bean and place in Request to be used via jsp:useBean and EL within JSPs (Sepearation of businesslogic)* * Just a proof of concept, impact of preprocessing on performance yet untested
  • 20.
    Postprocessing 20 • Injecting customwriter to postprocess output • Sample: – RewriterFilter • Further Usecases: – Integration of thirt party markup (e.g. via Velocity or Freemarker) – Injection of a generic Placeholderlogic (e.g. Personalization)
  • 21.
    Manipulating Inclusions 21 • Redirecting, Skipping or manipulating further processing • Samples: – Mobile RedirectFilter (trigger Redirect with matching selector for device) – TimeWarp Filter ( replacing ResourceData & corresponding Objects with Objects at given Timestamp) • Further Usecases – Controlled Impersonation in Author Mode for Permissionpreview (Publishpermissions) – Component Level Caching (Record response to cache and answer subsequent requests from cache)* * Not yet verified, but might be a solution for partial caching where dispatcher caches cannot be used
  • 22.
    Some last words… 22 •The Apache Sling Stack is the core of CQ5 / AEM • Apache Sling is an open source project that relies on an active community • So – be part the community! – Join the User and/or Dev Mailinglist – File Bugs and contribute Patches – Participate in community events to drive evolution of Apache Sling … … like adaptTo() 2013 in Berlin (http://www.adaptto.org) ;)
  • 23.
    Berlin pro!vision GmbH Wilmersdorfer Str.50-51 10627 Berlin Germany Tel. +49 (30) 818828-50 E-Mail info@pro-vision.de Frankfurt pro!vision GmbH Löwengasse 27 A 60385 Frankfurt am Main Germany Tel. +49 (69) 8700328-0 E-Mail info@pro-vision.de Karim Khan Tel. +49 (69) 8700328-0 E-Mail kkhan@pro-vision.de Contact 23