Issue #3964 - Listener behavior cleanup (Jetty 9.4.x) (#3965)

Issue #3964
* Avoid creating listener list for rarely used requestAttributeListener
* AbstractConnector keeps a specific list of HttpChannel.Listeners
to avoid Connection.Listeners and MBean listeners being added to
the HttpChannel listener list.
* Simplified listener handling by avoiding null connector, previously
only needed for testing.
* Fixed test that assumed HttpChannel listeners were not cleared by a recycle
* Separated out durable vs cyclic HttpChannel.Listeners, so as to
simplify handling.
* Deprecated cyclic HttpChannel.Listeners, as I'm not sure the channel is
the right place for them.
* Added improved method to combine multiple HttpChannel Listeners
into a single Listener.
* Fixed MockConnector
* Added benchmark
* Improved benchmark
* Updates from review
* Removed benchmark and alternate implementations.
* Updated javadoc
* Updates from review

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2019-08-27 17:38:20 +10:00 committed by GitHub
parent 1f189d4618
commit 83463c2a23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 702 additions and 258 deletions

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpChannelState;
@ -58,7 +59,7 @@ public class SpnegoAuthenticatorTest
@Test
public void testChallengeSentWithNoAuthorization() throws Exception
{
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public Server getServer()
@ -94,7 +95,7 @@ public class SpnegoAuthenticatorTest
@Test
public void testChallengeSentWithUnhandledAuthorization() throws Exception
{
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public Server getServer()
@ -162,4 +163,29 @@ public class SpnegoAuthenticatorTest
assertEquals("negotiate", _authenticator.getAuthSchemeFromHeader(" negotiate asdfasdf"));
assertEquals("negotiated", _authenticator.getAuthSchemeFromHeader(" negotiated asdfasdf"));
}
class MockConnector extends AbstractConnector
{
public MockConnector()
{
super(new Server() , null, null, null, 0);
}
@Override
protected void accept(int acceptorID) throws IOException, InterruptedException
{
}
@Override
public Object getTransport()
{
return null;
}
@Override
public String dumpSelf()
{
return null;
}
}
}

View File

