You need to add the filter mapping directly to the DeploymentInfo structure using
addFilterUrlMapping or addFilterServletNameMapping.
This is because there is a global ordering of filter mappings that determines the order
filters get invoked in, while there is no such concept for Servlets.
Stuart
----- Original Message -----
From: "Mondain" <mondain(a)gmail.com>
To: undertow-dev(a)lists.jboss.org
Sent: Thursday, 6 February, 2014 7:45:51 PM
Subject: Re: [undertow-dev] Embedding undertow into Red5
I've got a first rev of my web.xml parser now and I've run into a curious
thing regarding filters. How do I add the url-pattern to a FilterInfo
mapping as I do with a ServletInfo mapping?
On Thu, Feb 6, 2014 at 7:35 AM, Mondain < mondain(a)gmail.com > wrote:
Thanks for the reply, now I know I have more work to do.
On Thu, Feb 6, 2014 at 12:33 AM, Stuart Douglas < sdouglas(a)redhat.com >
wrote:
From: "Mondain" < mondain(a)gmail.com >
To: undertow-dev(a)lists.jboss.org
Sent: Thursday, 6 February, 2014 9:36:34 AM
Subject: [undertow-dev] Embedding undertow into Red5
I'm a core dev on the Red5 project and I would like to offer undertow as an
alternative to our current embedded tomcat server. I have read through the
examples, unit tests, and documentation regarding undertow. I have coded and
run my "plugin" implementation, but all I am getting are "Not Found"
responses in the browser. My suspicion is that the web.xml is not being read
in and / or parsed, but I'm not sure since I'm new with this code base.
Below you will see how I'm setting up and starting things; let me know what
I'm doing incorrectly.
Hi Mondain,
You are correct in your suspicion that Undertow is not parsing the web.xml.
Undertow provides an embedded Servlet implementation but it does not
implement the discovery/parsing parts, as this is left up to the embedding
application.
Basically instead of using web.xml you need to add servlets, filters etc to
the DeploymentInfo structure programatically. The main reason for this is
basically because Undertow is designed to integrate well into other
applications (especially Wildfly), and application servers generally provide
their own implementation of parsers, annotation processors etc.
With that said though at some point we will probably do a standalone
parser/annotation processor to make this work out of the box (probably by
just copying the relevant bits from wildfly and packaging them in their own
jar). This is a fairly low priority item at the moment though.
Stuart
//get a reference to the current threads classloader
final ClassLoader originalClassLoader =
Thread.currentThread().getContextClassLoader();
// root location for servlet container
String serverRoot = System.getProperty("red5.root");
String confRoot = System.getProperty("red5.config_root");
System.setProperty("UNDERTOW_HOME", serverRoot);
if (webappFolder == null) {
// Use default webapps directory
webappFolder = FileUtil.formatPath(System.getProperty("red5.root"),
"/webapps");
}
System.setProperty("red5.webapp.root", webappFolder);
// scan the sub directories to determine our context paths
buildContextPathList(webappFolder);
try {
// create our servlet container
container = ServletContainer.Factory.newInstance();
// create a root path handler
final PathHandler rootHandler = new PathHandler();
// create one server and use it everywhere
Undertow.Builder builder = Undertow.builder();
// loop through connectors adding listeners to the builder
for (UndertowConnector undertowConnector : connectors) {
InetSocketAddress addr = undertowConnector.getSocketAddress();
builder.addListener(addr.getPort(), addr.getHostName(),
(undertowConnector.isSecure() ? ListenerType.HTTPS : ListenerType.HTTP));
}
// loop the other contexts
for (String contextPath : contextPaths) {
// create a class loader for the context
ClassLoader classLoader = buildWebClassLoader(originalClassLoader,
webappFolder, contextPath);
// create deployment info
DeploymentInfo info = deployment()
.setClassLoader(classLoader)
.setContextPath(contextPath.equalsIgnoreCase("/ROOT") ? "/" :
contextPath)
.setDefaultEncoding("UTF-8")
.setDeploymentName(contextPath.substring(1) + ".war")
.setUrlEncoding("UTF-8");
// add the new deployment to the servlet container
DeploymentManager manager = container.addDeployment(info);
// deploy
manager.deploy();
// add path
rootHandler.addPrefixPath(info.getContextPath(), manager.start());
// get deployment
Deployment deployment = manager.getDeployment();
// get servlet context
final ServletContext servletContext = deployment.getServletContext();
log.debug("Context initialized: {}", servletContext.getContextPath());
try {
log.debug("Context: {}", servletContext);
final ClassLoader webClassLoader = info.getClassLoader();
log.debug("Webapp classloader: {}", webClassLoader);
// get the (spring) config file path
final String contextConfigLocation =
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONFIG_LOCATION_PARAM)
== null ? defaultSpringConfigLocation
:
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONFIG_LOCATION_PARAM);
log.debug("Spring context config location: {}", contextConfigLocation);
// get the (spring) parent context key
final String parentContextKey =
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.LOCATOR_FACTORY_KEY_PARAM)
== null ? defaultParentContextKey
:
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.LOCATOR_FACTORY_KEY_PARAM);
// set current threads classloader to the webapp classloader
Thread.currentThread().setContextClassLoader(webClassLoader);
// create a thread to speed-up application loading
Thread thread = new Thread("Launcher:" + servletContext.getContextPath()) {
public void run() {
//set thread context classloader to web classloader
Thread.currentThread().setContextClassLoader(webClassLoader);
//get the web app's parent context
ApplicationContext parentContext = null;
if (applicationContext.containsBean(parentContextKey)) {
parentContext = (ApplicationContext)
applicationContext.getBean(parentContextKey);
} else {
log.warn("Parent context was not found: {}", parentContextKey);
}
// create a spring web application context
final String contextClass =
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONTEXT_CLASS_PARAM)
== null ? XmlWebApplicationContext.class
.getName() :
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONTEXT_CLASS_PARAM);
// web app context (spring)
ConfigurableWebApplicationContext appctx = null;
try {
Class<?> clazz = Class.forName(contextClass, true, webClassLoader);
appctx = (ConfigurableWebApplicationContext) clazz.newInstance();
// set the root webapp ctx attr on the each servlet context so spring can
find it later
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
appctx);
appctx.setConfigLocations(new String[] { contextConfigLocation });
appctx.setServletContext(servletContext);
// set parent context or use current app context
if (parentContext != null) {
appctx.setParent(parentContext);
} else {
appctx.setParent(applicationContext);
}
// refresh the factory
appctx.refresh();
appctx.start();
} catch (Throwable e) {
throw new RuntimeException("Failed to load webapplication context class", e);
}
}
};
thread.setDaemon(true);
thread.start();
} catch (Throwable t) {
t.printStackTrace();
} finally {
//reset the classloader
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}
// Dump deployments list
if (log.isDebugEnabled()) {
for (String deployment : container.listDeployments()) {
log.debug("Container deployment: {}", deployment);
}
}
// add a root handler
builder.setHandler(rootHandler);
// build the server instance
server = builder.build();
log.info ("Starting Undertow");
server.start();
} catch (Exception e) {
if (e instanceof BindException || e.getMessage().indexOf("BindException") !=
-1) {
log.error("Error loading undertow, unable to bind connector. You may not have
permission to use the selected port", e);
} else {
log.error("Error loading undertow", e);
}
}
Regards,
Paul
--
http://gregoire.org/
http://code.google.com/p/red5/
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev
--
http://gregoire.org/
http://code.google.com/p/red5/
--
http://gregoire.org/
http://code.google.com/p/red5/
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev