292814 used filter/servlet name for managed attribute
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1928 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
41884b613c
commit
3e70a7f7ac
|
@ -79,6 +79,13 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful
|
||||
{
|
||||
private static final ThreadLocal<Context> __context=new ThreadLocal<Context>();
|
||||
|
||||
/**
|
||||
* If a context attribute with this name is set, it is interpreted as a
|
||||
* comma separated list of attribute name. Any other context attributes that
|
||||
* are set with a name from this list will result in a call to {@link #setManagedAttribute(String, Object)},
|
||||
* which typically initiates the creation of a JMX MBean for the attribute value.
|
||||
*/
|
||||
public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes";
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -618,7 +625,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
{
|
||||
String name = (String)e.nextElement();
|
||||
Object value = _scontext.getAttribute(name);
|
||||
setManagedAttribute(name,value);
|
||||
checkManagedAttribute(name,value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,7 +689,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
while(e.hasMoreElements())
|
||||
{
|
||||
String name = (String)e.nextElement();
|
||||
setManagedAttribute(name,null);
|
||||
checkManagedAttribute(name,null);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@ -999,7 +1006,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
*/
|
||||
public void removeAttribute(String name)
|
||||
{
|
||||
setManagedAttribute(name,null);
|
||||
checkManagedAttribute(name,null);
|
||||
_attributes.removeAttribute(name);
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1019,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
*/
|
||||
public void setAttribute(String name, Object value)
|
||||
{
|
||||
setManagedAttribute(name,value);
|
||||
checkManagedAttribute(name,value);
|
||||
_attributes.setAttribute(name,value);
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1036,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
while (e.hasMoreElements())
|
||||
{
|
||||
String name = (String)e.nextElement();
|
||||
setManagedAttribute(name,attributes.getAttribute(name));
|
||||
checkManagedAttribute(name,attributes.getAttribute(name));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1040,7 +1047,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
{
|
||||
String name = (String)e.nextElement();
|
||||
Object value=attributes.getAttribute(name);
|
||||
setManagedAttribute(name,value);
|
||||
checkManagedAttribute(name,value);
|
||||
_attributes.setAttribute(name,value);
|
||||
}
|
||||
}
|
||||
|
@ -1053,26 +1060,26 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
while (e.hasMoreElements())
|
||||
{
|
||||
String name = (String)e.nextElement();
|
||||
setManagedAttribute(name,null);
|
||||
checkManagedAttribute(name,null);
|
||||
}
|
||||
_attributes.clearAttributes();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void setManagedAttribute(String name, Object value)
|
||||
public void checkManagedAttribute(String name, Object value)
|
||||
{
|
||||
if (_managedAttributes!=null && _managedAttributes.containsKey(name))
|
||||
{
|
||||
Object old =_managedAttributes.put(name,value);
|
||||
if (old!=null)
|
||||
getServer().getContainer().removeBean(old);
|
||||
if (value!=null)
|
||||
{
|
||||
if (_logger.isDebugEnabled()) _logger.debug("Managing "+name);
|
||||
getServer().getContainer().addBean(value);
|
||||
}
|
||||
setManagedAttribute(name,value);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setManagedAttribute(String name, Object value)
|
||||
{
|
||||
Object old =_managedAttributes.put(name,value);
|
||||
getServer().getContainer().update(this,old,value,name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -1753,7 +1760,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
return;
|
||||
}
|
||||
|
||||
setManagedAttribute(name,value);
|
||||
checkManagedAttribute(name,value);
|
||||
Object old_value=_contextAttributes.getAttribute(name);
|
||||
|
||||
if (value==null)
|
||||
|
@ -1786,7 +1793,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
|
|||
*/
|
||||
public synchronized void removeAttribute(String name)
|
||||
{
|
||||
setManagedAttribute(name,null);
|
||||
checkManagedAttribute(name,null);
|
||||
|
||||
if (_contextAttributes==null)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@ import javax.servlet.http.HttpSessionBindingListener;
|
|||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.thread.Timeout;
|
||||
|
||||
|
@ -60,35 +61,53 @@ import org.eclipse.jetty.util.thread.Timeout;
|
|||
* The {@link #extractUserId(ServletRequest request)} function should be
|
||||
* implemented, in order to uniquely identify authenticated users.
|
||||
* <p>
|
||||
* The following init parameters control the behavior of the filter:
|
||||
* The following init parameters control the behavior of the filter:<dl>
|
||||
*
|
||||
* maxRequestsPerSec the maximum number of requests from a connection per
|
||||
* <dt>maxRequestsPerSec</dt>
|
||||
* <dd>the maximum number of requests from a connection per
|
||||
* second. Requests in excess of this are first delayed,
|
||||
* then throttled.
|
||||
* then throttled.</dd>
|
||||
*
|
||||
* delayMs is the delay given to all requests over the rate limit,
|
||||
* <dt>delayMs</dt>
|
||||
* <dd>is the delay given to all requests over the rate limit,
|
||||
* before they are considered at all. -1 means just reject request,
|
||||
* 0 means no delay, otherwise it is the delay.
|
||||
* 0 means no delay, otherwise it is the delay.</dd>
|
||||
*
|
||||
* maxWaitMs how long to blocking wait for the throttle semaphore.
|
||||
* <dt>maxWaitMs</dt>
|
||||
* <dd>how long to blocking wait for the throttle semaphore.</dd>
|
||||
*
|
||||
* throttledRequests is the number of requests over the rate limit able to be
|
||||
* considered at once.
|
||||
* <dt>throttledRequests</dt>
|
||||
* <dd>is the number of requests over the rate limit able to be
|
||||
* considered at once.</dd>
|
||||
*
|
||||
* throttleMs how long to async wait for semaphore.
|
||||
* <dt>throttleMs</dt>
|
||||
* <dd>how long to async wait for semaphore.</dd>
|
||||
*
|
||||
* maxRequestMs how long to allow this request to run.
|
||||
* <dt>maxRequestMs</dt>
|
||||
* <dd>how long to allow this request to run.</dd>
|
||||
*
|
||||
* maxIdleTrackerMs how long to keep track of request rates for a connection,
|
||||
* before deciding that the user has gone away, and discarding it
|
||||
* <dt>maxIdleTrackerMs</dt>
|
||||
* <dd>how long to keep track of request rates for a connection,
|
||||
* before deciding that the user has gone away, and discarding it</dd>
|
||||
*
|
||||
* insertHeaders if true , insert the DoSFilter headers into the response. Defaults to true.
|
||||
* <dt>insertHeaders</dt>
|
||||
* <dd>if true , insert the DoSFilter headers into the response. Defaults to true.</dd>
|
||||
*
|
||||
* trackSessions if true, usage rate is tracked by session if a session exists. Defaults to true.
|
||||
* <dt>trackSessions</dt>
|
||||
* <dd>if true, usage rate is tracked by session if a session exists. Defaults to true.</dd>
|
||||
*
|
||||
* remotePort if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.
|
||||
* <dt>remotePort</dt>
|
||||
* <dd>if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.</dd>
|
||||
*
|
||||
* ipWhitelist a comma-separated list of IP addresses that will not be rate limited
|
||||
* <dt>ipWhitelist</dt>
|
||||
* <dd>a comma-separated list of IP addresses that will not be rate limited</dd>
|
||||
*
|
||||
* <dt>managedAttr</dt>
|
||||
* <dd>if set to true, then this servlet is set as a {@link ServletContext} attribute with the
|
||||
* filter name as the attribute name. This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
|
||||
* manage the configuration of the filter.</dd>
|
||||
* </dl>
|
||||
* </p>
|
||||
*/
|
||||
|
||||
public class DoSFilter implements Filter
|
||||
|
@ -96,7 +115,6 @@ public class DoSFilter implements Filter
|
|||
final static String __TRACKER = "DoSFilter.Tracker";
|
||||
final static String __THROTTLED = "DoSFilter.Throttled";
|
||||
|
||||
final static String __DEFAULT_ATTR_PREFIX = "DoSFilter";
|
||||
final static int __DEFAULT_MAX_REQUESTS_PER_SEC = 25;
|
||||
final static int __DEFAULT_DELAY_MS = 100;
|
||||
final static int __DEFAULT_THROTTLE = 5;
|
||||
|
@ -105,7 +123,7 @@ public class DoSFilter implements Filter
|
|||
final static long __DEFAULT_MAX_REQUEST_MS_INIT_PARAM=30000L;
|
||||
final static long __DEFAULT_MAX_IDLE_TRACKER_MS_INIT_PARAM=30000L;
|
||||
|
||||
final static String ATTR_PREFIX_INIT_PARAM = "attrPrefix";
|
||||
final static String MANAGED_ATTR_INIT_PARAM="managedAttr";
|
||||
final static String MAX_REQUESTS_PER_S_INIT_PARAM = "maxRequestsPerSec";
|
||||
final static String DELAY_MS_INIT_PARAM = "delayMs";
|
||||
final static String THROTTLED_REQUESTS_INIT_PARAM = "throttledRequests";
|
||||
|
@ -154,11 +172,6 @@ public class DoSFilter implements Filter
|
|||
{
|
||||
_context = filterConfig.getServletContext();
|
||||
|
||||
String attrPrefix = __DEFAULT_ATTR_PREFIX;
|
||||
if (filterConfig.getInitParameter(ATTR_PREFIX_INIT_PARAM)!=null)
|
||||
attrPrefix=filterConfig.getInitParameter(ATTR_PREFIX_INIT_PARAM);
|
||||
_name = attrPrefix;
|
||||
|
||||
_queue = new Queue[getMaxPriority() + 1];
|
||||
_listener = new ContinuationListener[getMaxPriority() + 1];
|
||||
for (int p = 0; p < _queue.length; p++)
|
||||
|
@ -275,10 +288,8 @@ public class DoSFilter implements Filter
|
|||
});
|
||||
_timerThread.start();
|
||||
|
||||
if (_context!=null)
|
||||
{
|
||||
_context.setAttribute("org.eclipse.jetty.servlets."+_name,this);
|
||||
}
|
||||
if (_context!=null && Boolean.parseBoolean(filterConfig.getInitParameter(MANAGED_ATTR_INIT_PARAM)))
|
||||
_context.setAttribute(filterConfig.getFilterName(),this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,9 +60,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|||
* the web application.
|
||||
* <p>
|
||||
* To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger"
|
||||
* are set as context attributes prefixed with "org.eclipse.jetty.servlets."+name
|
||||
* (unless otherwise set with attrPrefix). This attribute prefix is also used for the
|
||||
* logger name.
|
||||
* are set as context attributes prefixed with the servlet name.
|
||||
* <p>
|
||||
* The following init parameters may be used to configure the servlet: <ul>
|
||||
* <li>name - Name of Proxy servlet (default: "ProxyServlet"
|
||||
|
@ -92,7 +90,6 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
protected ServletConfig _config;
|
||||
protected ServletContext _context;
|
||||
protected String _name="ProxyServlet";
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* (non-Javadoc)
|
||||
|
@ -111,17 +108,14 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
try
|
||||
{
|
||||
String t = config.getInitParameter("attrPrefix");
|
||||
if (t!=null)
|
||||
_name=t;
|
||||
_log= Log.getLogger("org.eclipse.jetty.servlets."+_name);
|
||||
_log= Log.getLogger("org.eclipse.jetty.servlets."+config.getServletName());
|
||||
|
||||
t = config.getInitParameter("maxThreads");
|
||||
String t = config.getInitParameter("maxThreads");
|
||||
if (t!=null)
|
||||
_client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
|
||||
else
|
||||
_client.setThreadPool(new QueuedThreadPool());
|
||||
((QueuedThreadPool)_client.getThreadPool()).setName(_name.substring(_name.lastIndexOf('.')+1));
|
||||
((QueuedThreadPool)_client.getThreadPool()).setName(config.getServletName());
|
||||
|
||||
t = config.getInitParameter("maxConnections");
|
||||
if (t!=null)
|
||||
|
@ -131,9 +125,9 @@ public class ProxyServlet implements Servlet
|
|||
|
||||
if (_context!=null)
|
||||
{
|
||||
_context.setAttribute("org.eclipse.jetty.servlets."+_name+".Logger",_log);
|
||||
_context.setAttribute("org.eclipse.jetty.servlets."+_name+".ThreadPool",_client.getThreadPool());
|
||||
_context.setAttribute("org.eclipse.jetty.servlets."+_name+".HttpClient",_client);
|
||||
_context.setAttribute(config.getServletName()+".Logger",_log);
|
||||
_context.setAttribute(config.getServletName()+".ThreadPool",_client.getThreadPool());
|
||||
_context.setAttribute(config.getServletName()+".HttpClient",_client);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -513,7 +507,7 @@ public class ProxyServlet implements Servlet
|
|||
if (!_prefix.startsWith("/"))
|
||||
throw new UnavailableException("Prefix parameter must start with a '/'.");
|
||||
|
||||
_log.info(_name + " @ " + _prefix + " to " + _proxyTo);
|
||||
_log.info(config.getServletName()+" @ " + _prefix + " to " + _proxyTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,7 @@ import javax.servlet.http.HttpSession;
|
|||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.continuation.ContinuationListener;
|
||||
import org.eclipse.jetty.continuation.ContinuationSupport;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
|
||||
/**
|
||||
* Quality of Service Filter.
|
||||
|
@ -42,14 +42,14 @@ import org.eclipse.jetty.util.log.Log;
|
|||
* If more requests are received, they are suspended and placed on priority queues. Priorities are determined by
|
||||
* the {@link #getPriority(ServletRequest)} method and are a value between 0 and the value given by the "maxPriority"
|
||||
* init parameter (default 10), with higher values having higher priority.
|
||||
* <p>
|
||||
* </p><p>
|
||||
* This filter is ideal to prevent wasting threads waiting for slow/limited
|
||||
* resources such as a JDBC connection pool. It avoids the situation where all of a
|
||||
* containers thread pool may be consumed blocking on such a slow resource.
|
||||
* By limiting the number of active threads, a smaller thread pool may be used as
|
||||
* the threads are not wasted waiting. Thus more memory may be available for use by
|
||||
* the active threads.
|
||||
* <p>
|
||||
* </p><p>
|
||||
* Furthermore, this filter uses a priority when resuming waiting requests. So that if
|
||||
* a container is under load, and there are many requests waiting for resources,
|
||||
* the {@link #getPriority(ServletRequest)} method is used, so that more important
|
||||
|
@ -57,24 +57,27 @@ import org.eclipse.jetty.util.log.Log;
|
|||
* maxRequest limit slightly smaller than the containers thread pool and a high priority
|
||||
* allocated to admin users. Thus regardless of load, admin users would always be
|
||||
* able to access the web application.
|
||||
* <p>
|
||||
* </p><p>
|
||||
* The maxRequest limit is policed by a {@link Semaphore} and the filter will wait a short while attempting to acquire
|
||||
* the semaphore. This wait is controlled by the "waitMs" init parameter and allows the expense of a suspend to be
|
||||
* avoided if the semaphore is shortly available. If the semaphore cannot be obtained, the request will be suspended
|
||||
* for the default suspend period of the container or the valued set as the "suspendMs" init parameter.
|
||||
*
|
||||
* </p><p>
|
||||
* If the "managedAttr" init parameter is set to true, then this servlet is set as a {@link ServletContext} attribute with the
|
||||
* filter name as the attribute name. This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
|
||||
* manage the configuration of the filter.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class QoSFilter implements Filter
|
||||
{
|
||||
final static String __DEFAULT_ATTR_PREFIX="QoSFilter";
|
||||
final static int __DEFAULT_MAX_PRIORITY=10;
|
||||
final static int __DEFAULT_PASSES=10;
|
||||
final static int __DEFAULT_WAIT_MS=50;
|
||||
final static long __DEFAULT_TIMEOUT_MS = -1;
|
||||
|
||||
final static String ATTR_PREFIX_INIT_PARAM="attrPrefix";
|
||||
final static String MANAGED_ATTR_INIT_PARAM="managedAttr";
|
||||
final static String MAX_REQUESTS_INIT_PARAM="maxRequests";
|
||||
final static String MAX_PRIORITY_INIT_PARAM="maxPriority";
|
||||
final static String MAX_WAIT_INIT_PARAM="waitMs";
|
||||
|
@ -82,7 +85,6 @@ public class QoSFilter implements Filter
|
|||
|
||||
ServletContext _context;
|
||||
|
||||
protected String _name;
|
||||
protected long _waitMs;
|
||||
protected long _suspendMs;
|
||||
protected int _maxRequests;
|
||||
|
@ -90,7 +92,7 @@ public class QoSFilter implements Filter
|
|||
private Semaphore _passes;
|
||||
private Queue<Continuation>[] _queue;
|
||||
private ContinuationListener[] _listener;
|
||||
private String _suspended=__DEFAULT_ATTR_PREFIX+"@"+this.hashCode();
|
||||
private String _suspended="QoSFilter@"+this.hashCode();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -99,11 +101,6 @@ public class QoSFilter implements Filter
|
|||
public void init(FilterConfig filterConfig)
|
||||
{
|
||||
_context=filterConfig.getServletContext();
|
||||
|
||||
String attrPrefix = __DEFAULT_ATTR_PREFIX;
|
||||
if (filterConfig.getInitParameter(ATTR_PREFIX_INIT_PARAM)!=null)
|
||||
attrPrefix = filterConfig.getInitParameter(ATTR_PREFIX_INIT_PARAM);
|
||||
_name = attrPrefix;
|
||||
|
||||
int max_priority=__DEFAULT_MAX_PRIORITY;
|
||||
if (filterConfig.getInitParameter(MAX_PRIORITY_INIT_PARAM)!=null)
|
||||
|
@ -142,11 +139,9 @@ public class QoSFilter implements Filter
|
|||
if (filterConfig.getInitParameter(SUSPEND_INIT_PARAM)!=null)
|
||||
suspend=Integer.parseInt(filterConfig.getInitParameter(SUSPEND_INIT_PARAM));
|
||||
_suspendMs=suspend;
|
||||
|
||||
if (_context!=null)
|
||||
{
|
||||
_context.setAttribute("org.eclipse.jetty.servlets."+_name,this);
|
||||
}
|
||||
|
||||
if (_context!=null && Boolean.parseBoolean(filterConfig.getInitParameter(MANAGED_ATTR_INIT_PARAM)))
|
||||
_context.setAttribute(filterConfig.getFilterName(),this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.server.context.ManagedAttributes</param-name>
|
||||
<param-value>org.eclipse.jetty.servlets.ProxyServlet.Logger,org.eclipse.jetty.servlets.ProxyServlet.ThreadPool,org.eclipse.jetty.servlets.ProxyServlet.HttpClient</param-value>
|
||||
<param-value>QoSFilter,TransparentProxy.Logger,TransparentProxy.ThreadPool,TransparentProxy.HttpClient</param-value>
|
||||
</context-param>
|
||||
|
||||
<!-- Declare TestListener, which declares TestFilter -->
|
||||
|
@ -38,6 +38,10 @@
|
|||
<param-name>maxRequests</param-name>
|
||||
<param-value>20</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>managedAttr</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>QoSFilter</filter-name>
|
||||
|
|
Loading…
Reference in New Issue