I have set up a DoSFilter for my webapp and have deployed it in Jetty. Things works nicely. However I occasionally want to change the Filter configuration. To do that I always have to change the web.xml and redeploy the webapps which is rather inconvenient. I would want to do this dynamically instead.
I learned that I can configure QoSFilter and DoSFilter using JMX since they are exposed as MBeans inside Jetty. I am having trouble in doing the same.
So far, I have been able to do the following:
<filter>
<filter-name>DoSFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.DoSFilter</filter-class>
<init-param>
<param-name>maxRequestsPerSec</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>requestPort</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>maxRequestMs</param-name>
<param-value>600000</param-value>
</init-param>
<init-param>
<param-name>excludePatterns</param-name>
<param-value>/healthCheck</param-value>
</init-param>
<init-param>
<param-name>managedAttr</param-name>
<param-value>true</param-value>
</init-param>
</filter>
The managedAttr param is set to true so that this filter is added to the ServletContext thereby exposing it as a MBean.
3 I've also added a context param asking jetty to make DoSFilter as a MBean as follows
<context-param>
<param-name>org.eclipse.jetty.server.context.ManagedAttributes</param-name>
<param-value>DoSFilter</param-value>
</context-param>
Now this works, but not the way I want it to. When I open Jconsole and go to the MBeans tab I can see the DoSFilter under org.eclipse.jetty.servlets.DoSFilter.
When I move down the tree, however, I can only see metadata information of that MBean. There are no attributes or operations attached to that MBean and I can't change anything.
Please advise. Am I doing anything wrong here?
My webapp is a spring application and there is only one servlet defined
<servlet>
<servlet-name>capture</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Thanks
UPDATE: I tried configuring this in Embedded Jetty and things seem to work fine. But I still can't get this to work in a standalone deployment.
Following is how I tested embedded Server
public static void main(String[] args) throws Exception {
Server server = new Server();
Connector connector = new ServerConnector(server);
server.addConnector(connector);
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
MBeanContainer mbeanContainer = new MBeanContainer(mbeanServer);
server.addBean(mbeanContainer);
WebAppContext context = new WebAppContext(server,"/home/neo/ideaprojects/helloworld/src/main/webapp/", "/");
DoSFilter filter = new DoSFilter();
FilterHolder holder = new FilterHolder(filter);
String name = "DosFilter";
holder.setName(name);
holder.setInitParameter("managedAttr", "true");
context.setInitParameter(ServletContextHandler.MANAGED_ATTRIBUTES, name);
context.addFilter(holder, "/*", EnumSet.of(DispatcherType.FORWARD));
// ----------------------------------------
server.start();
server.join();
}
Updated
I see the following debug logs in jetty standalone mode
2014-04-05 20:18:32.834:DBUG:oejj.MBeanContainer:main: beanAdded o.e.j.w.WebAppContext@ace3c1b{/,file:/tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-6506776307143437350.dir/webapp/,STARTING}{/ROOT.war}->org.eclipse.jetty.servlets.DoSFilter@6d4d63ba
2014-04-05 20:18:32.835:DBUG:oejj.ObjectMBean:main: ObjectMbean: mbeanFor org.eclipse.jetty.servlets.DoSFilter@6d4d63ba mClass=class org.eclipse.jetty.jmx.ObjectMBean
2014-04-05 20:18:32.835:DBUG:oejj.ObjectMBean:main: mbeanFor org.eclipse.jetty.servlets.DoSFilter@6d4d63ba is org.eclipse.jetty.jmx.ObjectMBean@34bb5def
2014-04-05 20:18:32.835:DBUG:oejj.ObjectMBean:main: No MBean Influence for DoSFilter
2014-04-05 20:18:32.835:DBUG:oejj.ObjectMBean:main: No MBean Influence for Object
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: No MBean Influence for Filter
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Influence Count: 3
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: No @ManagedObject declared on class org.eclipse.jetty.servlets.DoSFilter
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Influenced by: org.eclipse.jetty.servlets.DoSFilter
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Annotations not found for: org.eclipse.jetty.servlets.DoSFilter
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Influenced by: java.lang.Object
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Annotations not found for: java.lang.Object
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Influenced by: javax.servlet.Filter
2014-04-05 20:18:32.836:DBUG:oejj.ObjectMBean:main: Annotations not found for: javax.servlet.Filter
2014-04-05 20:18:32.836:DBUG:oejj.MBeanContainer:main: Registered org.eclipse.jetty.servlets:context=ROOT,type=dosfilter,id=0
I found the issue. The issue was with the jars I believe. I extended the DOSFilter to replace some headers before the check so I had to include the servlets jar in my webapp. I had a whole bunch of other jetty-*.jar in my WEB-INF/lib folder as well(for some other debug purporse) which somehow were creating conflicts. The webapp was a maven project so I added provided to all jetty based modules in my webapp so that these jars don't get packed into my deployable war. This solved the problem.