@ -45,6 +45,7 @@ import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Container;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.Graceful;
@ -154,6 +155,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
private final Set<EndPoint> _endpoints = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final Set<EndPoint> _immutableEndPoints = Collections.unmodifiableSet(_endpoints);
private final Graceful.Shutdown _shutdown = new Graceful.Shutdown();
private HttpChannel.Listener _httpChannelListeners = HttpChannel.NOOP_LISTENER;
private CountDownLatch _stopping;
private long _idleTimeout = 30000;
private String _defaultProtocol;
@ -188,6 +190,23 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
pool = _server.getBean(ByteBufferPool.class);
_byteBufferPool = pool != null ? pool : new ArrayByteBufferPool();
addEventListener(new Container.Listener()
{
@Override
public void beanAdded(Container parent, Object bean)
{
if (bean instanceof HttpChannel.Listener)
_httpChannelListeners = new HttpChannelListeners(getBeans(HttpChannel.Listener.class));
}
@Override
public void beanRemoved(Container parent, Object bean)
{
if (bean instanceof HttpChannel.Listener)
_httpChannelListeners = new HttpChannelListeners(getBeans(HttpChannel.Listener.class));
}
});
addBean(_server, false);
addBean(_executor);
if (executor == null)
@ -208,6 +227,24 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
_acceptors = new Thread[acceptors];
}
/**
* Get the {@link HttpChannel.Listener}s added to the connector
* as a single combined Listener.
* This is equivalent to a listener that iterates over the individual
* listeners returned from <code>getBeans(HttpChannel.Listener.class);</code>,
* except that: <ul>
* <li>The result is precomputed, so it is more efficient</li>
* <li>The result is ordered by the order added.</li>
* <li>The result is immutable.</li>
* </ul>
* @see #getBeans(Class)
* @return An unmodifiable list of EventListener beans
*/
public HttpChannel.Listener getHttpChannelListeners()
{
return _httpChannelListeners;
}
@Override
public Server getServer()
{

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
@ -69,6 +70,7 @@ import org.eclipse.jetty.util.thread.Scheduler;
*/
public class HttpChannel implements Runnable, HttpOutput.Interceptor
{
public static Listener NOOP_LISTENER = new Listener(){};
private static final Logger LOG = Log.getLogger(HttpChannel.class);
private final AtomicLong _requests = new AtomicLong();
@ -80,9 +82,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
private final HttpChannelState _state;
private final Request _request;
private final Response _response;
private final HttpChannel.Listener _combinedListener;
@Deprecated
private final List<Listener> _transientListeners = new ArrayList<>();
private HttpFields _trailers;
private final Supplier<HttpFields> _trailerSupplier = () -> _trailers;
private final List<Listener> _listeners;
private MetaData.Response _committedMetaData;
private RequestLog _requestLog;
private long _oldIdleTimeout;
@ -103,13 +107,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
_request = new Request(this, newHttpInput(_state));
_response = new Response(this, newHttpOutput());
_executor = connector == null ? null : connector.getServer().getThreadPool();
_requestLog = connector == null ? null : connector.getServer().getRequestLog();
List<Listener> listeners = new ArrayList<>();
if (connector != null)
listeners.addAll(connector.getBeans(Listener.class));
_listeners = listeners;
_executor = connector.getServer().getThreadPool();
_requestLog = connector.getServer().getRequestLog();
_combinedListener = (connector instanceof AbstractConnector)
? ((AbstractConnector)connector).getHttpChannelListeners()
: NOOP_LISTENER;
if (LOG.isDebugEnabled())
LOG.debug("new {} -> {},{},{}",
@ -139,14 +141,32 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
return _state;
}
/**
* Add a transient Listener to the HttpChannel.
* <p>Listeners added by this method will only be notified
* if the HttpChannel has been constructed with an instance of
* {@link TransientListeners} as an {@link AbstractConnector}
* provided listener</p>
* <p>Transient listeners are removed after every request cycle</p>
* @param listener
* @return true if the listener was added.
*/
@Deprecated
public boolean addListener(Listener listener)
{
return _listeners.add(listener);
return _transientListeners.add(listener);
}
@Deprecated
public boolean removeListener(Listener listener)
{
return _listeners.remove(listener);
return _transientListeners.remove(listener);
}
@Deprecated
public List<Listener> getTransientListeners()
{
return _transientListeners;
}
public long getBytesWritten()
@ -294,6 +314,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
_written = 0;
_trailers = null;
_oldIdleTimeout = 0;
_transientListeners.clear();
}
public void onAsyncWaitForContent()
@ -535,17 +556,17 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
try
{
_request.setDispatcherType(type);
notifyBeforeDispatch(_request);
_combinedListener.onBeforeDispatch(_request);
dispatchable.dispatch();
}
catch (Throwable x)
{
notifyDispatchFailure(_request, x);
_combinedListener.onDispatchFailure(_request, x);
throw x;
}
finally
{
notifyAfterDispatch(_request);
_combinedListener.onAfterDispatch(_request);
_request.setDispatcherType(null);
}
}
@ -668,7 +689,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
_request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme()));
notifyRequestBegin(_request);
_combinedListener.onRequestBegin(_request);
if (LOG.isDebugEnabled())
LOG.debug("REQUEST for {} on {}{}{} {} {}{}{}", request.getURIString(), this, System.lineSeparator(),
@ -680,7 +701,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
{
if (LOG.isDebugEnabled())
LOG.debug("onContent {} {}", this, content);
notifyRequestContent(_request, content.getByteBuffer());
_combinedListener.onRequestContent(_request, content.getByteBuffer());
return _request.getHttpInput().addContent(content);
}
@ -688,7 +709,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
{
if (LOG.isDebugEnabled())
LOG.debug("onContentComplete {}", this);
notifyRequestContentEnd(_request);
_combinedListener.onRequestContentEnd(_request);
return false;
}
@ -697,7 +718,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
if (LOG.isDebugEnabled())
LOG.debug("onTrailers {} {}", this, trailers);
_trailers = trailers;
notifyRequestTrailers(_request);
_combinedListener.onRequestTrailers(_request);
}
public boolean onRequestComplete()
@ -705,7 +726,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
if (LOG.isDebugEnabled())
LOG.debug("onRequestComplete {}", this);
boolean result = _request.getHttpInput().eof();
notifyRequestEnd(_request);
_combinedListener.onRequestEnd(_request);
return result;
}
@ -722,7 +743,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
setIdleTimeout(_oldIdleTimeout);
_request.onCompleted();
notifyComplete(_request);
_combinedListener.onComplete(_request);
_transport.onCompleted();
}
@ -738,7 +759,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
if (status < HttpStatus.BAD_REQUEST_400 || status > 599)
failure = new BadMessageException(HttpStatus.BAD_REQUEST_400, reason, failure);
notifyRequestFailure(_request, failure);
_combinedListener.onRequestFailure(_request, failure);
Action action;
try
@ -810,7 +831,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
? new Send100Callback(callback)
: new SendCallback(callback, content, true, complete);
notifyResponseBegin(_request);
_combinedListener.onResponseBegin(_request);
// committing write
_transport.send(info, _request.isHead(), content, complete, committed);
@ -936,89 +957,14 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
{
if (_state.abortResponse())
{
notifyResponseFailure(_request, failure);
_combinedListener.onResponseFailure(_request, failure);
_transport.abort(failure);
}
}
private void notifyRequestBegin(Request request)
{
notifyEvent1(listener -> listener::onRequestBegin, request);
}
private void notifyBeforeDispatch(Request request)
{
notifyEvent1(listener -> listener::onBeforeDispatch, request);
}
private void notifyDispatchFailure(Request request, Throwable failure)
{
notifyEvent2(listener -> listener::onDispatchFailure, request, failure);
}
private void notifyAfterDispatch(Request request)
{
notifyEvent1(listener -> listener::onAfterDispatch, request);
}
private void notifyRequestContent(Request request, ByteBuffer content)
{
notifyEvent2(listener -> listener::onRequestContent, request, content);
}
private void notifyRequestContentEnd(Request request)
{
notifyEvent1(listener -> listener::onRequestContentEnd, request);
}
private void notifyRequestTrailers(Request request)
{
notifyEvent1(listener -> listener::onRequestTrailers, request);
}
private void notifyRequestEnd(Request request)
{
notifyEvent1(listener -> listener::onRequestEnd, request);
}
private void notifyRequestFailure(Request request, Throwable failure)
{
notifyEvent2(listener -> listener::onRequestFailure, request, failure);
}
private void notifyResponseBegin(Request request)
{
notifyEvent1(listener -> listener::onResponseBegin, request);
}
private void notifyResponseCommit(Request request)
{
notifyEvent1(listener -> listener::onResponseCommit, request);
}
private void notifyResponseContent(Request request, ByteBuffer content)
{
notifyEvent2(listener -> listener::onResponseContent, request, content);
}
private void notifyResponseEnd(Request request)
{
notifyEvent1(listener -> listener::onResponseEnd, request);
}
private void notifyResponseFailure(Request request, Throwable failure)
{
notifyEvent2(listener -> listener::onResponseFailure, request, failure);
}
private void notifyComplete(Request request)
{
notifyEvent1(listener -> listener::onComplete, request);
}
private void notifyEvent1(Function<Listener, Consumer<Request>> function, Request request)
{
for (Listener listener : _listeners)
for (Listener listener : _transientListeners)
{
try
{
@ -1033,7 +979,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
private void notifyEvent2(Function<Listener, BiConsumer<Request, ByteBuffer>> function, Request request, ByteBuffer content)
{
for (Listener listener : _listeners)
for (Listener listener : _transientListeners)
{
ByteBuffer view = content.slice();
try
@ -1049,7 +995,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
private void notifyEvent2(Function<Listener, BiConsumer<Request, Throwable>> function, Request request, Throwable failure)
{
for (Listener listener : _listeners)
for (Listener listener : _transientListeners)
{
try
{
@ -1085,8 +1031,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
* <p>Listener methods are invoked synchronously from the thread that is
* performing the request processing, and they should not call blocking code
* (otherwise the request processing will be blocked as well).</p>
* <p>Listener instances that are set as a bean on the {@link Connector} are
* efficiently added to {@link HttpChannel}. If additional listeners are added
* using the deprecated {@link HttpChannel#addListener(Listener)}</p> method,
* then an instance of {@link TransientListeners} must be added to the connector
* in order for them to be invoked.
*/
public interface Listener
public interface Listener extends EventListener
{
/**
* Invoked just after the HTTP request line and headers have been parsed.
@ -1256,11 +1207,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
_response.getHttpOutput().closed();
super.succeeded();
if (_commit)
notifyResponseCommit(_request);
_combinedListener.onResponseCommit(_request);
if (_length > 0)
notifyResponseContent(_request, _content);
_combinedListener.onResponseContent(_request, _content);
if (_complete && _state.completeResponse())
notifyResponseEnd(_request);
_combinedListener.onResponseEnd(_request);
}
@Override
@ -1313,4 +1264,102 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
super.failed(new IllegalStateException());
}
}
/**
* A Listener instance that can be added as a bean to {@link AbstractConnector} so that
* the listeners obtained from HttpChannel{@link #getTransientListeners()}
*/
@Deprecated
public static class TransientListeners implements Listener
{
@Override
public void onRequestBegin(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestBegin, request);
}
@Override
public void onBeforeDispatch(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onBeforeDispatch, request);
}
@Override
public void onDispatchFailure(Request request, Throwable failure)
{
request.getHttpChannel().notifyEvent2(listener -> listener::onDispatchFailure, request, failure);
}
@Override
public void onAfterDispatch(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onAfterDispatch, request);
}
@Override
public void onRequestContent(Request request, ByteBuffer content)
{
request.getHttpChannel().notifyEvent2(listener -> listener::onRequestContent, request, content);
}
@Override
public void onRequestContentEnd(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestContentEnd, request);
}
@Override
public void onRequestTrailers(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestTrailers, request);
}
@Override
public void onRequestEnd(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestEnd, request);
}
@Override
public void onRequestFailure(Request request, Throwable failure)
{
request.getHttpChannel().notifyEvent2(listener -> listener::onRequestFailure, request, failure);
}
@Override
public void onResponseBegin(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onResponseBegin, request);
}
@Override
public void onResponseCommit(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onResponseCommit, request);
}
@Override
public void onResponseContent(Request request, ByteBuffer content)
{
request.getHttpChannel().notifyEvent2(listener -> listener::onResponseContent, request, content);
}
@Override
public void onResponseEnd(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onResponseEnd, request);
}
@Override
public void onResponseFailure(Request request, Throwable failure)
{
request.getHttpChannel().notifyEvent2(listener -> listener::onResponseFailure, request, failure);
}
@Override
public void onComplete(Request request)
{
request.getHttpChannel().notifyEvent1(listener -> listener::onComplete, request);
}
}
}

