Configuring a Custom Undertow Filter in WildFly: Difference between revisions
Line 11: | Line 11: | ||
=Overview= | =Overview= | ||
This article explains how to write and install a custom Undertow filter within WildFly. Note that the filter code is executed by one of the XNIO Worker's IO threads. The thread enters and ''exits'' the filter's code while the request processing is done later, on a different thread. | |||
In order to install the filter, you will need to wrap the filter class in a WildFly module, deploy the module and configure the Undertow subsystem to use the custom filter. | |||
=Write the Filter Class= | =Write the Filter Class= |
Revision as of 20:58, 20 January 2016
Internal
Example
Overview
This article explains how to write and install a custom Undertow filter within WildFly. Note that the filter code is executed by one of the XNIO Worker's IO threads. The thread enters and exits the filter's code while the request processing is done later, on a different thread.
In order to install the filter, you will need to wrap the filter class in a WildFly module, deploy the module and configure the Undertow subsystem to use the custom filter.
Write the Filter Class
For this specific example, the filter measures the request time. The implementation is interesting because the start watch event happens on a different thread than the one that triggers the stop watch event, unlike in Tomcat's case, where a filters' pre-invocation and post-invocation code is executed on the same thread.
This pattern is common for all Undertow's filters.
package com.novaordis.playground.wildfly.undertow.customfilter; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ResponseTime implements HttpHandler { private static final Logger log = LoggerFactory.getLogger(ResponseTime.class); private HttpHandler next; public ResponseTime(HttpHandler next) { this.next = next; } @Override public void handleRequest(HttpServerExchange exchange) throws Exception { log.info("before"); next.handleRequest(exchange); log.info("after"); } }
Important: the handler's code is executed by one of the XNIO Worker's IO threads. Those threads service NIO selectors, and it is critically important NOT to block them. For more details on non-blocking IO in Java, see NIO Concepts.
Create and Deploy a WildFly Module
In order to be made available to the Undertow subsystem, the custom filter code must be deployed as a WildFly Module. For more details on how to build and deploy a custom module, see:
Express the Module's Dependency on io.undertow.core
The filter code must implement so the module must have access to those classes. This is achieved by declaring the module's dependency on :
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="com.novaordis.playground.wildfly.custommodule" slot="1.0"> ... <dependencies> <module name="io.undertow.core"/> </dependencies> </module>
Also, you must list other modules dependencies your code needs, for example "org.slf4j":
.. <dependencies> ... <module name="org.slf4j"/> </dependencies> ...
Configure the Undertow Subsystem
Declare the Filter in the <filters> Section
... <subsystem xmlns="urn:jboss:domain:undertow:3.0"> ... <filters> ... <filter name="response-time" class-name="com.novaordis.playground.wildfly.undertow.customfilter.ResponseTime" module="com.novaordis.playground.wildfly.undertow.customfilter:1"/> </filters> </subsystem> ...
Module Version
If the module has been deployed in the "main" slot, no version information is required when configuring the filter. Otherwise, the version information can be specified after the module name and the ":" separator: module="com.novaordis.playground.wildfly.undertow.customfilter:1.0".
Declare a Reference to the Filter for a Specific Host
... <subsystem xmlns="urn:jboss:domain:undertow:3.0"> <server name="..."> ... <host name="..."> <location .../> ... <filter-ref name="response-time"/> ... </host> </server> ... </subsystem> ...