From 968a2ac95b9bbf5c8af0b1e708f2bc741532e39d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 00:09:34 +1100 Subject: [PATCH] 368240: Added concept of join to AggregateLifeCycle. Used by HttpClient and AbstractConnector --- .../org/eclipse/jetty/client/HttpClient.java | 177 +++++++---- .../eclipse/jetty/client/SelectConnector.java | 6 +- .../org/eclipse/jetty/http/HttpBuffers.java | 164 ++-------- .../eclipse/jetty/http/HttpBuffersImpl.java | 233 ++++++++++++++ .../org/eclipse/jetty/io/AbstractBuffers.java | 8 +- .../org/eclipse/jetty/io/PooledBuffers.java | 9 + .../eclipse/jetty/io/nio/SelectorManager.java | 3 + .../jetty/rewrite/handler/ProxyRuleTest.java | 4 +- .../jetty/server/AbstractConnector.java | 127 ++++++-- .../server/nio/AbstractNIOConnector.java | 12 +- .../server/nio/SelectChannelConnector.java | 39 +-- .../server/ssl/SslSelectChannelConnector.java | 3 +- .../util/component/AggregateLifeCycle.java | 291 ++++++++++++++---- .../jetty/util/ssl/SslContextFactory.java | 8 +- .../component/AggregateLifeCycleTest.java | 106 +++++++ 15 files changed, 863 insertions(+), 327 deletions(-) create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 21e8b0f89e9..baad2e962f7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -29,7 +29,9 @@ import org.eclipse.jetty.client.security.Authentication; import org.eclipse.jetty.client.security.RealmResolver; import org.eclipse.jetty.client.security.SecurityListener; import org.eclipse.jetty.http.HttpBuffers; +import org.eclipse.jetty.http.HttpBuffersImpl; import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.io.Buffers; import org.eclipse.jetty.io.Buffers.Type; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; @@ -66,7 +68,7 @@ import org.eclipse.jetty.util.thread.Timeout; * @see HttpExchange * @see HttpDestination */ -public class HttpClient extends HttpBuffers implements Attributes, Dumpable +public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attributes, Dumpable { public static final int CONNECTOR_SOCKET = 0; public static final int CONNECTOR_SELECT_CHANNEL = 2; @@ -91,43 +93,46 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable private int _maxRedirects = 20; private LinkedList _registeredListeners; - private SslContextFactory _sslContextFactory; + private final SslContextFactory _sslContextFactory; private RealmResolver _realmResolver; private AttributesMap _attributes=new AttributesMap(); + private final HttpBuffersImpl _buffers= new HttpBuffersImpl(); /* ------------------------------------------------------------------------------- */ private void setBufferTypes() { if (_connectorType==CONNECTOR_SOCKET) { - setRequestBufferType(Type.BYTE_ARRAY); - setRequestHeaderType(Type.BYTE_ARRAY); - setResponseBufferType(Type.BYTE_ARRAY); - setResponseHeaderType(Type.BYTE_ARRAY); + _buffers.setRequestBufferType(Type.BYTE_ARRAY); + _buffers.setRequestHeaderType(Type.BYTE_ARRAY); + _buffers.setResponseBufferType(Type.BYTE_ARRAY); + _buffers.setResponseHeaderType(Type.BYTE_ARRAY); } else { - setRequestBufferType(Type.DIRECT); - setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); - setResponseBufferType(Type.DIRECT); - setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); + _buffers.setRequestBufferType(Type.DIRECT); + _buffers.setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); + _buffers.setResponseBufferType(Type.DIRECT); + _buffers.setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); } + } /* ------------------------------------------------------------------------------- */ public HttpClient() { this(new SslContextFactory()); - setBufferTypes(); } /* ------------------------------------------------------------------------------- */ public HttpClient(SslContextFactory sslContextFactory) { _sslContextFactory = sslContextFactory; + addBean(_sslContextFactory); + addBean(_buffers); setBufferTypes(); } @@ -149,25 +154,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable _connectBlocking = connectBlocking; } - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.Dumpable#dump() - */ - public String dump() - { - return AggregateLifeCycle.dump(this); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String) - */ - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(this)).append("\n"); - AggregateLifeCycle.dump(out,indent,Arrays.asList(_threadPool,_connector),_destinations.values()); - } - /* ------------------------------------------------------------------------------- */ public void send(HttpExchange exchange) throws IOException { @@ -190,6 +176,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable pool.setDaemon(true); pool.setName("HttpClient"); _threadPool = pool; + addBean(_threadPool,true); } return _threadPool; @@ -201,7 +188,9 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable */ public void setThreadPool(ThreadPool threadPool) { + removeBean(_threadPool); _threadPool = threadPool; + addBean(_threadPool); } @@ -338,6 +327,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable } + /* ------------------------------------------------------------ */ /** * Registers a listener that can listen to the stream of execution between the client and the * server and influence events. Sequential calls to the method wrapper sequentially wrap the preceding @@ -422,7 +412,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable protected void doStart() throws Exception { setBufferTypes(); - super.doStart(); _timeoutQ.setDuration(_timeout); _timeoutQ.setNow(); @@ -432,24 +421,12 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable if (_threadPool == null) getThreadPool(); - if (_threadPool instanceof LifeCycle) - { - ((LifeCycle)_threadPool).start(); - } - - _sslContextFactory.start(); - - if (_connectorType == CONNECTOR_SELECT_CHANNEL) - { - - _connector = new SelectConnector(this); - } - else - { - _connector = new SocketConnector(this); - } - _connector.start(); - + + _connector=(_connectorType == CONNECTOR_SELECT_CHANNEL)?new SelectConnector(this):new SocketConnector(this); + addBean(_connector,true); + + super.doStart(); + _threadPool.dispatch(new Runnable() { public void run() @@ -480,14 +457,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable @Override protected void doStop() throws Exception { - _connector.stop(); - _connector = null; - _sslContextFactory.stop(); - - if (_threadPool instanceof LifeCycle) - { - ((LifeCycle)_threadPool).stop(); - } for (HttpDestination destination : _destinations.values()) { destination.close(); @@ -496,6 +465,8 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable _timeoutQ.cancelAll(); _idleTimeoutQ.cancelAll(); super.doStop(); + _connector = null; + removeBean(_connector); } /* ------------------------------------------------------------ */ @@ -667,6 +638,98 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable _maxRedirects = redirects; } + + + public int getRequestBufferSize() + { + return _buffers.getRequestBufferSize(); + } + + public void setRequestBufferSize(int requestBufferSize) + { + _buffers.setRequestBufferSize(requestBufferSize); + } + + public int getRequestHeaderSize() + { + return _buffers.getRequestHeaderSize(); + } + + public void setRequestHeaderSize(int requestHeaderSize) + { + _buffers.setRequestHeaderSize(requestHeaderSize); + } + + public int getResponseBufferSize() + { + return _buffers.getResponseBufferSize(); + } + + public void setResponseBufferSize(int responseBufferSize) + { + _buffers.setResponseBufferSize(responseBufferSize); + } + + public int getResponseHeaderSize() + { + return _buffers.getResponseHeaderSize(); + } + + public void setResponseHeaderSize(int responseHeaderSize) + { + _buffers.setResponseHeaderSize(responseHeaderSize); + } + + public Type getRequestBufferType() + { + return _buffers.getRequestBufferType(); + } + + public Type getRequestHeaderType() + { + return _buffers.getRequestHeaderType(); + } + + public Type getResponseBufferType() + { + return _buffers.getResponseBufferType(); + } + + public Type getResponseHeaderType() + { + return _buffers.getResponseHeaderType(); + } + + public void setRequestBuffers(Buffers requestBuffers) + { + _buffers.setRequestBuffers(requestBuffers); + } + + public void setResponseBuffers(Buffers responseBuffers) + { + _buffers.setResponseBuffers(responseBuffers); + } + + public Buffers getRequestBuffers() + { + return _buffers.getRequestBuffers(); + } + + public Buffers getResponseBuffers() + { + return _buffers.getResponseBuffers(); + } + + public void setMaxBuffers(int maxBuffers) + { + _buffers.setMaxBuffers(maxBuffers); + } + + public int getMaxBuffers() + { + return _buffers.getMaxBuffers(); + } + /* ------------------------------------------------------------ */ @Deprecated public String getTrustStoreLocation() diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java index b3c93a7dee8..892991bd964 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java @@ -97,9 +97,9 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, if (_httpClient.isConnectBlocking()) { - channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout()); - channel.configureBlocking(false); - _selectorManager.register( channel, destination ); + channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout()); + channel.configureBlocking(false); + _selectorManager.register( channel, destination ); } else { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java index 28c5ad13bdf..a502e72567f 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java @@ -19,211 +19,85 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle; /* ------------------------------------------------------------ */ /** Abstract Buffer pool. - * simple unbounded pool of buffers for header, request and response sizes. - * */ -public class HttpBuffers extends AbstractLifeCycle +public interface HttpBuffers { - private int _requestBufferSize=16*1024; - private int _requestHeaderSize=6*1024; - private int _responseBufferSize=32*1024; - private int _responseHeaderSize=6*1024; - private int _maxBuffers=1024; - - private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY; - private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY; - private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY; - private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY; - - private Buffers _requestBuffers; - private Buffers _responseBuffers; - - - public HttpBuffers() - { - super(); - } - /** * @return the requestBufferSize */ - public int getRequestBufferSize() - { - return _requestBufferSize; - } + public int getRequestBufferSize(); /** * @param requestBufferSize the requestBufferSize to set */ - public void setRequestBufferSize(int requestBufferSize) - { - _requestBufferSize = requestBufferSize; - } + public void setRequestBufferSize(int requestBufferSize); /** * @return the requestHeaderSize */ - public int getRequestHeaderSize() - { - return _requestHeaderSize; - } + public int getRequestHeaderSize(); /** * @param requestHeaderSize the requestHeaderSize to set */ - public void setRequestHeaderSize(int requestHeaderSize) - { - _requestHeaderSize = requestHeaderSize; - } + public void setRequestHeaderSize(int requestHeaderSize); /** * @return the responseBufferSize */ - public int getResponseBufferSize() - { - return _responseBufferSize; - } + public int getResponseBufferSize(); /** * @param responseBufferSize the responseBufferSize to set */ - public void setResponseBufferSize(int responseBufferSize) - { - _responseBufferSize = responseBufferSize; - } + public void setResponseBufferSize(int responseBufferSize); /** * @return the responseHeaderSize */ - public int getResponseHeaderSize() - { - return _responseHeaderSize; - } + public int getResponseHeaderSize(); /** * @param responseHeaderSize the responseHeaderSize to set */ - public void setResponseHeaderSize(int responseHeaderSize) - { - _responseHeaderSize = responseHeaderSize; - } + public void setResponseHeaderSize(int responseHeaderSize); /** * @return the requestBufferType */ - public Buffers.Type getRequestBufferType() - { - return _requestBufferType; - } - - /** - * @param requestBufferType the requestBufferType to set - */ - protected void setRequestBufferType(Buffers.Type requestBufferType) - { - _requestBufferType = requestBufferType; - } + public Buffers.Type getRequestBufferType(); /** * @return the requestHeaderType */ - public Buffers.Type getRequestHeaderType() - { - return _requestHeaderType; - } - - /** - * @param requestHeaderType the requestHeaderType to set - */ - protected void setRequestHeaderType(Buffers.Type requestHeaderType) - { - _requestHeaderType = requestHeaderType; - } + public Buffers.Type getRequestHeaderType(); /** * @return the responseBufferType */ - public Buffers.Type getResponseBufferType() - { - return _responseBufferType; - } - - /** - * @param responseBufferType the responseBufferType to set - */ - protected void setResponseBufferType(Buffers.Type responseBufferType) - { - _responseBufferType = responseBufferType; - } + public Buffers.Type getResponseBufferType(); /** * @return the responseHeaderType */ - public Buffers.Type getResponseHeaderType() - { - return _responseHeaderType; - } - - /** - * @param responseHeaderType the responseHeaderType to set - */ - protected void setResponseHeaderType(Buffers.Type responseHeaderType) - { - _responseHeaderType = responseHeaderType; - } + public Buffers.Type getResponseHeaderType(); /** * @param requestBuffers the requestBuffers to set */ - public void setRequestBuffers(Buffers requestBuffers) - { - _requestBuffers = requestBuffers; - } + public void setRequestBuffers(Buffers requestBuffers); /** * @param responseBuffers the responseBuffers to set */ - public void setResponseBuffers(Buffers responseBuffers) - { - _responseBuffers = responseBuffers; - } + public void setResponseBuffers(Buffers responseBuffers); - @Override - protected void doStart() - throws Exception - { - _requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers()); - _responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers()); - super.doStart(); - } - - @Override - protected void doStop() - throws Exception - { - _requestBuffers=null; - _responseBuffers=null; - } + public Buffers getRequestBuffers(); - public Buffers getRequestBuffers() - { - return _requestBuffers; - } - + public Buffers getResponseBuffers(); - public Buffers getResponseBuffers() - { - return _responseBuffers; - } + public void setMaxBuffers(int maxBuffers); - public void setMaxBuffers(int maxBuffers) - { - _maxBuffers = maxBuffers; - } - - public int getMaxBuffers() - { - return _maxBuffers; - } + public int getMaxBuffers(); } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java new file mode 100644 index 00000000000..43db337e73c --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java @@ -0,0 +1,233 @@ +// ======================================================================== +// Copyright (c) 2004-2009 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.http; + +import org.eclipse.jetty.io.Buffers; +import org.eclipse.jetty.io.BuffersFactory; +import org.eclipse.jetty.util.component.AbstractLifeCycle; + +/* ------------------------------------------------------------ */ +/** Abstract Buffer pool. + * simple unbounded pool of buffers for header, request and response sizes. + * + */ +public class HttpBuffersImpl extends AbstractLifeCycle implements HttpBuffers +{ + private int _requestBufferSize=16*1024; + private int _requestHeaderSize=6*1024; + private int _responseBufferSize=32*1024; + private int _responseHeaderSize=6*1024; + private int _maxBuffers=1024; + + private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY; + private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY; + private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY; + private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY; + + private Buffers _requestBuffers; + private Buffers _responseBuffers; + + + public HttpBuffersImpl() + { + super(); + } + + /** + * @return the requestBufferSize + */ + public int getRequestBufferSize() + { + return _requestBufferSize; + } + + /** + * @param requestBufferSize the requestBufferSize to set + */ + public void setRequestBufferSize(int requestBufferSize) + { + _requestBufferSize = requestBufferSize; + } + + /** + * @return the requestHeaderSize + */ + public int getRequestHeaderSize() + { + return _requestHeaderSize; + } + + /** + * @param requestHeaderSize the requestHeaderSize to set + */ + public void setRequestHeaderSize(int requestHeaderSize) + { + _requestHeaderSize = requestHeaderSize; + } + + /** + * @return the responseBufferSize + */ + public int getResponseBufferSize() + { + return _responseBufferSize; + } + + /** + * @param responseBufferSize the responseBufferSize to set + */ + public void setResponseBufferSize(int responseBufferSize) + { + _responseBufferSize = responseBufferSize; + } + + /** + * @return the responseHeaderSize + */ + public int getResponseHeaderSize() + { + return _responseHeaderSize; + } + + /** + * @param responseHeaderSize the responseHeaderSize to set + */ + public void setResponseHeaderSize(int responseHeaderSize) + { + _responseHeaderSize = responseHeaderSize; + } + + /** + * @return the requestBufferType + */ + public Buffers.Type getRequestBufferType() + { + return _requestBufferType; + } + + /** + * @param requestBufferType the requestBufferType to set + */ + public void setRequestBufferType(Buffers.Type requestBufferType) + { + _requestBufferType = requestBufferType; + } + + /** + * @return the requestHeaderType + */ + public Buffers.Type getRequestHeaderType() + { + return _requestHeaderType; + } + + /** + * @param requestHeaderType the requestHeaderType to set + */ + public void setRequestHeaderType(Buffers.Type requestHeaderType) + { + _requestHeaderType = requestHeaderType; + } + + /** + * @return the responseBufferType + */ + public Buffers.Type getResponseBufferType() + { + return _responseBufferType; + } + + /** + * @param responseBufferType the responseBufferType to set + */ + public void setResponseBufferType(Buffers.Type responseBufferType) + { + _responseBufferType = responseBufferType; + } + + /** + * @return the responseHeaderType + */ + public Buffers.Type getResponseHeaderType() + { + return _responseHeaderType; + } + + /** + * @param responseHeaderType the responseHeaderType to set + */ + public void setResponseHeaderType(Buffers.Type responseHeaderType) + { + _responseHeaderType = responseHeaderType; + } + + /** + * @param requestBuffers the requestBuffers to set + */ + public void setRequestBuffers(Buffers requestBuffers) + { + _requestBuffers = requestBuffers; + } + + /** + * @param responseBuffers the responseBuffers to set + */ + public void setResponseBuffers(Buffers responseBuffers) + { + _responseBuffers = responseBuffers; + } + + @Override + protected void doStart() + throws Exception + { + _requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers()); + _responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers()); + super.doStart(); + } + + @Override + protected void doStop() + throws Exception + { + _requestBuffers=null; + _responseBuffers=null; + } + + public Buffers getRequestBuffers() + { + return _requestBuffers; + } + + + public Buffers getResponseBuffers() + { + return _responseBuffers; + } + + public void setMaxBuffers(int maxBuffers) + { + _maxBuffers = maxBuffers; + } + + public int getMaxBuffers() + { + return _maxBuffers; + } + + public String toString() + { + return _requestBuffers+"/"+_responseBuffers; + } +} diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java index ef828361357..bc24d078ae9 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java @@ -2,6 +2,7 @@ package org.eclipse.jetty.io; import org.eclipse.jetty.io.nio.DirectNIOBuffer; import org.eclipse.jetty.io.nio.IndirectNIOBuffer; +import org.omg.stub.java.rmi._Remote_Stub; public abstract class AbstractBuffers implements Buffers { @@ -141,5 +142,10 @@ public abstract class AbstractBuffers implements Buffers } return false; } - + + /* ------------------------------------------------------------ */ + public String toString() + { + return this.getClass().getSimpleName()+"["+_headerSize+","+_bufferSize+"]"; + } } \ No newline at end of file diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java b/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java index 90f297e73d4..9c476312544 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java @@ -92,4 +92,13 @@ public class PooledBuffers extends AbstractBuffers _others.add(buffer); } } + + public String toString() + { + return this.getClass().getSimpleName()+ + "["+ + _headers.size()+"/"+_maxSize+"@"+_headerSize+","+ + _buffers.size()+"/"+_maxSize+"@"+_bufferSize+","+ + _others.size()+"/"+_maxSize+"@-]"; + } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java index eaeabc88624..dd101e9fbc1 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java @@ -938,6 +938,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa final ArrayList dump = new ArrayList(selector.keys().size()*2); dump.add(where); + /* final CountDownLatch latch = new CountDownLatch(1); addChange(new ChangeTask() @@ -957,6 +958,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa { LOG.ignore(e); } + */ + AggregateLifeCycle.dump(out,indent,dump); } } diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java index 9cb9def596a..85cab0f2ba0 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java @@ -31,6 +31,7 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.util.log.Log; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -87,7 +88,8 @@ public class ProxyRuleTest @Test public void testProxy() throws Exception { - + Log.getLogger("org.eclipse.jetty.client").setDebugEnabled(true); + ContentExchange exchange = new ContentExchange(true); exchange.setMethod(HttpMethods.GET); String body = "BODY"; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index 6f349ca4f8b..acc51a1c4cb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -22,9 +22,12 @@ import java.util.concurrent.atomic.AtomicLong; import javax.servlet.ServletRequest; import org.eclipse.jetty.http.HttpBuffers; +import org.eclipse.jetty.http.HttpBuffersImpl; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.io.Buffers; +import org.eclipse.jetty.io.Buffers.Type; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EofException; @@ -51,7 +54,7 @@ import org.eclipse.jetty.util.thread.ThreadPool; * * */ -public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable +public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable { private static final Logger LOG = Log.getLogger(AbstractConnector.class); @@ -95,11 +98,14 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /** duration of a connection */ private final SampleStatistic _connectionDurationStats = new SampleStatistic(); + protected final HttpBuffersImpl _buffers = new HttpBuffersImpl(); + /* ------------------------------------------------------------ */ /** */ public AbstractConnector() { + addBean(_buffers); } /* ------------------------------------------------------------ */ @@ -125,7 +131,9 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /* ------------------------------------------------------------ */ public void setThreadPool(ThreadPool pool) { + removeBean(_threadPool); _threadPool = pool; + addBean(_threadPool); } /* ------------------------------------------------------------ */ @@ -299,12 +307,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector // open listener port open(); - super.doStart(); - if (_threadPool == null) + { _threadPool = _server.getThreadPool(); - if (_threadPool != _server.getThreadPool() && (_threadPool instanceof LifeCycle)) - ((LifeCycle)_threadPool).start(); + addBean(_threadPool,false); + } + + super.doStart(); // Start selector thread synchronized (this) @@ -333,9 +342,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector LOG.warn(e); } - if (_threadPool != _server.getThreadPool() && _threadPool instanceof LifeCycle) - ((LifeCycle)_threadPool).stop(); - super.doStop(); Thread[] acceptors = null; @@ -785,6 +791,98 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _forwardedSslSessionIdHeader = forwardedSslSessionId; } + + + + public int getRequestBufferSize() + { + return _buffers.getRequestBufferSize(); + } + + public void setRequestBufferSize(int requestBufferSize) + { + _buffers.setRequestBufferSize(requestBufferSize); + } + + public int getRequestHeaderSize() + { + return _buffers.getRequestHeaderSize(); + } + + public void setRequestHeaderSize(int requestHeaderSize) + { + _buffers.setRequestHeaderSize(requestHeaderSize); + } + + public int getResponseBufferSize() + { + return _buffers.getResponseBufferSize(); + } + + public void setResponseBufferSize(int responseBufferSize) + { + _buffers.setResponseBufferSize(responseBufferSize); + } + + public int getResponseHeaderSize() + { + return _buffers.getResponseHeaderSize(); + } + + public void setResponseHeaderSize(int responseHeaderSize) + { + _buffers.setResponseHeaderSize(responseHeaderSize); + } + + public Type getRequestBufferType() + { + return _buffers.getRequestBufferType(); + } + + public Type getRequestHeaderType() + { + return _buffers.getRequestHeaderType(); + } + + public Type getResponseBufferType() + { + return _buffers.getResponseBufferType(); + } + + public Type getResponseHeaderType() + { + return _buffers.getResponseHeaderType(); + } + + public void setRequestBuffers(Buffers requestBuffers) + { + _buffers.setRequestBuffers(requestBuffers); + } + + public void setResponseBuffers(Buffers responseBuffers) + { + _buffers.setResponseBuffers(responseBuffers); + } + + public Buffers getRequestBuffers() + { + return _buffers.getRequestBuffers(); + } + + public Buffers getResponseBuffers() + { + return _buffers.getResponseBuffers(); + } + + public void setMaxBuffers(int maxBuffers) + { + _buffers.setMaxBuffers(maxBuffers); + } + + public int getMaxBuffers() + { + return _buffers.getMaxBuffers(); + } /* ------------------------------------------------------------ */ @Override @@ -1118,17 +1216,4 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector oldValue = valueHolder.get(); } } - - /* ------------------------------------------------------------ */ - public String dump() - { - return AggregateLifeCycle.dump(this); - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(this)).append("\n"); - } - } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java index 4fc4d1a301c..2083c5d3714 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java @@ -27,10 +27,10 @@ import org.eclipse.jetty.server.AbstractConnector; public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector { { - setRequestBufferType(Type.DIRECT); - setRequestHeaderType(Type.INDIRECT); - setResponseBufferType(Type.DIRECT); - setResponseHeaderType(Type.INDIRECT); + _buffers.setRequestBufferType(Type.DIRECT); + _buffers.setRequestHeaderType(Type.INDIRECT); + _buffers.setResponseBufferType(Type.DIRECT); + _buffers.setResponseHeaderType(Type.INDIRECT); } /* ------------------------------------------------------------------------------- */ @@ -46,8 +46,8 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements */ public void setUseDirectBuffers(boolean direct) { - setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT); - setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT); + _buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT); + _buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java index b6165d45fdf..9cf3ede1fef 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java @@ -82,6 +82,7 @@ public class SelectChannelConnector extends AbstractNIOConnector public SelectChannelConnector() { _manager.setMaxIdleTime(getMaxIdleTime()); + addBean(_manager,true); setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4)); } @@ -111,7 +112,11 @@ public class SelectChannelConnector extends AbstractNIOConnector synchronized(this) { if (_acceptChannel != null) - _acceptChannel.close(); + { + removeBean(_acceptChannel); + if (_acceptChannel.isOpen()) + _acceptChannel.close(); + } _acceptChannel = null; _localPort=-2; } @@ -177,6 +182,8 @@ public class SelectChannelConnector extends AbstractNIOConnector _localPort=_acceptChannel.socket().getLocalPort(); if (_localPort<=0) throw new IOException("Server channel not bound"); + + addBean(_acceptChannel); } } @@ -250,7 +257,6 @@ public class SelectChannelConnector extends AbstractNIOConnector _manager.setLowResourcesMaxIdleTime(getLowResourcesMaxIdleTime()); super.doStart(); - _manager.start(); } /* ------------------------------------------------------------ */ @@ -260,20 +266,7 @@ public class SelectChannelConnector extends AbstractNIOConnector @Override protected void doStop() throws Exception { - synchronized(this) - { - if(_manager.isRunning()) - { - try - { - _manager.stop(); - } - catch (Exception e) - { - LOG.warn(e); - } - } - } + close(); super.doStop(); } @@ -297,20 +290,6 @@ public class SelectChannelConnector extends AbstractNIOConnector return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer()); } - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - super.dump(out, indent); - ServerSocketChannel channel; - synchronized (this) - { - channel=_acceptChannel; - } - if (channel==null) - AggregateLifeCycle.dump(out,indent,Arrays.asList(null,"CLOSED",_manager)); - else - AggregateLifeCycle.dump(out,indent,Arrays.asList(channel,channel.isOpen()?"OPEN":"CLOSED",_manager)); - } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java index 1986e7bc08d..e7746cbb5c6 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java @@ -57,6 +57,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements public SslSelectChannelConnector(SslContextFactory sslContextFactory) { _sslContextFactory = sslContextFactory; + addBean(_sslContextFactory); setUseDirectBuffers(false); setSoLingerTime(30000); } @@ -597,7 +598,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements protected void doStart() throws Exception { _sslContextFactory.checkKeyStore(); - _sslContextFactory.start(); SSLEngine sslEngine = _sslContextFactory.newSslEngine(); @@ -627,7 +627,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements @Override protected void doStop() throws Exception { - _sslContextFactory.stop(); _sslBuffers=null; super.doStop(); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java index 8e14c84b7d0..281779a5241 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java @@ -12,92 +12,242 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; /** - * An AggregateLifeCycle is an AbstractLifeCycle with a collection of dependent beans. + * An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans. + *