View File

@ -0,0 +1,286 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server;
import java.nio.ByteBuffer;
import java.util.Collection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* A {@link HttpChannel.Listener} that holds a collection of
* other {@link HttpChannel.Listener} instances that are efficiently
* invoked without iteration.
* @see AbstractConnector
*/
public class HttpChannelListeners implements HttpChannel.Listener
{
static final Logger LOG = Log.getLogger(HttpChannel.class);
public static HttpChannel.Listener NOOP = new HttpChannel.Listener() {};
private final NotifyRequest onRequestBegin;
private final NotifyRequest onBeforeDispatch;
private final NotifyFailure onDispatchFailure;
private final NotifyRequest onAfterDispatch;
private final NotifyContent onRequestContent;
private final NotifyRequest onRequestContentEnd;
private final NotifyRequest onRequestTrailers;
private final NotifyRequest onRequestEnd;
private final NotifyFailure onRequestFailure;
private final NotifyRequest onResponseBegin;
private final NotifyRequest onResponseCommit;
private final NotifyContent onResponseContent;
private final NotifyRequest onResponseEnd;
private final NotifyFailure onResponseFailure;
private final NotifyRequest onComplete;
public HttpChannelListeners(Collection<HttpChannel.Listener> listeners)
{
try
{
NotifyRequest onRequestBegin = NotifyRequest.NOOP;
NotifyRequest onBeforeDispatch = NotifyRequest.NOOP;
NotifyFailure onDispatchFailure = NotifyFailure.NOOP;
NotifyRequest onAfterDispatch = NotifyRequest.NOOP;
NotifyContent onRequestContent = NotifyContent.NOOP;
NotifyRequest onRequestContentEnd = NotifyRequest.NOOP;
NotifyRequest onRequestTrailers = NotifyRequest.NOOP;
NotifyRequest onRequestEnd = NotifyRequest.NOOP;
NotifyFailure onRequestFailure = NotifyFailure.NOOP;
NotifyRequest onResponseBegin = NotifyRequest.NOOP;
NotifyRequest onResponseCommit = NotifyRequest.NOOP;
NotifyContent onResponseContent = NotifyContent.NOOP;
NotifyRequest onResponseEnd = NotifyRequest.NOOP;
NotifyFailure onResponseFailure = NotifyFailure.NOOP;
NotifyRequest onComplete = NotifyRequest.NOOP;
for (HttpChannel.Listener listener : listeners)
{
if (!listener.getClass().getMethod("onRequestBegin", Request.class).isDefault())
onRequestBegin = combine(onRequestBegin, listener::onRequestBegin);
if (!listener.getClass().getMethod("onBeforeDispatch", Request.class).isDefault())
onBeforeDispatch = combine(onBeforeDispatch, listener::onBeforeDispatch);
if (!listener.getClass().getMethod("onDispatchFailure", Request.class, Throwable.class).isDefault())
onDispatchFailure = combine(onDispatchFailure, listener::onDispatchFailure);
if (!listener.getClass().getMethod("onAfterDispatch", Request.class).isDefault())
onAfterDispatch = combine(onAfterDispatch, listener::onAfterDispatch);
if (!listener.getClass().getMethod("onRequestContent", Request.class, ByteBuffer.class).isDefault())
onRequestContent = combine(onRequestContent, listener::onRequestContent);
if (!listener.getClass().getMethod("onRequestContentEnd", Request.class).isDefault())
onRequestContentEnd = combine(onRequestContentEnd, listener::onRequestContentEnd);
if (!listener.getClass().getMethod("onRequestTrailers", Request.class).isDefault())
onRequestTrailers = combine(onRequestTrailers, listener::onRequestTrailers);
if (!listener.getClass().getMethod("onRequestEnd", Request.class).isDefault())
onRequestEnd = combine(onRequestEnd, listener::onRequestEnd);
if (!listener.getClass().getMethod("onRequestFailure", Request.class, Throwable.class).isDefault())
onRequestFailure = combine(onRequestFailure, listener::onRequestFailure);
if (!listener.getClass().getMethod("onResponseBegin", Request.class).isDefault())
onResponseBegin = combine(onResponseBegin, listener::onResponseBegin);
if (!listener.getClass().getMethod("onResponseCommit", Request.class).isDefault())
onResponseCommit = combine(onResponseCommit, listener::onResponseCommit);
if (!listener.getClass().getMethod("onResponseContent", Request.class, ByteBuffer.class).isDefault())
onResponseContent = combine(onResponseContent, listener::onResponseContent);
if (!listener.getClass().getMethod("onResponseEnd", Request.class).isDefault())
onResponseEnd = combine(onResponseEnd, listener::onResponseEnd);
if (!listener.getClass().getMethod("onResponseFailure", Request.class, Throwable.class).isDefault())
onResponseFailure = combine(onResponseFailure, listener::onResponseFailure);
if (!listener.getClass().getMethod("onComplete", Request.class).isDefault())
onComplete = combine(onComplete, listener::onComplete);
}
this.onRequestBegin = onRequestBegin;
this.onBeforeDispatch = onBeforeDispatch;
this.onDispatchFailure = onDispatchFailure;
this.onAfterDispatch = onAfterDispatch;
this.onRequestContent = onRequestContent;
this.onRequestContentEnd = onRequestContentEnd;
this.onRequestTrailers = onRequestTrailers;
this.onRequestEnd = onRequestEnd;
this.onRequestFailure = onRequestFailure;
this.onResponseBegin = onResponseBegin;
this.onResponseCommit = onResponseCommit;
this.onResponseContent = onResponseContent;
this.onResponseEnd = onResponseEnd;
this.onResponseFailure = onResponseFailure;
this.onComplete = onComplete;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
@Override
public void onRequestBegin(Request request)
{
onRequestBegin.onRequest(request);
}
@Override
public void onBeforeDispatch(Request request)
{
onBeforeDispatch.onRequest(request);
}
@Override
public void onDispatchFailure(Request request, Throwable failure)
{
onDispatchFailure.onFailure(request, failure);
}
@Override
public void onAfterDispatch(Request request)
{
onAfterDispatch.onRequest(request);
}
@Override
public void onRequestContent(Request request, ByteBuffer content)
{
onRequestContent.onContent(request, content);
}
@Override
public void onRequestContentEnd(Request request)
{
onRequestContentEnd.onRequest(request);
}
@Override
public void onRequestTrailers(Request request)
{
onRequestTrailers.onRequest(request);
}
@Override
public void onRequestEnd(Request request)
{
onRequestEnd.onRequest(request);
}
@Override
public void onRequestFailure(Request request, Throwable failure)
{
onRequestFailure.onFailure(request, failure);
}
@Override
public void onResponseBegin(Request request)
{
onResponseBegin.onRequest(request);
}
@Override
public void onResponseCommit(Request request)
{
onResponseCommit.onRequest(request);
}
@Override
public void onResponseContent(Request request, ByteBuffer content)
{
onResponseContent.onContent(request, content);
}
@Override
public void onResponseEnd(Request request)
{
onResponseEnd.onRequest(request);
}
@Override
public void onResponseFailure(Request request, Throwable failure)
{
onResponseFailure.onFailure(request, failure);
}
@Override
public void onComplete(Request request)
{
onComplete.onRequest(request);
}
private interface NotifyRequest
{
void onRequest(Request request);
NotifyRequest NOOP = request ->
{
};
}
private interface NotifyFailure
{
void onFailure(Request request, Throwable failure);
NotifyFailure NOOP = (request, failure) ->
{
};
}
private interface NotifyContent
{
void onContent(Request request, ByteBuffer content);
NotifyContent NOOP = (request, content) ->
{
};
}
private static NotifyRequest combine(NotifyRequest first, NotifyRequest second)
{
if (first == NotifyRequest.NOOP)
return second;
if (second == NotifyRequest.NOOP)
return first;
return request ->
{
first.onRequest(request);
second.onRequest(request);
};
}
private static NotifyFailure combine(NotifyFailure first, NotifyFailure second)
{
if (first == NotifyFailure.NOOP)
return second;
if (second == NotifyFailure.NOOP)
return first;
return (request, throwable) ->
{
first.onFailure(request, throwable);
second.onFailure(request, throwable);
};
}
private static NotifyContent combine(NotifyContent first, NotifyContent second)
{
if (first == NotifyContent.NOOP)
return (request, content) -> second.onContent(request, content.slice());
if (second == NotifyContent.NOOP)
return (request, content) -> first.onContent(request, content.slice());
return (request, content) ->
{
content = content.slice();
first.onContent(request, content);
second.onContent(request, content);
};
}
}

View File

@ -1873,6 +1873,7 @@ public class Request implements HttpServletRequest
_remote = null;
_sessions = null;
_input.recycle();
_requestAttributeListeners.clear();
}
/*

View File

@ -240,6 +240,37 @@ public class HttpChannelEventTest
assertThat(elapsed.get(), Matchers.greaterThan(0L));
}
@Test
public void testTransientListener() throws Exception
{
start(new TestHandler());
CountDownLatch latch = new CountDownLatch(1);
connector.addBean(new HttpChannel.TransientListeners());
connector.addBean(new HttpChannel.Listener()
{
@Override
public void onRequestBegin(Request request)
{
request.getHttpChannel().addListener(new HttpChannel.Listener()
{
@Override
public void onComplete(Request request)
{
latch.countDown();
}
});
}
});
HttpTester.Request request = HttpTester.newRequest();
request.setHeader("Host", "localhost");
HttpTester.Response response = HttpTester.parseResponse(connector.getResponse(request.toString(), 5, TimeUnit.SECONDS));
assertEquals(HttpStatus.OK_200, response.getStatus());
assertTrue(latch.await(5, TimeUnit.SECONDS));
}
private static class TestHandler extends AbstractHandler.ErrorDispatchHandler
{
@Override

View File

@ -95,7 +95,7 @@ public class HttpInputAsyncStateTest
public void before()
{
_noReadInDataAvailable = false;
_in = new HttpInput(new HttpChannelState(new HttpChannel(null, new HttpConfiguration(), null, null)
_in = new HttpInput(new HttpChannelState(new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public void onAsyncWaitForContent()

View File

@ -92,7 +92,7 @@ public class HttpInputTest
@BeforeEach
public void before()
{
_in = new HttpInput(new HttpChannelState(new HttpChannel(null, new HttpConfiguration(), null, null)
_in = new HttpInput(new HttpChannelState(new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public void onAsyncWaitForContent()

View File

@ -45,7 +45,7 @@ public class HttpWriterTest
final ByteBufferPool pool = new ArrayByteBufferPool();
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
{
@Override
public ByteBufferPool getByteBufferPool()

View File

@ -0,0 +1,46 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server;
import java.io.IOException;
class MockConnector extends AbstractConnector
{
public MockConnector()
{
super(new Server() , null, null, null, 0);
}
@Override
protected void accept(int acceptorID) throws IOException, InterruptedException
{
}
@Override
public Object getTransport()
{
return null;
}
@Override
public String dumpSelf()
{
return null;
}
}

View File

@ -43,7 +43,7 @@ public interface Container
/**
* @param clazz the class of the beans
* @param <T> the Bean type
* @return the list of beans of the given class (or subclass)
* @return a list of beans of the given class (or subclass)
* @see #getBeans()
* @see #getContainedBeans(Class)
*/

View File

@ -65,8 +65,8 @@ public abstract class AbstractClusteredInvalidationSessionTest extends AbstractT
TestServer server1 = new TestServer(0, maxInactiveInterval, scavengeInterval, cacheFactory1, storeFactory1);
ServletContextHandler context = server1.addContext(contextPath);
context.addServlet(TestServlet.class, servletMapping);
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
try
{

View File

@ -77,8 +77,8 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes
TestServlet servlet1 = new TestServlet();
ServletHolder holder1 = new ServletHolder(servlet1);
ServletContextHandler context = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
TestSessionListener listener1 = new TestSessionListener();
context.getSessionHandler().addEventListener(listener1);
context.addServlet(holder1, servletMapping);
@ -96,8 +96,8 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes
((AbstractSessionDataStoreFactory)storeFactory2).setSavePeriodSec(0); //always save when the session exits
TestServer server2 = new TestServer(0, maxInactivePeriod, scavengePeriod, cacheFactory2, storeFactory2);
ServletContextHandler context2 = server2.addContext(contextPath);
TestContextScopeListener scopeListener2 = new TestContextScopeListener();
context2.addEventListener(scopeListener2);
TestHttpChannelCompleteListener scopeListener2 = new TestHttpChannelCompleteListener();
server2.getServerConnector().addBean(scopeListener2);
context2.addServlet(TestServlet.class, servletMapping);
SessionHandler m2 = context2.getSessionHandler();

View File

@ -23,7 +23,6 @@ import java.io.FileOutputStream;
import java.io.FileWriter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
@ -103,8 +102,8 @@ public abstract class AbstractWebAppObjectInSessionTest extends AbstractTestBase
TestServer server1 = new TestServer(0, TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC,
cacheFactory, storeFactory);
WebAppContext wac1 = server1.addWebAppContext(warDir.getCanonicalPath(), contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
wac1.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
wac1.addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping);
try

View File

@ -1,76 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.server.HttpChannel.Listener;
import org.eclipse.jetty.server.HttpChannelState;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.server.handler.ContextHandler.ContextScopeListener;
public class TestContextScopeListener implements ContextScopeListener
{
AtomicReference<CountDownLatch> _exitSynchronizer = new AtomicReference<>();
boolean listenerAdded = false;
/**
* @return the exitSynchronizer
*/
public CountDownLatch getExitSynchronizer()
{
return _exitSynchronizer.get();
}
/**
* @param exitSynchronizer the exitSynchronizer to set
*/
public void setExitSynchronizer(CountDownLatch exitSynchronizer)
{
_exitSynchronizer.set(exitSynchronizer);
}
@Override
public void enterScope(Context context, org.eclipse.jetty.server.Request request, Object reason)
{
//noop
}
@Override
public void exitScope(final Context context, final org.eclipse.jetty.server.Request request)
{
if (request != null && !listenerAdded)
{
listenerAdded = true;
request.getHttpChannel().addListener(new Listener()
{
@Override
public void onComplete(Request request)
{
Listener.super.onComplete(request);
if (_exitSynchronizer.get() != null)
_exitSynchronizer.get().countDown();
}
});
}
}
}

View File

@ -0,0 +1,45 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.server.HttpChannel.Listener;
import org.eclipse.jetty.server.Request;
public class TestHttpChannelCompleteListener implements Listener
{
private final AtomicReference<CountDownLatch> _exitSynchronizer = new AtomicReference<>();
/**
* @param exitSynchronizer the exitSynchronizer to set
*/
public void setExitSynchronizer(CountDownLatch exitSynchronizer)
{
_exitSynchronizer.set(exitSynchronizer);
}
@Override
public void onComplete(Request request)
{
if (_exitSynchronizer.get() != null)
_exitSynchronizer.get().countDown();
}
}

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.server.session;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler;
@ -93,6 +94,11 @@ public class TestServer
return h;
}
public ServerConnector getServerConnector()
{
return _server.getBean(ServerConnector.class);
}
public void start() throws Exception
{
// server -> contexts collection -> context handler -> session handler -> servlet handler

View File

@ -22,7 +22,6 @@ import java.io.IOException;
import java.lang.reflect.Proxy;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
@ -65,8 +64,8 @@ public class AsyncTest
String mapping = "/server";
ServletContextHandler contextHandler = server.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
contextHandler.addServlet(holder, mapping);
@ -117,8 +116,8 @@ public class AsyncTest
String mapping = "/server";
ServletContextHandler contextHandler = server.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
contextHandler.addServlet(holder, mapping);
@ -167,8 +166,8 @@ public class AsyncTest
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
ServletContextHandler contextA = server.addContext("/ctxA");
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextA.addEventListener(scopeListener); //just pick one of the contexts to register the listener
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener); //just pick one of the contexts to register the listener
CrossContextServlet ccServlet = new CrossContextServlet();
ServletHolder ccHolder = new ServletHolder(ccServlet);
contextA.addServlet(ccHolder, "/*");
@ -224,8 +223,8 @@ public class AsyncTest
String mapping = "/server";
ServletContextHandler contextHandler = server.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
@ -277,8 +276,8 @@ public class AsyncTest
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
ServletContextHandler contextA = server.addContext("/ctxA");
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextA.addEventListener(scopeListener); //just pick a context
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
CrossContextServlet ccServlet = new CrossContextServlet();
ServletHolder ccHolder = new ServletHolder(ccServlet);
contextA.addServlet(ccHolder, "/*");

View File

@ -76,8 +76,8 @@ public class CreationTest
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
server1.start();
@ -145,8 +145,8 @@ public class CreationTest
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
server1.start();
@ -197,8 +197,8 @@ public class CreationTest
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
server1.start();
@ -245,8 +245,8 @@ public class CreationTest
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
server1.start();
@ -299,8 +299,8 @@ public class CreationTest
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
ServletContextHandler ctxB = server1.addContext(contextB);
ctxB.addServlet(TestServletB.class, servletMapping);
@ -354,8 +354,8 @@ public class CreationTest
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler contextHandler = server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
ServletContextHandler ctxB = server1.addContext(contextB);
ctxB.addServlet(TestServletB.class, servletMapping);

View File

@ -22,7 +22,6 @@ import java.util.Collections;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
@ -79,8 +78,8 @@ public class DefaultSessionCacheTest
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
TestServer server = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
ServletContextHandler contextHandler = server.addContext("/test");
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
TestHttpSessionListener listener = new TestHttpSessionListener();
contextHandler.getSessionHandler().addEventListener(listener);

View File

@ -151,8 +151,8 @@ public class DeleteUnloadableSessionTest
TestServer server = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
ServletContextHandler context = server.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);

View File

@ -94,8 +94,8 @@ public class DirtyAttributeTest
ServletContextHandler ctxA = server.addContext("/mod");
ctxA.addServlet(TestDirtyServlet.class, "/test");
TestContextScopeListener scopeListener = new TestContextScopeListener();
ctxA.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
server.start();
int port = server.getPort();
@ -125,15 +125,13 @@ public class DirtyAttributeTest
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
//ensure request fully finished processing
latch.await(5, TimeUnit.SECONDS);
assertTrue(latch.await(5, TimeUnit.SECONDS));
A_VALUE.assertPassivatesEquals(1);
A_VALUE.assertActivatesEquals(1);
A_VALUE.assertBindsEquals(1);
A_VALUE.assertUnbindsEquals(0);
//do another request using the cookie to try changing the session attribute to the same value again
latch = new CountDownLatch(1);
scopeListener.setExitSynchronizer(latch);

View File

@ -76,8 +76,8 @@ public class IdleSessionTest
_server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_server1.start();
int port1 = _server1.getPort();
@ -202,8 +202,8 @@ public class IdleSessionTest
_server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_server1.start();
int port1 = _server1.getPort();

View File

@ -75,8 +75,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase
context1.addServlet(TestServlet.class, servletMapping);
TestHttpSessionListener listener = new TestHttpSessionListener();
context1.getSessionHandler().addEventListener(listener);
TestContextScopeListener scopeListener = new TestContextScopeListener();
context1.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server1.getServerConnector().addBean(scopeListener);
try
{
@ -144,8 +144,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase
TestServer server = new TestServer(0, maxInactivePeriod, scavengePeriod,
cacheFactory, storeFactory);
ServletContextHandler context = server.addContext("/");
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
_dataStore = context.getSessionHandler().getSessionCache().getSessionDataStore();
context.addServlet(TestServlet.class, servletMapping);
@ -208,8 +208,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase
TestServer server = new TestServer(0, maxInactivePeriod, scavengePeriod,
cacheFactory, storeFactory);
ServletContextHandler context = server.addContext("/");
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
_dataStore = context.getSessionHandler().getSessionCache().getSessionDataStore();
context.addServlet(TestServlet.class, servletMapping);
String contextPath = "/";

View File

@ -59,8 +59,8 @@ public class ReentrantRequestSessionTest
ServletContextHandler context = server.addContext(contextPath);
context.addServlet(TestServlet.class, servletMapping);
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
server.getServerConnector().addBean(scopeListener);
try
{

View File

@ -58,8 +58,8 @@ public class SameContextForwardedSessionTest
TestServer testServer = new TestServer(0, -1, -1, cacheFactory, storeFactory);
ServletContextHandler testServletContextHandler = testServer.addContext("/context");
TestContextScopeListener scopeListener = new TestContextScopeListener();
testServletContextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
testServer.getServerConnector().addBean(scopeListener);
ServletHolder holder = new ServletHolder(new Servlet1());
testServletContextHandler.addServlet(holder, "/one");
testServletContextHandler.addServlet(Servlet2.class, "/two");

View File

@ -124,8 +124,8 @@ public class SaveOptimizeTest
_servlet = new TestServlet();
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
_server1.start();
@ -207,8 +207,8 @@ public class SaveOptimizeTest
_servlet = new TestServlet();
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
_server1.start();
@ -297,8 +297,8 @@ public class SaveOptimizeTest
_servlet = new TestServlet();
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
_server1.start();
@ -392,8 +392,8 @@ public class SaveOptimizeTest
_servlet = new TestServlet();
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
_server1.start();
@ -471,8 +471,8 @@ public class SaveOptimizeTest
_servlet = new TestServlet();
ServletHolder holder = new ServletHolder(_servlet);
ServletContextHandler contextHandler = _server1.addContext(contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextHandler.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server1.getServerConnector().addBean(scopeListener);
contextHandler.addServlet(holder, servletMapping);
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
_server1.start();

View File

@ -22,7 +22,6 @@ import java.io.IOException;
import java.net.HttpCookie;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@ -41,7 +40,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
@ -118,8 +116,8 @@ public class SessionRenewTest
String contextPathA = "";
String servletMapping = "/server";
WebAppContext contextA = _server.addWebAppContext(".", contextPathA);
TestContextScopeListener scopeListener = new TestContextScopeListener();
contextA.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server.getServerConnector().addBean(scopeListener);
contextA.setParentLoaderPriority(true);
contextA.addServlet(TestServlet.class, servletMapping);
@ -185,8 +183,8 @@ public class SessionRenewTest
String contextPath = "";
String servletMapping = "/server";
WebAppContext context = _server.addWebAppContext(".", contextPath);
TestContextScopeListener scopeListener = new TestContextScopeListener();
context.addEventListener(scopeListener);
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
_server.getServerConnector().addBean(scopeListener);
context.setParentLoaderPriority(true);
context.addServlet(TestServlet.class, servletMapping);
TestHttpSessionIdListener testListener = new TestHttpSessionIdListener();