+ * Beans can be added the AggregateLifeCycle either as joined beans, as disjoint beans. A joined bean is started, stopped and destroyed with the aggregate. + * A disjointed bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally. + *

+ * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be a disjoined bean. + * Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #join(LifeCycle)} and {@link #disjoin(LifeCycle)} can be used to + * explicitly control the life cycle relationship. *

- * Dependent beans are started and stopped with the {@link LifeCycle} and if they are destroyed if they are also {@link Destroyable}. - * */ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable { private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class); - private final List _dependentBeans=new CopyOnWriteArrayList(); + private final List _beans=new CopyOnWriteArrayList(); - public void destroy() + private class Bean { - for (Object o : _dependentBeans) + Bean(Object b) { - if (o instanceof Destroyable) - { - ((Destroyable)o).destroy(); - } + _bean=b; } - _dependentBeans.clear(); + final Object _bean; + volatile boolean _joined=true; } + /* ------------------------------------------------------------ */ + /** + * Start the joined lifecycle beans in the order they were added. + * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() + */ @Override protected void doStart() throws Exception { - for (Object o:_dependentBeans) + for (Bean b:_beans) { - if (o instanceof LifeCycle) - ((LifeCycle)o).start(); + if (b._joined && b._bean instanceof LifeCycle) + { + LifeCycle l=(LifeCycle)b._bean; + if (!l.isRunning()) + l.start(); + } } super.doStart(); } - + + /* ------------------------------------------------------------ */ + /** + * Stop the joined lifecycle beans in the reverse order they were added. + * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() + */ @Override protected void doStop() throws Exception { super.doStop(); - List reverse = new ArrayList(_dependentBeans); + List reverse = new ArrayList(_beans); Collections.reverse(reverse); - for (Object o:reverse) + for (Bean b:reverse) { - if (o instanceof LifeCycle) - ((LifeCycle)o).stop(); + if (b._joined && b._bean instanceof LifeCycle) + { + LifeCycle l=(LifeCycle)b._bean; + if (l.isRunning()) + l.stop(); + } } } + /* ------------------------------------------------------------ */ + /** + * Destroy the joined Destroyable beans in the reverse order they were added. + * @see org.eclipse.jetty.util.component.Destroyable#destroy() + */ + public void destroy() + { + List reverse = new ArrayList(_beans); + Collections.reverse(reverse); + for (Bean b:reverse) + { + if (b._bean instanceof Destroyable && b._joined) + { + Destroyable d=(Destroyable)b._bean; + d.destroy(); + } + } + _beans.clear(); + } + + + /* ------------------------------------------------------------ */ + /** Is the bean contained in the aggregate. + * @param bean + * @return True if the aggregate contains the bean + */ + public boolean contains(Object bean) + { + for (Bean b:_beans) + if (b._bean==bean) + return true; + return false; + } + + /* ------------------------------------------------------------ */ + /** Is the bean joined to the aggregate. + * @param bean + * @return True if the aggregate contains the bean and it is joined + */ + public boolean isJoined(Object bean) + { + for (Bean b:_beans) + if (b._bean==bean) + return b._joined; + return false; + } + /* ------------------------------------------------------------ */ /** * Add an associated bean. - * The bean will be added to this LifeCycle and if it is also a - * {@link LifeCycle} instance, it will be - * started/stopped. Any beans that are also - * {@link Destroyable}, will be destroyed with the server. + * If the bean is a {@link LifeCycle}, it is added as neither joined or disjoint and + * that status will be determined when the Aggregate bean is started. * @param o the bean object to add + * @return true if the bean was added or false if it has already been added. */ public boolean addBean(Object o) { - if (o == null) + if (contains(o)) return false; - boolean added=false; - if (!_dependentBeans.contains(o)) + + Bean b = new Bean(o); + _beans.add(b); + + // extra LifeCycle handling + if (o instanceof LifeCycle) { - _dependentBeans.add(o); - added=true; + LifeCycle l=(LifeCycle)o; + + // If it is running, then assume it is disjoint + if (l.isRunning()) + b._joined=false; + + // else if we are running, then start the bean + else if (isRunning()) + { + try + { + l.start(); + } + catch(Exception e) + { + throw new RuntimeException (e); + } + } } - try + return true; + } + + /* ------------------------------------------------------------ */ + /** Add an associated lifecycle. + * @param o The lifecycle to add + * @param joined True if the LifeCycle is to be joined, otherwise it will be disjoint. + * @return + */ + public boolean addBean(Object o, boolean joined) + { + if (contains(o)) + return false; + + Bean b = new Bean(o); + b._joined=joined; + _beans.add(b); + + if (o instanceof LifeCycle) { - if (isStarted() && o instanceof LifeCycle) - ((LifeCycle)o).start(); + LifeCycle l=(LifeCycle)o; + + if (joined && isRunning()) + { + try + { + l.start(); + } + catch(Exception e) + { + throw new RuntimeException (e); + } + } } - catch (Exception e) + return true; + } + + /* ------------------------------------------------------------ */ + /** + * Join a bean to this aggregate, so that it is started/stopped/destroyed with the + * aggregate lifecycle. + * @param bean The bean to join (must already have been added). + */ + public void join(Object bean) + { + for (Bean b :_beans) { - throw new RuntimeException (e); + if (b._bean==bean) + { + b._joined=true; + return; + } } - return added; + throw new IllegalArgumentException(); } + /* ------------------------------------------------------------ */ + /** + * Disjoin a bean to this aggregate, so that it is not started/stopped/destroyed with the + * aggregate lifecycle. + * @param bean The bean to join (must already have been added). + */ + public void disjoin(Object bean) + { + for (Bean b :_beans) + { + if (b._bean==bean) + { + b._joined=false; + return; + } + } + throw new IllegalArgumentException(); + } + /* ------------------------------------------------------------ */ /** Get dependent beans * @return List of beans. */ public Collection getBeans() { - return _dependentBeans; + return getBeans(Object.class); } /* ------------------------------------------------------------ */ @@ -109,19 +259,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable public List getBeans(Class clazz) { ArrayList beans = new ArrayList(); - Iterator iter = _dependentBeans.iterator(); - while (iter.hasNext()) + for (Bean b:_beans) { - Object o = iter.next(); - if (clazz.isInstance(o)) - beans.add((T)o); + if (clazz.isInstance(b._bean)) + beans.add((T)(b._bean)); } return beans; } /* ------------------------------------------------------------ */ - /** Get dependent bean of a specific class. + /** Get dependent beans of a specific class. * If more than one bean of the type exist, the first is returned. * @see #addBean(Object) * @param clazz @@ -129,23 +277,13 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable */ public T getBean(Class clazz) { - Iterator iter = _dependentBeans.iterator(); - T t=null; - int count=0; - while (iter.hasNext()) + for (Bean b:_beans) { - Object o = iter.next(); - if (clazz.isInstance(o)) - { - count++; - if (t==null) - t=(T)o; - } + if (clazz.isInstance(b._bean)) + return (T)b._bean; } - if (count>1 && LOG.isDebugEnabled()) - LOG.debug("getBean({}) 1 of {}",clazz.getName(),count); - return t; + return null; } /* ------------------------------------------------------------ */ @@ -154,7 +292,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable */ public void removeBeans () { - _dependentBeans.clear(); + _beans.clear(); } /* ------------------------------------------------------------ */ @@ -163,9 +301,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable */ public boolean removeBean (Object o) { - if (o == null) - return false; - return _dependentBeans.remove(o); + Iterator i = _beans.iterator(); + while(i.hasNext()) + { + Bean b=i.next(); + if (b._bean==o) + { + _beans.remove(b); + return true; + } + } + return false; } /* ------------------------------------------------------------ */ @@ -218,7 +364,32 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable public void dump(Appendable out,String indent) throws IOException { dumpThis(out); - dump(out,indent,_dependentBeans); + int size=_beans.size(); + if (size==0) + return; + int i=0; + for (Bean b : _beans) + { + i++; + + if (b._joined) + { + out.append(indent).append(" +- "); + if (b._bean instanceof Dumpable) + ((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | ")); + else + out.append(String.valueOf(b._bean)).append("\n"); + } + else + { + out.append(indent).append(" +~ "); + out.append(String.valueOf(b._bean)).append("\n"); + } + + } + + if (i!=size) + out.append(indent).append(" |\n"); } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index 6180022cd7e..d1b8d9bbfac 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1521,5 +1521,11 @@ public class SslContextFactory extends AbstractLifeCycle sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols())); } - + + /* ------------------------------------------------------------ */ + public String toString() + { + return this.getClass().getSimpleName()+"@"+Integer.toHexString(hashCode())+ + "("+_keyStorePath+","+_trustStorePath+")#"+getState(); + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java index 3bda2998abc..2b5ec8d6e86 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java @@ -110,6 +110,107 @@ public class AggregateLifeCycleTest } + @Test + public void testDisJoint() throws Exception + { + final AtomicInteger destroyed=new AtomicInteger(); + final AtomicInteger started=new AtomicInteger(); + final AtomicInteger stopped=new AtomicInteger(); + + AggregateLifeCycle a0=new AggregateLifeCycle(); + + AggregateLifeCycle a1=new AggregateLifeCycle() + { + @Override + protected void doStart() throws Exception + { + started.incrementAndGet(); + super.doStart(); + } + + @Override + protected void doStop() throws Exception + { + stopped.incrementAndGet(); + super.doStop(); + } + + @Override + public void destroy() + { + destroyed.incrementAndGet(); + super.destroy(); + } + + }; + + // Start the a1 bean before adding, makes it auto disjoint + a1.start(); + + // Now add it + a0.addBean(a1); + Assert.assertFalse(a0.isJoined(a1)); + + a0.start(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(0,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.start(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(0,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.stop(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(0,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a1.stop(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.start(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.join(a1); + Assert.assertTrue(a0.isJoined(a1)); + + a0.stop(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + + a0.start(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.stop(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(2,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + + a0.disjoin(a1); + Assert.assertFalse(a0.isJoined(a1)); + + a0.destroy(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(2,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a1.destroy(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(2,stopped.get()); + Assert.assertEquals(1,destroyed.get()); + + } + @Test public void testDumpable() { @@ -159,6 +260,11 @@ public class AggregateLifeCycleTest System.err.println("--"); a2.addBean(aa0); a0.dumpStdErr(); + + System.err.println("--"); + a0.disjoin(aa); + a2.disjoin(aa0); + a0.dumpStdErr(); } }