diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java index 3548d7f19f5..4dc4411c806 100644 --- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java @@ -41,7 +41,6 @@ public class ManyConnectors SelectChannelConnector connector1 = new SelectChannelConnector(server); connector1.setHost("127.0.0.1"); connector1.setPort(8888); - connector1.setName("admin"); String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution"); System.setProperty("jetty.home", jetty_home); diff --git a/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java b/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java index 45c474dfa0d..fdcea86c59c 100644 --- a/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java +++ b/example-jetty-embedded/src/test/java/org/eclipse/jetty/embedded/GzipHandlerTest.java @@ -34,7 +34,7 @@ import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.server.handler.GzipHandler; +import org.eclipse.jetty.servlets.gzip.GzipHandler; import org.eclipse.jetty.util.IO; import org.junit.After; import org.junit.Before; diff --git a/jetty-annotations/src/main/config/start.d/100-jetty-annotations.ini b/jetty-annotations/src/main/config/start.d/100-jetty-annotations.ini new file mode 100644 index 00000000000..d950b9efdf4 --- /dev/null +++ b/jetty-annotations/src/main/config/start.d/100-jetty-annotations.ini @@ -0,0 +1,3 @@ +OPTIONS=annotations +etc/jetty-annotations.xml + diff --git a/jetty-client/pom.xml b/jetty-client-old/pom.xml similarity index 100% rename from jetty-client/pom.xml rename to jetty-client-old/pom.xml diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/AbstractHttpConnection.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/Address.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/Address.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/Address.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/Address.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/AsyncHttpConnection.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/CachedExchange.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/CachedExchange.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/CachedExchange.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/ContentExchange.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/ContentExchange.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/ContentExchange.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpClient.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpClient.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpDestination.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpDestination.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpEventListener.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpEventListener.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/HttpEventListener.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpEventListener.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpExchange.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/HttpExchange.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/HttpExchange.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/RedirectListener.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/RedirectListener.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/RedirectListener.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/SelectConnector.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/SelectConnector.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SocketConnector.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/SocketConnector.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/SocketConnector.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/SocketConnector.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/Authentication.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/Authentication.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/Authentication.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/Authentication.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/BasicAuthentication.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/BasicAuthentication.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/BasicAuthentication.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/BasicAuthentication.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/DigestAuthentication.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/HashRealmResolver.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/HashRealmResolver.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/HashRealmResolver.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/HashRealmResolver.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/ProxyAuthorization.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/ProxyAuthorization.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/ProxyAuthorization.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/ProxyAuthorization.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/Realm.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/Realm.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/Realm.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/Realm.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/RealmResolver.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/RealmResolver.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/RealmResolver.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/RealmResolver.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/SecurityListener.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/webdav/MkcolExchange.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/MkcolExchange.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/webdav/MkcolExchange.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/MkcolExchange.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/webdav/PropfindExchange.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/PropfindExchange.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/webdav/PropfindExchange.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/PropfindExchange.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/webdav/WebdavListener.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/WebdavListener.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/webdav/WebdavListener.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/WebdavListener.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java b/jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java similarity index 100% rename from jetty-client/src/main/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java rename to jetty-client-old/src/main/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractConnectionTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/AbstractConnectionTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/AbstractConnectionTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/AbstractConnectionTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/AbstractHttpExchangeCancelTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncCallbackHttpExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSelectConnectionTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncSelectConnectionTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSelectConnectionTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncSelectConnectionTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncSslHttpExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/AsyncSslSecurityListenerTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/BlockingHttpExchangeCancelTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/CachedHeadersIsolationTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/Curl.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/Curl.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/Curl.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ErrorStatusTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExpirationWithLimitedConnectionsTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ExpirationWithLimitedConnectionsTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ExpirationWithLimitedConnectionsTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ExpirationWithLimitedConnectionsTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ExpireTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ExpireTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ExpireTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ExternalKeyStoreAsyncSslHttpExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Http100ContinueTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/Http100ContinueTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/Http100ContinueTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/Http100ContinueTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAsserts.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpAsserts.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpAsserts.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpAsserts.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpDestinationQueueTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpDestinationQueueTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpDestinationQueueTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpDestinationQueueTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpGetRedirectTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpHeadersTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpsProxyAuthenticationTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpsProxyAuthenticationTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpsProxyAuthenticationTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpsProxyAuthenticationTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/HttpsViaBrokenHttpProxyTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/NonBlockingHttpExchangeCancelTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyFakeTunnelTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ProxyFakeTunnelTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ProxyFakeTunnelTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ProxyFakeTunnelTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/ProxyTunnellingTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SecuredContentExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SecurityListenerTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SelectConnectionTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SelectConnectionTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SelectConnectionTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SelectConnectionTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Siege.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/Siege.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/Siege.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/Siege.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SluggishServerTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SocketConnectionTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SocketConnectionTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SocketConnectionTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SocketConnectionTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslBytesClientTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslBytesTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslBytesTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslCertSecuredExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslCertSecuredExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslCertSecuredExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslCertSecuredExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslContentExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslContentExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslContentExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslContentExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslHttpExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSecuredContentExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSecuredErrorStatusTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSecurityListenerTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSelectChannelValidationTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSelectChannelValidationTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslSelectChannelValidationTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSelectChannelValidationTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslSocketValidationTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSocketValidationTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslSocketValidationTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslSocketValidationTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslValidationTestBase.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/SslValidationTestBase.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/SslValidationTestBase.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/SslValidationTestBase.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/TimeoutExchangeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/TimeoutExchangeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/TimeoutExchangeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/TimeoutExchangeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/TimeoutTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/TimeoutTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/TimeoutTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/TimeoutTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/UnexpectedDataTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/WebSocketUpgradeTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/WebdavListenerTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/WebdavListenerTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/WebdavListenerTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/WebdavListenerTest.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/AbstractSslServerAndClientCreator.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/AsyncSslServerAndClientCreator.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/ExternalKeyStoreAsyncSslServerAndClientCreator.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/ExternalKeyStoreAsyncSslServerAndClientCreator.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/ExternalKeyStoreAsyncSslServerAndClientCreator.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/ExternalKeyStoreAsyncSslServerAndClientCreator.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/GenericServerHandler.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/GenericServerHandler.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/GenericServerHandler.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/GenericServerHandler.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/HttpServerAndClientCreator.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/HttpServerAndClientCreator.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/HttpServerAndClientCreator.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/HttpServerAndClientCreator.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/ServerAndClientCreator.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/ServerAndClientCreator.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/ServerAndClientCreator.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/ServerAndClientCreator.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/SslServerAndClientCreator.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/SslServerAndClientCreator.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/helperClasses/SslServerAndClientCreator.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/helperClasses/SslServerAndClientCreator.java diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java b/jetty-client-old/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java similarity index 100% rename from jetty-client/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java rename to jetty-client-old/src/test/java/org/eclipse/jetty/client/security/SecurityResolverTest.java diff --git a/jetty-client/src/test/resources/foo.txt b/jetty-client-old/src/test/resources/foo.txt similarity index 100% rename from jetty-client/src/test/resources/foo.txt rename to jetty-client-old/src/test/resources/foo.txt diff --git a/jetty-client/src/test/resources/keystore b/jetty-client-old/src/test/resources/keystore similarity index 100% rename from jetty-client/src/test/resources/keystore rename to jetty-client-old/src/test/resources/keystore diff --git a/jetty-client/src/test/resources/realm.properties b/jetty-client-old/src/test/resources/realm.properties similarity index 100% rename from jetty-client/src/test/resources/realm.properties rename to jetty-client-old/src/test/resources/realm.properties diff --git a/jetty-deploy/src/test/resources/jetty.xml b/jetty-deploy/src/test/resources/jetty.xml index 785ca813206..3f343ececcf 100644 --- a/jetty-deploy/src/test/resources/jetty.xml +++ b/jetty-deploy/src/test/resources/jetty.xml @@ -15,18 +15,10 @@ - 200 10 - - diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 5e55683ef7e..b77c9dd653d 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -343,22 +343,24 @@ ${project.version} - - Configure javadoc.xml /resources /resources/ diff --git a/jetty-distribution/src/main/resources/contexts/javadoc.xml b/jetty-distribution/src/main/resources/contexts/javadoc.xml index d2a1509300b..3fec5c07feb 100644 --- a/jetty-distribution/src/main/resources/contexts/javadoc.xml +++ b/jetty-distribution/src/main/resources/contexts/javadoc.xml @@ -9,7 +9,6 @@ to serve static html files and images. --> - Configure javadoc.xml /javadoc /javadoc/ diff --git a/jetty-distribution/src/main/resources/start.ini b/jetty-distribution/src/main/resources/start.ini index dfc2783db50..b86d24d2c77 100644 --- a/jetty-distribution/src/main/resources/start.ini +++ b/jetty-distribution/src/main/resources/start.ini @@ -1,8 +1,13 @@ #=========================================================== # Jetty start.jar arguments -# Each line of this file is prepended to the command line -# arguments # of a call to: +# The contents of this file, together with the start.ini +# fragments found in start.d directory are used to build +# the classpath and command line on a call to # java -jar start.jar [arg...] +# +# Use the following command to see more options +# java -jar start.jar --help +# #=========================================================== @@ -46,7 +51,7 @@ # for a full listing do # java -jar start.jar --list-options #----------------------------------------------------------- -OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,annotations +OPTIONS=Server,jsp,resources,websocket,ext,plus #----------------------------------------------------------- @@ -55,9 +60,7 @@ OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,annotations # For a full list of available configuration files do # java -jar start.jar --help #----------------------------------------------------------- -#etc/jetty-jmx.xml etc/jetty.xml -etc/jetty-annotations.xml # etc/jetty-ssl.xml # etc/jetty-requestlog.xml etc/jetty-deploy.xml diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 2439c0b09d1..aa5a9229fb9 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -17,11 +17,6 @@ jetty-io ${project.version} - - org.eclipse.jetty.orbit - javax.servlet - provided - org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index 26c9f08e4f5..2db27b62bc5 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -72,7 +72,7 @@ public class HttpParser private boolean _host; /* ------------------------------------------------------------------------------- */ - private State _state=State.START; + private volatile State _state=State.START; private HttpMethod _method; private String _methodString; private HttpVersion _version; @@ -217,7 +217,7 @@ public class HttpParser { _methodString = _method.asString(); buffer.position(buffer.position()+_methodString.length()+1); - _state=State.SPACE1; + setState(State.SPACE1); return; } } @@ -227,7 +227,7 @@ public class HttpParser if (_version!=null) { buffer.position(buffer.position()+_version.asString().length()+1); - _state=State.SPACE1; + setState(State.SPACE1); return; } } @@ -245,7 +245,7 @@ public class HttpParser { _string.setLength(0); _string.append((char)ch); - _state=_requestHandler!=null?State.METHOD:State.RESPONSE_VERSION; + setState(_requestHandler!=null?State.METHOD:State.RESPONSE_VERSION); return; } } @@ -314,7 +314,7 @@ public class HttpParser HttpMethod method=HttpMethod.CACHE.get(_methodString); if (method!=null) _methodString=method.asString(); - _state=State.SPACE1; + setState(State.SPACE1); } else if (ch < HttpTokens.SPACE && ch>=0) { @@ -335,7 +335,7 @@ public class HttpParser badMessage(buffer,HttpStatus.BAD_REQUEST_400,"Unknown Version"); return true; } - _state=State.SPACE1; + setState(State.SPACE1); } else if (ch < HttpTokens.SPACE && ch>=0) { @@ -351,12 +351,12 @@ public class HttpParser { if (_responseHandler!=null) { - _state=State.STATUS; + setState(State.STATUS); _responseStatus=ch-'0'; } else { - _state=State.URI; + setState(State.URI); _utf8.reset(); _utf8.append(ch); } @@ -371,7 +371,7 @@ public class HttpParser case STATUS: if (ch == HttpTokens.SPACE) { - _state=State.SPACE2; + setState(State.SPACE2); } else if (ch>='0' && ch<='9') { @@ -381,7 +381,7 @@ public class HttpParser { return_from_parse|=_responseHandler.startResponse(_version, _responseStatus, null); _eol=ch; - _state=State.HEADER; + setState(State.HEADER); } else { @@ -394,7 +394,7 @@ public class HttpParser { _uri=_utf8.toString(); _utf8.reset(); - _state=State.SPACE2; + setState(State.SPACE2); } else if (ch < HttpTokens.SPACE && ch>=0) { @@ -402,7 +402,7 @@ public class HttpParser _uri=_utf8.toString(); _utf8.reset(); return_from_parse|=_requestHandler.startRequest(_method,_methodString,_uri,null); - _state=State.END; + setState(State.END); BufferUtil.clear(buffer); return_from_parse|=_handler.headerComplete(); return_from_parse|=_handler.messageComplete(_contentPosition); @@ -419,11 +419,11 @@ public class HttpParser if (_responseHandler!=null) { _length=1; - _state=State.REASON; + setState(State.REASON); } else { - _state=State.REQUEST_VERSION; + setState(State.REQUEST_VERSION); // try quick look ahead if (buffer.position()>0 && buffer.hasArray()) @@ -434,7 +434,7 @@ public class HttpParser _string.setLength(0); buffer.position(buffer.position()+_version.asString().length()-1); _eol=buffer.get(); - _state=State.HEADER; + setState(State.HEADER); return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, _version); } } @@ -446,13 +446,13 @@ public class HttpParser { return_from_parse|=_responseHandler.startResponse(_version, _responseStatus, null); _eol=ch; - _state=State.HEADER; + setState(State.HEADER); } else { // HTTP/0.9 return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, null); - _state=State.END; + setState(State.END); BufferUtil.clear(buffer); return_from_parse|=_handler.headerComplete(); return_from_parse|=_handler.messageComplete(_contentPosition); @@ -472,7 +472,7 @@ public class HttpParser } _eol=ch; - _state=State.HEADER; + setState(State.HEADER); return_from_parse|=_requestHandler.startRequest(_method,_methodString, _uri, _version); continue; } @@ -487,7 +487,7 @@ public class HttpParser String reason=takeLengthString(); _eol=ch; - _state=State.HEADER; + setState(State.HEADER); return_from_parse|=_responseHandler.startResponse(_version, _responseStatus, reason); continue; } @@ -547,7 +547,7 @@ public class HttpParser // header value without name - continuation? _length=-1; _string.setLength(0); - _state=State.HEADER_VALUE; + setState(State.HEADER_VALUE); break; } @@ -673,23 +673,23 @@ public class HttpParser switch (_endOfContent) { case EOF_CONTENT: - _state=State.EOF_CONTENT; + setState(State.EOF_CONTENT); return_from_parse|=_handler.headerComplete(); break; case CHUNKED_CONTENT: - _state=State.CHUNKED_CONTENT; + setState(State.CHUNKED_CONTENT); return_from_parse|=_handler.headerComplete(); break; case NO_CONTENT: return_from_parse|=_handler.headerComplete(); - _state=State.END; + setState(State.END); return_from_parse|=_handler.messageComplete(_contentPosition); break; default: - _state=State.CONTENT; + setState(State.CONTENT); return_from_parse|=_handler.headerComplete(); break; } @@ -705,13 +705,13 @@ public class HttpParser { _headerString=_header.asString(); buffer.position(buffer.position()+_headerString.length()); - _state=buffer.get(buffer.position()-1)==':'?State.HEADER_VALUE:State.HEADER_NAME; + setState(buffer.get(buffer.position()-1)==':'?State.HEADER_VALUE:State.HEADER_NAME); break; } } // New header - _state=State.HEADER_NAME; + setState(State.HEADER_NAME); _string.setLength(0); _string.append((char)ch); _length=1; @@ -729,7 +729,7 @@ public class HttpParser consumeCRLF(ch,buffer); _headerString=takeLengthString(); _header=HttpHeader.CACHE.get(_headerString); - _state=State.HEADER; + setState(State.HEADER); break; @@ -739,7 +739,7 @@ public class HttpParser _headerString=takeLengthString(); _header=HttpHeader.CACHE.get(_headerString); } - _state=State.HEADER_VALUE; + setState(State.HEADER_VALUE); break; case HttpTokens.SPACE: case HttpTokens.TAB: @@ -758,7 +758,7 @@ public class HttpParser } _string.append((char)ch); _length=_string.length(); - _state=State.HEADER_IN_NAME; + setState(State.HEADER_IN_NAME); } } @@ -773,7 +773,7 @@ public class HttpParser _headerString=takeString(); _length=-1; _header=HttpHeader.CACHE.get(_headerString); - _state=State.HEADER; + setState(State.HEADER); break; case HttpTokens.COLON: @@ -783,11 +783,11 @@ public class HttpParser _header=HttpHeader.CACHE.get(_headerString); } _length=-1; - _state=State.HEADER_VALUE; + setState(State.HEADER_VALUE); break; case HttpTokens.SPACE: case HttpTokens.TAB: - _state=State.HEADER_NAME; + setState(State.HEADER_NAME); _string.append((char)ch); break; default: @@ -821,7 +821,7 @@ public class HttpParser _valueString=takeLengthString(); } } - _state=State.HEADER; + setState(State.HEADER); break; case HttpTokens.SPACE: case HttpTokens.TAB: @@ -830,7 +830,7 @@ public class HttpParser { _string.append((char)ch); _length=_string.length(); - _state=State.HEADER_IN_VALUE; + setState(State.HEADER_IN_VALUE); } } break; @@ -861,12 +861,12 @@ public class HttpParser } _length=-1; } - _state=State.HEADER; + setState(State.HEADER); break; case HttpTokens.SPACE: case HttpTokens.TAB: _string.append((char)ch); - _state=State.HEADER_VALUE; + setState(State.HEADER_VALUE); break; default: _string.append((char)ch); @@ -919,7 +919,7 @@ public class HttpParser case CONTENT: if (_contentPosition==_contentLength) { - _state=State.END; + setState(State.END); if(_handler.messageComplete(_contentPosition)) return true; } @@ -936,7 +936,7 @@ public class HttpParser { String chars = BufferUtil.toDetailString(buffer); BufferUtil.clear(buffer); - throw new IllegalStateException(this+" Extra data after oshut: "+chars); + throw new IllegalStateException(this+" data when CLOSED: "+chars); } BufferUtil.clear(buffer); } @@ -955,7 +955,7 @@ public class HttpParser // Handle HEAD response if (_responseStatus>0 && _headResponse) { - _state=State.END; + setState(State.END); if (_handler.messageComplete(_contentLength)) return true; } @@ -987,7 +987,7 @@ public class HttpParser long remaining=_contentLength - _contentPosition; if (remaining == 0) { - _state=State.END; + setState(State.END); if (_handler.messageComplete(_contentPosition)) return true; } @@ -1011,7 +1011,7 @@ public class HttpParser if(_contentPosition == _contentLength) { - _state=State.END; + setState(State.END); if (_handler.messageComplete(_contentPosition)) return true; } @@ -1030,7 +1030,7 @@ public class HttpParser { _chunkLength=0; _chunkPosition=0; - _state=State.CHUNK_SIZE; + setState(State.CHUNK_SIZE); } break; } @@ -1046,15 +1046,15 @@ public class HttpParser { if (_eol==HttpTokens.CARRIAGE_RETURN && buffer.hasRemaining() && buffer.get(buffer.position())==HttpTokens.LINE_FEED) _eol=buffer.get(); - _state=State.END; + setState(State.END); if (_handler.messageComplete(_contentPosition)) return true; } else - _state=State.CHUNK; + setState(State.CHUNK); } else if (ch <= HttpTokens.SPACE || ch == HttpTokens.SEMI_COLON) - _state=State.CHUNK_PARAMS; + setState(State.CHUNK_PARAMS); else if (ch >= '0' && ch <= '9') _chunkLength=_chunkLength * 16 + (ch - '0'); else if (ch >= 'a' && ch <= 'f') @@ -1076,12 +1076,12 @@ public class HttpParser { if (_eol==HttpTokens.CARRIAGE_RETURN && buffer.hasRemaining() && buffer.get(buffer.position())==HttpTokens.LINE_FEED) _eol=buffer.get(); - _state=State.END; + setState(State.END); if (_handler.messageComplete(_contentPosition)) return true; } else - _state=State.CHUNK; + setState(State.CHUNK); } break; } @@ -1091,7 +1091,7 @@ public class HttpParser int remaining=_chunkLength - _chunkPosition; if (remaining == 0) { - _state=State.CHUNKED_CONTENT; + setState(State.CHUNKED_CONTENT); } else { @@ -1136,7 +1136,7 @@ public class HttpParser private void badMessage(ByteBuffer buffer, int status, String reason) { BufferUtil.clear(buffer); - _state=State.CLOSED; + setState(State.CLOSED); _handler.badMessage(status, reason); } @@ -1151,12 +1151,15 @@ public class HttpParser break; case EOF_CONTENT: - _state=State.END; + setState(State.END); _handler.messageComplete(_contentPosition); break; + case CLOSED: + break; + default: - _state=State.END; + setState(State.END); if (!_headResponse) _handler.earlyEOF(); _handler.messageComplete(_contentPosition); @@ -1177,7 +1180,7 @@ public class HttpParser default: LOG.warn("Closing {}",this); } - _state=State.CLOSED; + setState(State.CLOSED); _endOfContent=EndOfContent.UNKNOWN_CONTENT; _contentPosition=0; _responseStatus=0; @@ -1189,7 +1192,7 @@ public class HttpParser public void reset() { // reset state - _state=State.START; + setState(State.START); _endOfContent=EndOfContent.UNKNOWN_CONTENT; _contentPosition=0; _responseStatus=0; @@ -1199,10 +1202,11 @@ public class HttpParser } /* ------------------------------------------------------------------------------- */ - public void setState(State state) + private void setState(State state) { - this._state=state; - _endOfContent=EndOfContent.UNKNOWN_CONTENT; + if (_state==State.CLOSED && state==State.END) + new Throwable().printStackTrace(); + _state=state; } /* ------------------------------------------------------------------------------- */ diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java index 04a1c9cf891..9506ca90f83 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java @@ -21,8 +21,6 @@ package org.eclipse.jetty.io; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; @@ -30,6 +28,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; public abstract class AbstractEndPoint implements EndPoint { @@ -38,8 +37,8 @@ public abstract class AbstractEndPoint implements EndPoint private final InetSocketAddress _local; private final InetSocketAddress _remote; - private final ScheduledExecutorService _scheduler; - private final AtomicReference> _timeout = new AtomicReference<>(); + private final Scheduler _scheduler; + private final AtomicReference _timeout = new AtomicReference<>(); private final Runnable _idleTask = new Runnable() { @Override @@ -73,7 +72,7 @@ public abstract class AbstractEndPoint implements EndPoint } }; - protected AbstractEndPoint(ScheduledExecutorService scheduler,InetSocketAddress local,InetSocketAddress remote) + protected AbstractEndPoint(Scheduler scheduler,InetSocketAddress local,InetSocketAddress remote) { _local=local; _remote=remote; @@ -176,12 +175,12 @@ public abstract class AbstractEndPoint implements EndPoint protected void scheduleIdleTimeout(long delay) { - Future newTimeout = null; + Scheduler.Task newTimeout = null; if (isOpen() && delay > 0 && _scheduler!=null) newTimeout = _scheduler.schedule(_idleTask, delay, TimeUnit.MILLISECONDS); - Future oldTimeout = _timeout.getAndSet(newTimeout); + Scheduler.Task oldTimeout = _timeout.getAndSet(newTimeout); if (oldTimeout != null) - oldTimeout.cancel(false); + oldTimeout.cancel(); } protected long checkIdleTimeout() diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java index 32b24dbb6b9..1946ba3f22c 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java @@ -96,20 +96,35 @@ public class ArrayByteBufferPool implements ByteBufferPool { if (size<=_min) return null; - int b=size/_inc; + int b=(size-1)/_inc; if (b>=_direct.length) return null; - return direct?_direct[b]:_indirect[b]; + Bucket bucket = direct?_direct[b]:_indirect[b]; + + return bucket; } - private static class Bucket + public static class Bucket { - final int _size; - final Queue _queue= new ConcurrentLinkedQueue<>(); + public final int _size; + public final Queue _queue= new ConcurrentLinkedQueue<>(); Bucket(int size) { _size=size; } + + @Override + public String toString() + { + return String.format("Bucket@%x{%d,%d}",hashCode(),_size,_queue.size()); + } + } + + + // Package local for testing + Bucket[] bucketsFor(boolean direct) + { + return direct ? _direct : _indirect; } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java index e6cace7793a..e29895c93f0 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java @@ -23,12 +23,12 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.charset.Charset; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; /* ------------------------------------------------------------ */ @@ -76,25 +76,25 @@ public class ByteArrayEndPoint extends AbstractEndPoint } /* ------------------------------------------------------------ */ - public ByteArrayEndPoint(ScheduledExecutorService timer, long idleTimeoutMs) + public ByteArrayEndPoint(Scheduler scheduler, long idleTimeoutMs) { - this(timer,idleTimeoutMs,null,null); + this(scheduler,idleTimeoutMs,null,null); } /* ------------------------------------------------------------ */ - public ByteArrayEndPoint(ScheduledExecutorService timer, long idleTimeoutMs, byte[] input, int outputSize) + public ByteArrayEndPoint(Scheduler timer, long idleTimeoutMs, byte[] input, int outputSize) { this(timer,idleTimeoutMs,input!=null?BufferUtil.toBuffer(input):null,BufferUtil.allocate(outputSize)); } /* ------------------------------------------------------------ */ - public ByteArrayEndPoint(ScheduledExecutorService timer, long idleTimeoutMs, String input, int outputSize) + public ByteArrayEndPoint(Scheduler timer, long idleTimeoutMs, String input, int outputSize) { this(timer,idleTimeoutMs,input!=null?BufferUtil.toBuffer(input):null,BufferUtil.allocate(outputSize)); } /* ------------------------------------------------------------ */ - public ByteArrayEndPoint(ScheduledExecutorService timer, long idleTimeoutMs, ByteBuffer input, ByteBuffer output) + public ByteArrayEndPoint(Scheduler timer, long idleTimeoutMs, ByteBuffer input, ByteBuffer output) { super(timer,NOIP,NOIP); _in=input==null?BufferUtil.EMPTY_BUFFER:input; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java index 52fa2eb428d..4f3563b6569 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ChannelEndPoint.java @@ -28,11 +28,11 @@ import java.nio.channels.ByteChannel; import java.nio.channels.ClosedChannelException; import java.nio.channels.GatheringByteChannel; import java.nio.channels.SocketChannel; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; /** * Channel End Point. @@ -47,7 +47,7 @@ public class ChannelEndPoint extends AbstractEndPoint private volatile boolean _ishut; private volatile boolean _oshut; - public ChannelEndPoint(ScheduledExecutorService scheduler,SocketChannel channel) + public ChannelEndPoint(Scheduler scheduler,SocketChannel channel) throws IOException { super(scheduler, (InetSocketAddress)channel.socket().getLocalSocketAddress(), @@ -186,7 +186,7 @@ public class ChannelEndPoint extends AbstractEndPoint if (flushed>0) { notIdle(); - + // clear empty buffers to prevent position creeping up the buffer for (ByteBuffer b : buffers) if (BufferUtil.isEmpty(b)) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java index 38ea8d7efeb..3451a077c58 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSelectChannelEndPoint.java @@ -23,10 +23,10 @@ import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.util.List; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; public class NetworkTrafficSelectChannelEndPoint extends SelectChannelEndPoint { @@ -34,7 +34,7 @@ public class NetworkTrafficSelectChannelEndPoint extends SelectChannelEndPoint private final List listeners; - public NetworkTrafficSelectChannelEndPoint(SocketChannel channel, SelectorManager.ManagedSelector selectSet, SelectionKey key, ScheduledExecutorService scheduler, long idleTimeout, List listeners) throws IOException + public NetworkTrafficSelectChannelEndPoint(SocketChannel channel, SelectorManager.ManagedSelector selectSet, SelectionKey key, Scheduler scheduler, long idleTimeout, List listeners) throws IOException { super(channel, selectSet, key, scheduler, idleTimeout); this.listeners = listeners; diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java index 8d944207362..1b5c3171f35 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectChannelEndPoint.java @@ -18,15 +18,16 @@ package org.eclipse.jetty.io; +import java.io.IOException; import java.nio.channels.CancelledKeyException; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jetty.io.SelectorManager.ManagedSelector; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; /** * An ChannelEndpoint that can be scheduled by {@link SelectorManager}. @@ -74,7 +75,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements SelectorMa */ private volatile int _interestOps; - public SelectChannelEndPoint(SocketChannel channel, ManagedSelector selector, SelectionKey key, ScheduledExecutorService scheduler, long idleTimeout) + public SelectChannelEndPoint(SocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler, long idleTimeout) throws IOException { super(scheduler,channel); _selector = selector; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java new file mode 100644 index 00000000000..f8de3f87dc4 --- /dev/null +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java @@ -0,0 +1,147 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.io; + +import java.nio.ByteBuffer; + +import org.hamcrest.Matchers; +import org.junit.Test; + +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class ArrayByteBufferPoolTest +{ + @Test + public void testMinimumRelease() throws Exception + { + ArrayByteBufferPool bufferPool = new ArrayByteBufferPool(10,100,1000); + ArrayByteBufferPool.Bucket[] buckets = bufferPool.bucketsFor(true); + + for (int size=1;size<=9;size++) + { + ByteBuffer buffer = bufferPool.acquire(size, true); + + assertTrue(buffer.isDirect()); + assertEquals(size,buffer.capacity()); + for (ArrayByteBufferPool.Bucket bucket : buckets) + assertTrue(bucket._queue.isEmpty()); + + bufferPool.release(buffer); + + for (ArrayByteBufferPool.Bucket bucket : buckets) + assertTrue(bucket._queue.isEmpty()); + } + } + + @Test + public void testMaxRelease() throws Exception + { + ArrayByteBufferPool bufferPool = new ArrayByteBufferPool(10,100,1000); + ArrayByteBufferPool.Bucket[] buckets = bufferPool.bucketsFor(true); + + for (int size=999;size<=1001;size++) + { + bufferPool.clear(); + ByteBuffer buffer = bufferPool.acquire(size, true); + + assertTrue(buffer.isDirect()); + assertThat(buffer.capacity(),greaterThanOrEqualTo(size)); + for (ArrayByteBufferPool.Bucket bucket : buckets) + assertTrue(bucket._queue.isEmpty()); + + bufferPool.release(buffer); + + int pooled=0; + for (ArrayByteBufferPool.Bucket bucket : buckets) + { + pooled+=bucket._queue.size(); + } + assertEquals(size<=1000,1==pooled); + } + } + + @Test + public void testAcquireRelease() throws Exception + { + ArrayByteBufferPool bufferPool = new ArrayByteBufferPool(10,100,1000); + ArrayByteBufferPool.Bucket[] buckets = bufferPool.bucketsFor(true); + + for (int size=390;size<=510;size++) + { + bufferPool.clear(); + ByteBuffer buffer = bufferPool.acquire(size, true); + + assertTrue(buffer.isDirect()); + assertThat(buffer.capacity(), greaterThanOrEqualTo(size)); + for (ArrayByteBufferPool.Bucket bucket : buckets) + assertTrue(bucket._queue.isEmpty()); + + bufferPool.release(buffer); + + int pooled=0; + for (ArrayByteBufferPool.Bucket bucket : buckets) + { + if (!bucket._queue.isEmpty()) + { + pooled+=bucket._queue.size(); + assertThat(bucket._size,greaterThanOrEqualTo(size)); + assertThat(bucket._size,Matchers.lessThan(size+100)); + } + } + assertEquals(1,pooled); + } + } + + @Test + public void testAcquireReleaseAcquire() throws Exception + { + ArrayByteBufferPool bufferPool = new ArrayByteBufferPool(10,100,1000); + ArrayByteBufferPool.Bucket[] buckets = bufferPool.bucketsFor(true); + + for (int size=390;size<=510;size++) + { + bufferPool.clear(); + ByteBuffer buffer1 = bufferPool.acquire(size, true); + bufferPool.release(buffer1); + ByteBuffer buffer2 = bufferPool.acquire(size, true); + bufferPool.release(buffer2); + ByteBuffer buffer3 = bufferPool.acquire(size, false); + bufferPool.release(buffer3); + + int pooled=0; + for (ArrayByteBufferPool.Bucket bucket : buckets) + { + if (!bucket._queue.isEmpty()) + { + pooled+=bucket._queue.size(); + assertThat(bucket._size,greaterThanOrEqualTo(size)); + assertThat(bucket._size,Matchers.lessThan(size+100)); + } + } + assertEquals(1,pooled); + + assertTrue(buffer1==buffer2); + assertTrue(buffer1!=buffer3); + } + } + +} diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java index 30243eee426..b772b1df92a 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java @@ -21,14 +21,14 @@ package org.eclipse.jetty.io; import java.io.IOException; import java.nio.ByteBuffer; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -46,18 +46,19 @@ import static org.junit.Assert.fail; @RunWith(AdvancedRunner.class) public class ByteArrayEndPointTest { - private ScheduledExecutorService _scheduler; + private Scheduler _scheduler; @Before - public void before() + public void before() throws Exception { - _scheduler = Executors.newSingleThreadScheduledExecutor(); + _scheduler = new TimerScheduler(); + _scheduler.start(); } @After - public void after() + public void after() throws Exception { - _scheduler.shutdownNow(); + _scheduler.stop(); } @Test diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java index ba4c2e88782..3667fe75ed3 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java @@ -28,8 +28,6 @@ import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -38,6 +36,8 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.junit.After; import org.junit.Assert; import org.junit.Test; @@ -45,7 +45,7 @@ import org.junit.Test; public class SelectChannelEndPointInterestsTest { private QueuedThreadPool threadPool; - private ScheduledExecutorService scheduler; + private Scheduler scheduler; private ServerSocketChannel connector; private SelectorManager selectorManager; @@ -54,7 +54,8 @@ public class SelectChannelEndPointInterestsTest threadPool = new QueuedThreadPool(); threadPool.start(); - scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler = new TimerScheduler(); + scheduler.start(); connector = ServerSocketChannel.open(); connector.bind(new InetSocketAddress("localhost", 0)); @@ -107,12 +108,12 @@ public class SelectChannelEndPointInterestsTest @After public void destroy() throws Exception { + if (scheduler!=null) + scheduler.stop(); if (selectorManager != null) selectorManager.stop(); if (connector != null) connector.close(); - if (scheduler != null) - scheduler.shutdownNow(); if (threadPool != null) threadPool.stop(); } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java index 9e2c39f1803..07783e64f24 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java @@ -31,14 +31,14 @@ import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -56,7 +56,7 @@ public class SelectChannelEndPointTest protected volatile EndPoint _lastEndPoint; protected ServerSocketChannel _connector; protected QueuedThreadPool _threadPool = new QueuedThreadPool(); - protected ScheduledExecutorService _scheduler = Executors.newSingleThreadScheduledExecutor(); + protected Scheduler _scheduler = new TimerScheduler(); protected SelectorManager _manager = new SelectorManager() { @Override @@ -93,6 +93,7 @@ public class SelectChannelEndPointTest _lastEndPointLatch = new CountDownLatch(1); _connector = ServerSocketChannel.open(); _connector.socket().bind(null); + _scheduler.start(); _threadPool.start(); _manager.start(); } @@ -100,6 +101,7 @@ public class SelectChannelEndPointTest @After public void stopManager() throws Exception { + _scheduler.stop(); _manager.stop(); _threadPool.stop(); _connector.close(); diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java index 5d75622adfb..158e685e0d6 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java @@ -28,8 +28,6 @@ import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSocket; @@ -42,6 +40,8 @@ import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -58,7 +58,7 @@ public class SslConnectionTest private volatile FutureCallback _writeCallback; protected ServerSocketChannel _connector; protected QueuedThreadPool _threadPool = new QueuedThreadPool(); - protected ScheduledExecutorService _scheduler = Executors.newSingleThreadScheduledExecutor(); + protected Scheduler _scheduler = new TimerScheduler(); protected SelectorManager _manager = new SelectorManager() { @Override @@ -112,6 +112,7 @@ public class SslConnectionTest _connector = ServerSocketChannel.open(); _connector.socket().bind(null); _threadPool.start(); + _scheduler.start(); _manager.start(); } @@ -121,6 +122,7 @@ public class SslConnectionTest if (_lastEndp.isOpen()) _lastEndp.close(); _manager.stop(); + _scheduler.stop(); _threadPool.stop(); _connector.close(); } diff --git a/jetty-io/src/test/resources/jetty-logging.properties b/jetty-io/src/test/resources/jetty-logging.properties index 55f088b8656..cce2bbacbd3 100644 --- a/jetty-io/src/test/resources/jetty-logging.properties +++ b/jetty-io/src/test/resources/jetty-logging.properties @@ -1,2 +1,2 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -org.eclipse.jetty.io.LEVEL=DEBUG +org.eclipse.jetty.io.LEVEL=INFO diff --git a/jetty-jmx/src/main/config/etc/jetty-jmx.xml b/jetty-jmx/src/main/config/etc/jetty-jmx.xml index 4db0dbb473a..3b3e75bb99b 100644 --- a/jetty-jmx/src/main/config/etc/jetty-jmx.xml +++ b/jetty-jmx/src/main/config/etc/jetty-jmx.xml @@ -7,7 +7,7 @@ - + @@ -21,7 +21,7 @@ --> - + @@ -35,16 +35,8 @@ - - - - - - - - - - true + + diff --git a/jetty-jmx/src/main/config/start.d/000-jetty-jmx.ini b/jetty-jmx/src/main/config/start.d/000-jetty-jmx.ini new file mode 100644 index 00000000000..d13fecfff23 --- /dev/null +++ b/jetty-jmx/src/main/config/start.d/000-jetty-jmx.ini @@ -0,0 +1,2 @@ +OPTIONS=jmx +etc/jetty-jmx.xml diff --git a/jetty-overlay-deployer/src/test/resources/home/overlays/templates/myfoo=foo/WEB-INF/jetty-web.xml b/jetty-overlay-deployer/src/test/resources/home/overlays/templates/myfoo=foo/WEB-INF/jetty-web.xml index 33526645e3c..26eee4b4bff 100644 --- a/jetty-overlay-deployer/src/test/resources/home/overlays/templates/myfoo=foo/WEB-INF/jetty-web.xml +++ b/jetty-overlay-deployer/src/test/resources/home/overlays/templates/myfoo=foo/WEB-INF/jetty-web.xml @@ -2,5 +2,7 @@ - Executing jetty-web.xml for - \ No newline at end of file + + Executing jetty-web.xml for + + diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/impl/PluginManagerImpl.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/DefaultPluginManager.java similarity index 70% rename from jetty-plugins/src/main/java/org/eclipse/jetty/plugins/impl/PluginManagerImpl.java rename to jetty-plugins/src/main/java/org/eclipse/jetty/plugins/DefaultPluginManager.java index 41c33411026..9203a6f0f49 100644 --- a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/impl/PluginManagerImpl.java +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/DefaultPluginManager.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.plugins.impl; +package org.eclipse.jetty.plugins; import java.io.File; import java.io.FileOutputStream; @@ -25,27 +25,26 @@ import java.io.InputStream; import java.util.Arrays; import java.util.Enumeration; import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; -import org.eclipse.jetty.plugins.MavenService; -import org.eclipse.jetty.plugins.PluginManager; import org.eclipse.jetty.plugins.model.Plugin; -public class PluginManagerImpl implements PluginManager +public class DefaultPluginManager implements PluginManager { private String _jettyHome; private MavenService _mavenService; private static List excludes = Arrays.asList("META-INF"); - public PluginManagerImpl(MavenService mavenService, String jettyHome) + public DefaultPluginManager(MavenService mavenService, String jettyHome) { this._mavenService = mavenService; this._jettyHome = jettyHome; } - public List listAvailablePlugins() + public Set listAvailablePlugins() { return _mavenService.listAvailablePlugins(); } @@ -61,7 +60,7 @@ public class PluginManagerImpl implements PluginManager { try { - JarFile pluginJar = new JarFile(plugin.getPluginJar()); + ZipFile pluginJar = new ZipFile(plugin.getPluginJar()); extractJar(pluginJar); } catch (IOException e) @@ -70,32 +69,33 @@ public class PluginManagerImpl implements PluginManager } } - private void extractJar(JarFile file) + private void extractJar(ZipFile file) { - Enumeration entries = file.entries(); + Enumeration entries = file.entries(); while (entries.hasMoreElements()) { extractFileFromJar(file, entries.nextElement()); } } - private void extractFileFromJar(JarFile jarFile, JarEntry jarEntry) + private void extractFileFromJar(ZipFile zipFile, ZipEntry zipEntry) { for (String exclude : excludes) - if (jarEntry.getName().startsWith(exclude)) + if (zipEntry.getName().startsWith(exclude)) return; - System.out.println("Extracting: " + jarEntry.getName()); - File f = new File(_jettyHome + File.separator + jarEntry.getName()); - if (jarEntry.isDirectory()) + System.out.println("Extracting: " + zipEntry.getName()); + File f = new File(_jettyHome + File.separator + zipEntry.getName()); + if (zipEntry.isDirectory()) { // if its a directory, create it - f.mkdir(); // TODO: check the result: what if the directory cannot be created ? + if(!f.mkdir()) // TODO: what if the directory cannot be created? + System.out.println("Can't create directory: " + f); return; } - try (InputStream is = jarFile.getInputStream(jarEntry); + try (InputStream is = zipFile.getInputStream(zipEntry); FileOutputStream fos = new FileOutputStream(f)) { while (is.available() > 0) @@ -105,7 +105,7 @@ public class PluginManagerImpl implements PluginManager } catch (IOException e) { - throw new IllegalStateException("Could not extract plugin jar", e); + throw new IllegalStateException("Could not extract plugin zip", e); } } } diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/HttpMavenService.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/HttpMavenService.java new file mode 100644 index 00000000000..ad080734cfb --- /dev/null +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/HttpMavenService.java @@ -0,0 +1,256 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.plugins; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.plugins.model.Plugin; +import org.eclipse.jetty.plugins.util.MavenUtils; +import org.eclipse.jetty.plugins.util.RepositoryParser; +import org.eclipse.jetty.plugins.util.StreamUtils; + +public class HttpMavenService implements MavenService +{ + private static final String REPOSITORY_URL = "http://repo2.maven.org/maven2/"; + private static final String[] GROUP_IDS = new String[]{ "org/eclipse/jetty", "org/mortbay/jetty" }; + private static final String VERSION = "9.0.0-SNAPSHOT"; // TODO: should be automatically set + private boolean _searchRemoteRepository = true; + private boolean _searchLocalRepository = false; + private String _localRepository = MavenUtils.getLocalRepositoryLocation(); + private String _repositoryUrl = REPOSITORY_URL; + private String[] _groupIds = GROUP_IDS; + private String _version = VERSION; + + public Set listAvailablePlugins() + { + System.out.println("Using local repo: " + _searchLocalRepository + " remote repo: " + _searchRemoteRepository); + Set availablePlugins = new HashSet<>(); + if (_searchRemoteRepository) + availablePlugins.addAll(getListOfRemotePlugins()); + + if (_searchLocalRepository) + availablePlugins.addAll(getListOfLocalPlugins()); + + return availablePlugins; + } + + private Set getListOfLocalPlugins() + { + Set availablePlugins = new HashSet<>(); + File localMavenRepository = new File(_localRepository); + if (!localMavenRepository.exists()) + { + System.out.println("Can't find local repo: " + localMavenRepository); + return availablePlugins; + } + + System.out.println("Using local repository: " + localMavenRepository); + + for (String groupId : _groupIds) + { + File file = new File(_localRepository + groupId); + if (!file.exists()) + break; + + String[] localMavenModuleList = file.list(); + + System.out.println("Trying the following modules: " + Arrays.toString(localMavenModuleList)); + for (String potentialPlugin : localMavenModuleList) + { + File pluginFile = new File(_localRepository + getPluginPath(groupId,potentialPlugin)); + if (pluginFile.exists()) + availablePlugins.add(potentialPlugin); + } + } + + return availablePlugins; + } + + private Set getListOfRemotePlugins() + { + Set availablePlugins = new HashSet<>(); + + String moduleListing = fetchDirectoryListingOfJettyModules(); + List modules = RepositoryParser + .parseLinksInDirectoryListing(moduleListing); + + for (String module : modules) + { + String listing = fetchModuleDirectoryListing(module); + if (RepositoryParser.isModuleAPlugin(listing)) + { + availablePlugins.add(module); + } + } + return availablePlugins; + } + + private String fetchDirectoryListingOfJettyModules() + { + try + { + StringBuilder directoryListing = new StringBuilder(); + for (String groupId : _groupIds) + { + URL url = new URL(_repositoryUrl + groupId); + URLConnection connection = url.openConnection(); + InputStream inputStream = connection.getInputStream(); + directoryListing.append(StreamUtils.inputStreamToString(inputStream)); + } + return directoryListing.toString(); + } + catch (IOException e) + { + throw new IllegalStateException(e); + } + } + + private String fetchModuleDirectoryListing(String module) + { + for (String groupId : _groupIds) + { + try + { + URL configJar = new URL(_repositoryUrl + getModulePath(groupId, module)); + URLConnection connection = configJar.openConnection(); + InputStream inputStream = connection.getInputStream(); + return StreamUtils.inputStreamToString(inputStream); + } + catch (MalformedURLException e) + { + throw new IllegalStateException(e); + } + catch (IOException e) + { + // Honestly, I'm not a friend of ignoring exceptions as it might + // hide something important. In this case however it "usually" + // just means: THIS IS NOT A PLUGIN! However it still might hide + // things. If that'll be the case, I hope I'm not the one who + // has to debug my own code. ;) + System.out.println(e); //TODO: + } + } + return "not a plugin"; + } + + public Plugin getPlugin(String pluginName) + { + File pluginJar = getPluginFile(pluginName); + return new Plugin(pluginName, pluginJar); + } + + private String getPluginPath(String groupId, String pluginName) + { + return getModulePath(groupId, pluginName) + pluginName + "-" + _version + "-plugin.zip"; + } + + private String getModulePath(String groupId, String pluginName) + { + return groupId + "/" + pluginName + "/" + _version + + "/"; + } + + /** + * Tries to find the plugin in the local repo first and then tries the remote repositories in the order they're + * stored in _repositoryUrls + * + * @param pluginName the name of the plugin to get the plugin file for + * @return the plugin file + */ + private File getPluginFile(String pluginName) + { + for (String groupId : _groupIds) + { + File pluginFile = new File(MavenUtils.getLocalRepositoryLocation() + getPluginPath(groupId, pluginName)); + if (pluginFile.exists()) + return pluginFile; + + String urlString = _repositoryUrl + getPluginPath(groupId, pluginName); + String fileName = urlString.substring(urlString.lastIndexOf("/") + 1); + try + { + return getPluginFileFromRemoteLocation(urlString, fileName); + } + catch (IOException e) + { + System.out.println("Couldn't find plugin: " + pluginName + " at repo: " + _repositoryUrl + ". " + + "Probably trying other repo. Reason: " + e.getMessage()); + } + } + throw new IllegalStateException("Plugin: " + pluginName + " not found at any configured repo."); + } + + private File getPluginFileFromRemoteLocation(String urlString, String fileName) throws IOException + { + URL url = new URL(urlString); + URLConnection connection = url.openConnection(); + InputStream inputStream = connection.getInputStream(); + File tempFile = new File(System.getProperty("java.io.tmpdir"), + fileName); + OutputStream out = new FileOutputStream(tempFile); + byte buf[] = new byte[1024]; + int len; + while ((len = inputStream.read(buf)) > 0) + out.write(buf, 0, len); + out.close(); + inputStream.close(); + return tempFile; + } + + public void setGroupId(String groupId) + { + this._groupIds = new String[] { groupId.replace(".", "/") }; + } + + public void setLocalRepository(String localRepository) + { + this._localRepository = localRepository; + } + + public void setRepositoryUrl(String repositoryUrl) + { + this._repositoryUrl = repositoryUrl; + } + + public void setVersion(String version) + { + this._version = version; + } + + public void setSearchRemoteRepository(boolean searchRemoteRepository) + { + this._searchRemoteRepository = searchRemoteRepository; + } + + public void setSearchLocalRepository(boolean searchLocalRepository) + { + this._searchLocalRepository = searchLocalRepository; + } +} diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/Main.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/Main.java index 6278d313cbc..dbe5c359461 100644 --- a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/Main.java +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/Main.java @@ -18,17 +18,14 @@ package org.eclipse.jetty.plugins; -import java.util.List; import java.util.Map; - -import org.eclipse.jetty.plugins.impl.HttpMavenServiceImpl; -import org.eclipse.jetty.plugins.impl.PluginManagerImpl; +import java.util.Set; public class Main { private static final String JETTY_HOME = "JETTY_HOME"; - private MavenService _mavenService = new HttpMavenServiceImpl(); + private MavenService _mavenService = new HttpMavenService(); private PluginManager _pluginManager; private String _jettyHome; private String _installPlugin; @@ -36,6 +33,8 @@ public class Main private String _repositoryUrl; private String _groupId; private String _version; + private boolean _searchRemoteRepository = true; + private boolean _searchLocalRepository = false; public static void main(String[] args) { @@ -49,41 +48,32 @@ public class Main parseCommandline(args); configureMavenService(); - _pluginManager = new PluginManagerImpl(_mavenService, _jettyHome); + _pluginManager = new DefaultPluginManager(_mavenService, _jettyHome); if (_listPlugins) - { listPlugins(); - } else if (_installPlugin != null) - { installPlugin(); - } } private void configureMavenService() { if (_repositoryUrl != null) - { _mavenService.setRepositoryUrl(_repositoryUrl); - } if (_groupId != null) - { _mavenService.setGroupId(_groupId); - } if (_version != null) - { _mavenService.setVersion(_version); - } + + _mavenService.setSearchLocalRepository(_searchLocalRepository); + _mavenService.setSearchRemoteRepository(_searchRemoteRepository); } private void listPlugins() { - List availablePlugins = _pluginManager.listAvailablePlugins(); + Set availablePlugins = _pluginManager.listAvailablePlugins(); for (String pluginName : availablePlugins) - { System.out.println(pluginName); - } } private void installPlugin() @@ -97,9 +87,7 @@ public class Main { Map env = System.getenv(); if (env.containsKey(JETTY_HOME)) - { _jettyHome = env.get(JETTY_HOME); - } } private void parseCommandline(String[] args) @@ -110,40 +98,36 @@ public class Main i++; if (arg.startsWith("--jettyHome=")) - { _jettyHome = arg.substring(12); - } if (arg.startsWith("--repositoryUrl=")) - { _repositoryUrl = arg.substring(16); - } if (arg.startsWith("--groupId=")) - { _groupId = arg.substring(10); - } if (arg.startsWith("--version=")) - { _version = arg.substring(10); - } + if (arg.startsWith("--useLocalRepo=")) + _searchLocalRepository = Boolean.valueOf(arg.substring(15)); + if (arg.startsWith("--useRemoteRepo=")) + _searchRemoteRepository = Boolean.valueOf(arg.substring(15)); if (arg.startsWith("install")) - { _installPlugin = args[i]; - } if ("list".equals(arg)) - { _listPlugins = true; - } } - // TODO: Usage instead of throwing exceptions if (_jettyHome == null && _installPlugin != null) - throw new IllegalArgumentException( - "No --jettyHome commandline option specified and no \"JETTY_HOME\" environment variable found!"); + printUsage("No --jettyHome commandline option specified and no \"JETTY_HOME\" environment variable found!"); if (_installPlugin == null && !_listPlugins) - throw new IllegalArgumentException( - "Neither install nor list commandline option specified. Nothing to do for me!"); + printUsage("Neither install nor list commandline option specified. Nothing to do for me!"); if (_installPlugin != null && _listPlugins) - throw new IllegalArgumentException( - "Please specify either install or list commandline options, but not both at the same time!"); + printUsage("Please specify either install or list commandline options, " + + "but not both at the same time!"); + } + + private void printUsage(String errorMessage) + { + System.out.println(errorMessage); + System.exit(1); + //TODO: print usage } } diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/MavenService.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/MavenService.java index 7505fa8bbba..08b55a92305 100644 --- a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/MavenService.java +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/MavenService.java @@ -18,13 +18,13 @@ package org.eclipse.jetty.plugins; -import java.util.List; +import java.util.Set; import org.eclipse.jetty.plugins.model.Plugin; public interface MavenService { - public List listAvailablePlugins(); + public Set listAvailablePlugins(); public Plugin getPlugin(String pluginName); @@ -33,4 +33,8 @@ public interface MavenService public void setRepositoryUrl(String repositoryUrl); public void setVersion(String version); + + public void setSearchLocalRepository(boolean searchLocalRepository); + + public void setSearchRemoteRepository(boolean searchRemoteRepository); } diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/PluginManager.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/PluginManager.java index 1e2266a4535..36c721c7162 100644 --- a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/PluginManager.java +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/PluginManager.java @@ -18,11 +18,11 @@ package org.eclipse.jetty.plugins; -import java.util.List; +import java.util.Set; public interface PluginManager { - public List listAvailablePlugins(); + public Set listAvailablePlugins(); public void installPlugin(String pluginName); } diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/impl/HttpMavenServiceImpl.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/impl/HttpMavenServiceImpl.java deleted file mode 100644 index f102537d631..00000000000 --- a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/impl/HttpMavenServiceImpl.java +++ /dev/null @@ -1,161 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2012 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.plugins.impl; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jetty.plugins.MavenService; -import org.eclipse.jetty.plugins.model.Plugin; -import org.eclipse.jetty.plugins.util.RepositoryParser; -import org.eclipse.jetty.plugins.util.StreamUtils; - -public class HttpMavenServiceImpl implements MavenService -{ - private static final String REPOSITORY_URL = "http://repo2.maven.org/maven2/"; - private static final String GROUP_ID = "org/eclipse/jetty"; - private static final String VERSION = "7.6.0.v20120127"; // TODO: should be automatically set - private String _repositoryUrl = REPOSITORY_URL; - private String _groupId = GROUP_ID; - private String _version = VERSION; - - public List listAvailablePlugins() - { - List availablePlugins = new ArrayList<>(); - - String moduleListing = fetchDirectoryListingOfJettyModules(); - List modules = RepositoryParser - .parseLinksInDirectoryListing(moduleListing); - - for (String module : modules) - { - String listing = fetchModuleDirectoryListing(module); - if (RepositoryParser.isModuleAPlugin(listing)) - { - availablePlugins.add(module); - } - } - - return availablePlugins; - } - - private String fetchDirectoryListingOfJettyModules() - { - try - { - URL url = new URL(_repositoryUrl + _groupId); - URLConnection connection = url.openConnection(); - InputStream inputStream = connection.getInputStream(); - return StreamUtils.inputStreamToString(inputStream); - } - catch (IOException e) - { - throw new IllegalStateException(e); - } - } - - private String fetchModuleDirectoryListing(String module) - { - try - { - URL configJar = new URL(getModuleDirectory(module)); - URLConnection connection = configJar.openConnection(); - InputStream inputStream = connection.getInputStream(); - return StreamUtils.inputStreamToString(inputStream); - } - catch (MalformedURLException e) - { - throw new IllegalStateException(e); - } - catch (IOException e) - { - // Honestly, I'm not a friend of ignoring exceptions as it might - // hide something important. In this case however it "usually" - // just means: THIS IS NOT A PLUGIN! However it still might hide - // things. If that'll be the case, I hope I'm not the one who - // has to debug my own code. ;) - return "not a plugin"; - } - } - - public Plugin getPlugin(String pluginName) - { - File configJar = getFile(getModulePrefix(pluginName) + "-plugin.jar"); - return new Plugin(pluginName, configJar); - } - - private String getModuleDirectory(String pluginName) - { - return _repositoryUrl + _groupId + "/" + pluginName + "/" + _version - + "/"; - } - - private String getModulePrefix(String pluginName) - { - return getModuleDirectory(pluginName) + pluginName + "-" + _version; - } - - private File getFile(String urlString) - { - String fileName = urlString.substring(urlString.lastIndexOf("/") + 1); - try - { - URL url = new URL(urlString); - URLConnection connection = url.openConnection(); - InputStream inputStream = connection.getInputStream(); - File tempFile = new File(System.getProperty("java.io.tmpdir"), - fileName); - OutputStream out = new FileOutputStream(tempFile); - byte buf[] = new byte[1024]; - int len; - while ((len = inputStream.read(buf)) > 0) - out.write(buf, 0, len); - out.close(); - inputStream.close(); - return tempFile; - } - catch (IOException e) - { - throw new IllegalStateException(e); - } - } - - public void setGroupId(String groupId) - { - this._groupId = groupId.replace(".", "/"); - } - - public void setRepositoryUrl(String repositoryUrl) - { - this._repositoryUrl = repositoryUrl; - } - - public void setVersion(String version) - { - this._version = version; - } -} diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/model/Plugin.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/model/Plugin.java index b7840537ab0..4225097fbfb 100644 --- a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/model/Plugin.java +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/model/Plugin.java @@ -25,10 +25,10 @@ public class Plugin private final String name; private final File pluginJar; - public Plugin(String name, File configJar) + public Plugin(String name, File pluginJar) { this.name = name; - this.pluginJar = configJar; + this.pluginJar = pluginJar; } public String getName() diff --git a/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/util/MavenUtils.java b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/util/MavenUtils.java new file mode 100644 index 00000000000..09cc746d448 --- /dev/null +++ b/jetty-plugins/src/main/java/org/eclipse/jetty/plugins/util/MavenUtils.java @@ -0,0 +1,172 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.plugins.util; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +public class MavenUtils +{ + private final static String DEFAULT_REPOSITORY_LOCATION = System.getProperty("user.home") + "/.m2/repository/"; + + /** + * Looks for maven's settings.xml in $M2_HOME/conf/settings.xml + * + * @return a file representing the global settings.xml + */ + static File findGlobalSettingsXml() + { + String m2Home = System.getenv("M2_HOME"); + return new File(m2Home + "/conf/settings.xml"); + } + + /** + * Looks for maven's settings.xml in ${user.home}/.m2/settings.xml + * + * @return a file representing the user's settings.xml + */ + static File findUserSettingsXml() + { + String userHome = System.getProperty("user.home"); + return new File(userHome + "/.m2/settings.xml"); + } + + /** + * Read the local repository location from settings.xml. A setting in the user's settings.xml will override the + * global one. + * + * @return location of the local maven repo + */ + public static String getLocalRepositoryLocation() + { + String repositoryLocation = DEFAULT_REPOSITORY_LOCATION; + try + { + // find the global setting + String tempRepositoryLocation = parseSettingsXml(findGlobalSettingsXml()); + if (tempRepositoryLocation != null) + repositoryLocation = tempRepositoryLocation; + + // override with user settings.xml + tempRepositoryLocation = parseSettingsXml(findUserSettingsXml()); + if (tempRepositoryLocation != null) + repositoryLocation = tempRepositoryLocation; + } + catch (IOException | SAXException e) + { + throw new IllegalStateException(e); + } + return repositoryLocation; + } + + private static String parseSettingsXml(File settingsXml) throws IOException, SAXException + { + if(!settingsXml.exists()) + return null; + + // readability is more important than efficiency here, so we just recreate those objects + XMLReader reader = XMLReaderFactory.createXMLReader(); + SettingsXmlContentHandler settingsXmlContentHandler = new SettingsXmlContentHandler(); + reader.setContentHandler(settingsXmlContentHandler); + + InputSource source = new InputSource(new FileReader(settingsXml)); + reader.parse(source); + return settingsXmlContentHandler.getRepositoryLocation(); + } + + private static class SettingsXmlContentHandler implements ContentHandler + { + private String repositoryLocation; + private String currentValue; + + @Override + public void characters(char[] ch, int start, int length) throws SAXException + { + currentValue = new String(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException + { + if (localName.equals("localRepository")) + { + repositoryLocation = currentValue; + } + } + + public String getRepositoryLocation() + { + return repositoryLocation; + } + + @Override + public void setDocumentLocator(Locator locator) + { + } + + @Override + public void startDocument() throws SAXException + { + } + + @Override + public void endDocument() throws SAXException + { + } + + @Override + public void startPrefixMapping(String prefix, String uri) throws SAXException + { + } + + @Override + public void endPrefixMapping(String prefix) throws SAXException + { + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException + { + } + + @Override + public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException + { + } + + @Override + public void processingInstruction(String target, String data) throws SAXException + { + } + + @Override + public void skippedEntity(String name) throws SAXException + { + } + } +} diff --git a/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/impl/HttpMavenServiceTest.java b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/HttpMavenServiceIntegrationTest.java similarity index 84% rename from jetty-plugins/src/test/java/org/eclipse/jetty/plugins/impl/HttpMavenServiceTest.java rename to jetty-plugins/src/test/java/org/eclipse/jetty/plugins/HttpMavenServiceIntegrationTest.java index 443ed7c9d44..826888cf8ec 100644 --- a/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/impl/HttpMavenServiceTest.java +++ b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/HttpMavenServiceIntegrationTest.java @@ -16,13 +16,12 @@ // ======================================================================== // -package org.eclipse.jetty.plugins.impl; +package org.eclipse.jetty.plugins; import java.io.File; import java.io.IOException; -import java.util.List; +import java.util.Set; -import org.eclipse.jetty.plugins.MavenService; import org.eclipse.jetty.plugins.model.Plugin; import org.junit.Before; import org.junit.Ignore; @@ -35,16 +34,15 @@ import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; /** - * This is currently more an integration test downloading real stuff from real - * maven repositories. Actually it's preferred to have a real unit test or at - * least a local repository server. But since HttpClient.send(exchange) has an + * This is currently more an integration test downloading real stuff from real maven repositories. Actually it's + * preferred to have a real unit test or at least a local repository server. But since HttpClient.send(exchange) has an * api which is really hard to mock, I will leave that exercise for later. *

* However this tests should be disabled for the general build and ci. */ -public class HttpMavenServiceTest +public class HttpMavenServiceIntegrationTest { - private MavenService _mavenService = new HttpMavenServiceImpl(); + private HttpMavenService _mavenService = new HttpMavenService(); private static final String JETTY_JMX_PLUGIN_NAME = "jetty-jmx"; private static final String PRIVATE_NEXUS_REPOSITORY_URL = "http://gravity-design.de:8080/nexus/content/repositories/releases/"; @@ -60,7 +58,7 @@ public class HttpMavenServiceTest @Ignore("requires online repo") public void testListAvailablePlugins() { - List pluginNames = _mavenService.listAvailablePlugins(); + Set pluginNames = _mavenService.listAvailablePlugins(); assertThat(pluginNames.size(), is(2)); } diff --git a/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/HttpMavenServiceTest.java b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/HttpMavenServiceTest.java new file mode 100644 index 00000000000..c6a2a88caa4 --- /dev/null +++ b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/HttpMavenServiceTest.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.plugins; + +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +/** + */ +public class HttpMavenServiceTest +{ + private HttpMavenService _mavenService = new HttpMavenService(); + + private static final String MAVEN_CENTRAL_URL = "http://repo2.maven.org/maven2/"; + + @Before + public void setUp() throws Exception + { + _mavenService.setLocalRepository(this.getClass().getClassLoader().getResource("maven_repo").getFile() + "/"); + _mavenService.setRepositoryUrl(MAVEN_CENTRAL_URL); + _mavenService.setVersion("version"); + _mavenService.setSearchRemoteRepository(false); + _mavenService.setSearchLocalRepository(true); + } + + @Test + public void testListAvailablePlugins() + { + Set pluginNames = _mavenService.listAvailablePlugins(); + assertThat(pluginNames.size(), is(2)); + assertThat("plugin jetty-plugin found", pluginNames.contains("jetty-plugin"), is(true)); + assertThat("plugin jetty-anotherplugin found", pluginNames.contains("jetty-anotherplugin"), is(true)); + } + +} diff --git a/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/impl/PluginManagerTest.java b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/PluginManagerTest.java similarity index 77% rename from jetty-plugins/src/test/java/org/eclipse/jetty/plugins/impl/PluginManagerTest.java rename to jetty-plugins/src/test/java/org/eclipse/jetty/plugins/PluginManagerTest.java index d2f38a05ca3..4e567ff559c 100644 --- a/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/impl/PluginManagerTest.java +++ b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/PluginManagerTest.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.plugins.impl; +package org.eclipse.jetty.plugins; import java.io.File; import java.io.FileInputStream; @@ -24,11 +24,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.nio.channels.FileChannel; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import junit.framework.Assert; -import org.eclipse.jetty.plugins.MavenService; import org.eclipse.jetty.plugins.model.Plugin; import org.junit.Before; import org.junit.Test; @@ -46,8 +45,8 @@ public class PluginManagerTest { @Mock private MavenService _mavenService; - private PluginManagerImpl _pluginManager; - private List availablePlugins = createAvailablePluginsTestData(); + private DefaultPluginManager _Default_pluginManager; + private Set availablePlugins = createAvailablePluginsTestData(); private ClassLoader _classLoader = this.getClass().getClassLoader(); private String _tmpDir; private File _javaTmpDir = new File(System.getProperty("java.io.tmpdir")); @@ -57,14 +56,14 @@ public class PluginManagerTest { URL resource = this.getClass().getResource("/jetty_home"); _tmpDir = resource.getFile(); - _pluginManager = new PluginManagerImpl(_mavenService, _tmpDir); + _Default_pluginManager = new DefaultPluginManager(_mavenService, _tmpDir); } @Test public void testListAvailablePlugins() { when(_mavenService.listAvailablePlugins()).thenReturn(availablePlugins); - List availablePlugins = _pluginManager.listAvailablePlugins(); + Set availablePlugins = _Default_pluginManager.listAvailablePlugins(); assertThat("jetty-jmx not found", availablePlugins.contains("jetty-jmx"), is(true)); assertThat("jetty-jta not found", @@ -74,16 +73,16 @@ public class PluginManagerTest @Test public void testInstallPluginJar() { - String pluginName = "jetty-plugin-with-plugin-jar"; - URL resource = _classLoader.getResource("example-plugin.jar"); + String pluginName = "jetty-plugin-with-plugin-zip"; + URL resource = _classLoader.getResource("example-plugin.zip"); Assert.assertNotNull(resource); - String pluginJar = resource.getFile(); - File pluginJarFile = new File(pluginJar); - Plugin plugin = createTestPlugin(pluginName, pluginJarFile); + String pluginZip = resource.getFile(); + File pluginZipFile = new File(pluginZip); + Plugin plugin = createTestPlugin(pluginName, pluginZipFile); when(_mavenService.getPlugin(pluginName)).thenReturn(plugin); - _pluginManager.installPlugin(pluginName); + _Default_pluginManager.installPlugin(pluginName); File someJar = new File(_tmpDir + File.separator + "lib" + File.separator + "somejar.jar"); assertThat("someJar.jar does not exist", someJar.exists(), is(true)); @@ -97,30 +96,30 @@ public class PluginManagerTest public void testInstallPlugins() throws IOException { String pluginName = "jetty-jmx"; - URL resource = _classLoader.getResource("jetty-jmx-7.6.0.v20120127-plugin.jar"); + URL resource = _classLoader.getResource("jetty-jmx-version-plugin.zip"); Assert.assertNotNull(resource); - String jmxPluginConfigJar = resource.getFile(); - File jmxPluginConfigJarFile = new File(jmxPluginConfigJar); + String jmxPluginZip = resource.getFile(); + File jmxPluginZipFile = new File(jmxPluginZip); // Need to copy it to a temp file since the implementation will move the // file and we need to keep the test files where they are. - File jmxPluginConfigTempCopy = copyToTempFile(jmxPluginConfigJarFile); + File jmxPluginConfigTempCopy = copyToTempFile(jmxPluginZipFile); Plugin plugin = new Plugin(pluginName, jmxPluginConfigTempCopy); when(_mavenService.getPlugin(pluginName)).thenReturn(plugin); - _pluginManager.installPlugin(pluginName); + _Default_pluginManager.installPlugin(pluginName); File metaInf = new File(_tmpDir + File.separator + "META-INF"); File jettyXmlConfigFile = new File(_tmpDir + File.separator + "start.d" + File.separator + "20-jetty-jmx.xml"); File jettyJmxJarFile = new File(_tmpDir + File.separator + "lib" - + File.separator + "jetty-jmx-7.6.0.v20120127.jar"); + + File.separator + "jetty-jmx-version.jar"); assertThat("META-INF should be skipped", metaInf.exists(), not(true)); assertThat("20-jetty-jmx.xml does not exist", jettyXmlConfigFile.exists(), is(true)); - assertThat("jetty-jmx-7.6.0.v20120127.jar does not exist", + assertThat("jetty-jmx-version.jar does not exist", jettyJmxJarFile.exists(), is(true)); } @@ -135,9 +134,9 @@ public class PluginManagerTest return destFile; } - private List createAvailablePluginsTestData() + private Set createAvailablePluginsTestData() { - List availablePlugins = new ArrayList<>(); + Set availablePlugins = new HashSet<>(); availablePlugins.add("jetty-jmx"); availablePlugins.add("jetty-jta"); return availablePlugins; diff --git a/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/util/MavenUtilsTest.java b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/util/MavenUtilsTest.java new file mode 100644 index 00000000000..569bfed23f3 --- /dev/null +++ b/jetty-plugins/src/test/java/org/eclipse/jetty/plugins/util/MavenUtilsTest.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.plugins.util; + +import java.io.File; + +import org.junit.Ignore; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class MavenUtilsTest +{ + @Test + @Ignore("Very environment specific, so disabled in commit. Enable if working on the code.") + public void testFindUserSettingsXml() + { + File settingsXml = MavenUtils.findUserSettingsXml(); + assertThat("settings.xml is found", settingsXml.exists(), is(true)); + } + + @Test + @Ignore("Very environment specific, so disabled in commit. Enable if working on the code.") + public void testGetLocalRepositoryLocation() + { + String repositoryLocation = MavenUtils.getLocalRepositoryLocation(); + assertThat("maven repository exists", new File(repositoryLocation).exists(), is(true)); + } +} diff --git a/jetty-plugins/src/test/resources/example-plugin.jar b/jetty-plugins/src/test/resources/example-plugin.jar deleted file mode 100644 index 31cd1e04d4b..00000000000 Binary files a/jetty-plugins/src/test/resources/example-plugin.jar and /dev/null differ diff --git a/jetty-plugins/src/test/resources/example-plugin.zip b/jetty-plugins/src/test/resources/example-plugin.zip new file mode 100644 index 00000000000..c152b1f515b Binary files /dev/null and b/jetty-plugins/src/test/resources/example-plugin.zip differ diff --git a/jetty-plugins/src/test/resources/jetty-jmx-7.6.0.v20120127-plugin.jar b/jetty-plugins/src/test/resources/jetty-jmx-7.6.0.v20120127-plugin.jar deleted file mode 100644 index ed99c27732a..00000000000 Binary files a/jetty-plugins/src/test/resources/jetty-jmx-7.6.0.v20120127-plugin.jar and /dev/null differ diff --git a/jetty-plugins/src/test/resources/jetty-jmx-version-plugin.zip b/jetty-plugins/src/test/resources/jetty-jmx-version-plugin.zip new file mode 100644 index 00000000000..f680dd04cae Binary files /dev/null and b/jetty-plugins/src/test/resources/jetty-jmx-version-plugin.zip differ diff --git a/jetty-plugins/src/test/resources/maven_repo/org/eclipse/jetty/jetty-anotherplugin/version/jetty-anotherplugin-version-plugin.zip b/jetty-plugins/src/test/resources/maven_repo/org/eclipse/jetty/jetty-anotherplugin/version/jetty-anotherplugin-version-plugin.zip new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jetty-plugins/src/test/resources/maven_repo/org/eclipse/jetty/jetty-plugin/version/jetty-plugin-version-plugin.zip b/jetty-plugins/src/test/resources/maven_repo/org/eclipse/jetty/jetty-plugin/version/jetty-plugin-version-plugin.zip new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jetty-server/src/main/config/etc/jetty-proxy.xml b/jetty-proxy/src/main/config/etc/jetty-proxy.xml similarity index 100% rename from jetty-server/src/main/config/etc/jetty-proxy.xml rename to jetty-proxy/src/main/config/etc/jetty-proxy.xml diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml index afaaa184a07..6d5a7e79409 100644 --- a/jetty-server/src/main/config/etc/jetty.xml +++ b/jetty-server/src/main/config/etc/jetty.xml @@ -1,5 +1,6 @@ - + + @@ -16,32 +17,28 @@ - - - - + + 10 200 false - + + - + 300000 - 2 - false - 8443 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 7de823ebb86..1cdd2c0bd71 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 @@ -24,10 +24,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; -import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -41,6 +38,8 @@ import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; /** *

Partial implementation of {@link Connector}

@@ -55,11 +54,10 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co private final Server _server; private final SslContextFactory _sslContextFactory; private final Executor _executor; - private final ScheduledExecutorService _scheduler; + private final Scheduler _scheduler; private final ByteBufferPool _byteBufferPool; private final Thread[] _acceptors; private volatile CountDownLatch _stopping; - private volatile String _name; private volatile long _idleTimeout = 200000; private volatile ConnectionFactory defaultConnectionFactory; @@ -74,30 +72,23 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co public AbstractConnector( Server server, Executor executor, - ScheduledExecutorService scheduler, + Scheduler scheduler, ByteBufferPool pool, SslContextFactory sslContextFactory, int acceptors) { _server=server; _executor=executor!=null?executor:_server.getThreadPool(); - _scheduler=scheduler!=null?scheduler:Executors.newSingleThreadScheduledExecutor(new ThreadFactory() - { - @Override - public Thread newThread(Runnable r) - { - return new Thread(r, "Scheduler-" + getName()); - } - }); + _scheduler=scheduler!=null?scheduler:new TimerScheduler(); _byteBufferPool = pool!=null?pool:new MappedByteBufferPool(); _sslContextFactory = sslContextFactory; addBean(_server,false); addBean(_executor); if (executor==null) - unmanage(_executor); - addBean(_scheduler,scheduler==null); - addBean(_byteBufferPool,pool==null); + unmanage(_executor); // inherited from server + addBean(_scheduler); + addBean(_byteBufferPool); addBean(_sslContextFactory); addBean(_stats,true); @@ -341,18 +332,6 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co } } - @Override - @ManagedAttribute("name of the connector") - public String getName() - { - return _name; - } - - public void setName(String name) - { - _name = name; - } - protected void connectionOpened(Connection connection) { _stats.connectionOpened(); @@ -373,7 +352,8 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co _stats.connectionClosed(duration, requests, requests); } - public ScheduledExecutorService getScheduler() + @Override + public Scheduler getScheduler() { return _scheduler; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java index c4fc3799cc6..21fafc7a50c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java @@ -21,10 +21,10 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.util.concurrent.Executor; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; /** *

Partial implementation of {@link NetworkConnector}.

@@ -34,7 +34,7 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme private volatile String _host; private volatile int _port = 0; - public AbstractNetworkConnector(Server server, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, SslContextFactory sslContextFactory, int acceptors) + public AbstractNetworkConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, SslContextFactory sslContextFactory, int acceptors) { super(server, executor, scheduler, pool, sslContextFactory, acceptors); } @@ -70,13 +70,7 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme @Override protected void doStart() throws Exception { - if (getName() == null) - setName(getHost() == null ? "0.0.0.0" : getHost() + ":" + getPort()); - open(); - - setName(getName() + "/" + getLocalPort()); - super.doStart(); } @@ -84,12 +78,7 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme protected void doStop() throws Exception { close(); - super.doStop(); - - int i = getName().lastIndexOf("/"); - if (i > 0) - setName(getName().substring(0, i)); } @Override diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java index 99a877c8b45..908abd0db07 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.server; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.annotation.ManagedAttribute; @@ -27,6 +26,7 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.Graceful; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; /** *

A {@link Connector} accept connections and data from remote peers, @@ -36,11 +36,6 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; @ManagedObject("Connector Interface") public interface Connector extends LifeCycle, Graceful { - /** - * @return the name of the connector, defaulting to host:port - */ - public String getName(); - /** * @return the {@link Server} instance associated with this {@link Connector} */ @@ -52,9 +47,9 @@ public interface Connector extends LifeCycle, Graceful public Executor getExecutor(); /** - * @return the {@link ScheduledExecutorService} used to schedule tasks + * @return the {@link Scheduler} used to schedule tasks */ - public ScheduledExecutorService getScheduler(); + public Scheduler getScheduler(); /** * @return the {@link ByteBufferPool} to acquire buffers from and release buffers to diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java index a0c8c420e22..29fac7f48a2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.DispatcherType; @@ -47,6 +46,7 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; /* ------------------------------------------------------------ */ @@ -232,7 +232,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable { try { - _request.setHandled(false); // TODO: is this right here ? + _request.setHandled(false); _response.getHttpOutput().reopen(); if (_state.isInitial()) @@ -617,7 +617,7 @@ public class HttpChannel implements HttpParser.RequestHandler, Runnable _connector.getExecutor().execute(task); } - public ScheduledExecutorService getScheduler() + public Scheduler getScheduler() { return _connector.getScheduler(); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index f2b3780ca97..83e7f0ee079 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -20,8 +20,6 @@ package org.eclipse.jetty.server; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; @@ -41,6 +39,7 @@ import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; /* ------------------------------------------------------------ */ /** Implementation of Continuation and AsyncContext interfaces @@ -723,7 +722,7 @@ public class HttpChannelState implements AsyncContext, Continuation /* ------------------------------------------------------------ */ protected void scheduleTimeout() { - ScheduledExecutorService scheduler = _channel.getScheduler(); + Scheduler scheduler = _channel.getScheduler(); if (scheduler!=null) _event._timeout=scheduler.schedule(new AsyncTimeout(),_timeoutMs,TimeUnit.MILLISECONDS); } @@ -734,9 +733,9 @@ public class HttpChannelState implements AsyncContext, Continuation AsyncEventState event=_event; if (event!=null) { - Future task=event._timeout; + Scheduler.Task task=event._timeout; if (task!=null) - task.cancel(false); + task.cancel(); } } @@ -1038,7 +1037,7 @@ public class HttpChannelState implements AsyncContext, Continuation /* ------------------------------------------------------------ */ public class AsyncEventState extends AsyncEvent { - private Future _timeout; + private Scheduler.Task _timeout; private final ServletContext _suspendedContext; private ServletContext _dispatchContext; private String _pathInContext; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java index 46748c4f56b..19db4db28e8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java @@ -19,11 +19,11 @@ package org.eclipse.jetty.server; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; public class HttpServerConnector extends SelectChannelConnector { @@ -37,7 +37,7 @@ public class HttpServerConnector extends SelectChannelConnector this(server, null, null, null, sslContextFactory, 0, 0); } - public HttpServerConnector(@Name("server") Server server, @Name("executor") Executor executor, @Name("scheduler") ScheduledExecutorService scheduler, @Name("bufferPool") ByteBufferPool pool, @Name("sslContextFactory") SslContextFactory sslContextFactory, @Name("acceptors") int acceptors, @Name("selectors") int selectors) + public HttpServerConnector(@Name("server") Server server, @Name("executor") Executor executor, @Name("scheduler") Scheduler scheduler, @Name("bufferPool") ByteBufferPool pool, @Name("sslContextFactory") SslContextFactory sslContextFactory, @Name("acceptors") int acceptors, @Name("selectors") int selectors) { super(server, executor, scheduler, pool, sslContextFactory, acceptors, selectors); setDefaultConnectionFactory(new HttpServerConnectionFactory(this)); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java index c265a7ea48d..9764dd32a84 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java @@ -24,7 +24,6 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLEngine; @@ -36,6 +35,7 @@ import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; public class LocalConnector extends AbstractConnector { @@ -51,7 +51,7 @@ public class LocalConnector extends AbstractConnector this(server, null, null, null, sslContextFactory, 0); } - public LocalConnector(Server server, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, + public LocalConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool pool, SslContextFactory sslContextFactory, int acceptors) { super(server,executor,scheduler,pool, sslContextFactory, acceptors); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 29ce8e5a972..d38187f278f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -67,6 +67,7 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; +import org.eclipse.jetty.server.session.AbstractSessionManager; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; import org.eclipse.jetty.util.MultiMap; @@ -1161,6 +1162,21 @@ public class Request implements HttpServletRequest return _channel.getResponse(); } + /* ------------------------------------------------------------ */ + /* + * Add @override when 3.1 api is available + */ + public String changeSessionId() + { + HttpSession session = getSession(false); + if (session == null) + throw new IllegalStateException("No session"); + + AbstractSessionManager.renewSession(this, session, getRemoteUser()!=null); + + return session.getId(); + } + /* ------------------------------------------------------------ */ /* * @see javax.servlet.http.HttpServletRequest#getSession() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java index cf6eb5971b9..6aec9e8ec85 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java @@ -29,7 +29,6 @@ import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.Executor; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; import javax.net.ssl.SSLEngine; import org.eclipse.jetty.io.ByteBufferPool; @@ -42,6 +41,7 @@ import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; /** *

Implementation of {@link NetworkConnector} based on NIO classes.

@@ -57,12 +57,12 @@ public class SelectChannelConnector extends AbstractNetworkConnector private volatile boolean _reuseAddress = true; private volatile int _lingerTime = -1; - public SelectChannelConnector(Server server) + public SelectChannelConnector(@Name("server") Server server) { this(server, null); } - public SelectChannelConnector(Server server, SslContextFactory sslContextFactory) + public SelectChannelConnector(@Name("server")Server server, @Name("sslContextFactory") SslContextFactory sslContextFactory) { this(server, null, null, null, sslContextFactory, 0, 0); } @@ -77,7 +77,7 @@ public class SelectChannelConnector extends AbstractNetworkConnector public SelectChannelConnector( @Name("server") Server server, @Name("executor") Executor executor, - @Name("scheduler") ScheduledExecutorService scheduler, + @Name("scheduler") Scheduler scheduler, @Name("bufferPool") ByteBufferPool pool, @Name("sslContextFactory") SslContextFactory sslContextFactory, @Name("acceptors") int acceptors, diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 2c066bfcb78..a4eb0dfdae1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -46,6 +46,7 @@ import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.Container; import org.eclipse.jetty.util.component.Destroyable; import org.eclipse.jetty.util.component.Graceful; @@ -79,7 +80,7 @@ public class Server extends HandlerWrapper implements Attributes __version=System.getProperty("jetty.version","9.x.y.z-SNAPSHOT"); } - private final Container _container=new Container(); + private final Container _container; private final AttributesMap _attributes = new AttributesMap(); private final ThreadPool _threadPool; private final List _connectors = new CopyOnWriteArrayList<>(); @@ -101,7 +102,7 @@ public class Server extends HandlerWrapper implements Attributes /** Convenience constructor * Creates server and a {@link SelectChannelConnector} at the passed port. */ - public Server(int port) + public Server(@Name("port")int port) { this((ThreadPool)null); SelectChannelConnector connector=new SelectChannelConnector(this); @@ -113,7 +114,7 @@ public class Server extends HandlerWrapper implements Attributes /** Convenience constructor * Creates server and a {@link SelectChannelConnector} at the passed address. */ - public Server(InetSocketAddress addr) + public Server(@Name("address")InetSocketAddress addr) { this((ThreadPool)null); SelectChannelConnector connector=new SelectChannelConnector(this); @@ -124,9 +125,16 @@ public class Server extends HandlerWrapper implements Attributes /* ------------------------------------------------------------ */ - public Server(ThreadPool pool) + public Server(@Name("threadpool") ThreadPool pool) + { + this(pool, null); + } + + /* ------------------------------------------------------------ */ + public Server(@Name("threadpool") ThreadPool pool,@Name("container") Container container) { _threadPool=pool!=null?pool:new QueuedThreadPool(); + _container=container!=null?container:new Container(); addBean(_threadPool); setServer(this); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 3837f7f9fc5..22f31e99228 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -63,7 +63,6 @@ import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HandlerContainer; -import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.ArrayUtil; @@ -147,7 +146,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu private String[] _vhosts; - private Set _connectors; private EventListener[] _eventListeners; private Logger _logger; @@ -168,7 +166,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu private Map _managedAttributes; private String[] _protectedTargets; - public enum Availability { AVAILABLE,SHUTDOWN,UNAVAILABLE}; + public enum Availability { UNAVAILABLE,STARTING,AVAILABLE,SHUTDOWN,}; private volatile Availability _availability; /* ------------------------------------------------------------ */ @@ -392,36 +390,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return _vhosts; } - /* ------------------------------------------------------------ */ - /** - * @return an array of connector names that this context will accept a request from. - */ - @ManagedAttribute("Names and ports of accepted connectors") - public String[] getConnectorNames() - { - if (_connectors == null || _connectors.size() == 0) - return null; - - return _connectors.toArray(new String[_connectors.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * Set the names of accepted connectors. - * - * Names are either "host:port" or a specific configured name for a connector. - * - * @param connectors - * If non null, an array of connector names that this context will accept a request from. - */ - public void setConnectorNames(String[] connectors) - { - if (connectors == null || connectors.length == 0) - _connectors = null; - else - _connectors = new HashSet(Arrays.asList(connectors)); - } - /* ------------------------------------------------------------ */ /* * @see javax.servlet.ServletContext#getAttribute(java.lang.String) @@ -697,7 +665,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu @Override protected void doStart() throws Exception { - _availability = Availability.UNAVAILABLE; + _availability = Availability.STARTING; if (_contextPath == null) throw new IllegalStateException("Null contextPath"); @@ -727,6 +695,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu startContext(); _availability = Availability.AVAILABLE; + LOG.info("started {}",this); } finally { @@ -787,7 +756,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu public void callContextInitialized (ServletContextListener l, ServletContextEvent e) { l.contextInitialized(e); - LOG.info("started {}",this); } /* ------------------------------------------------------------ */ @@ -899,14 +867,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu return false; } - // Check the connector - if (_connectors != null && _connectors.size() > 0) - { - String connector = HttpChannel.getCurrentHttpChannel().getConnector().getName(); - if (connector == null || !_connectors.contains(connector)) - return false; - } - // Are we not the root context? if (_contextPath.length() > 1) { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java index f7b2aa04d8c..0d8277a8324 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java @@ -66,8 +66,8 @@ public abstract class AbstractHttpTest @After public void tearDown() throws Exception { - ((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(false); server.stop(); + ((StdErrLog)Log.getLogger(HttpChannel.class)).setHideStacks(false); } protected SimpleHttpResponse executeRequest() throws URISyntaxException, IOException diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java index da54ce2afbf..e1c0744fb50 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpManyWaysToAsyncCommitBadBehaviourTest.java @@ -41,6 +41,7 @@ import static org.junit.Assert.assertThat; //TODO: reset buffer tests //TODO: add protocol specific tests for connection: close and/or chunking + @RunWith(value = Parameterized.class) public class HttpManyWaysToAsyncCommitBadBehaviourTest extends AbstractHttpTest { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index a1ce4cfc12d..71123685f53 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -26,8 +26,6 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.Locale; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -43,6 +41,8 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.session.HashSessionIdManager; import org.eclipse.jetty.server.session.HashSessionManager; import org.eclipse.jetty.server.session.HashedSession; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Assert; @@ -58,19 +58,19 @@ public class ResponseTest { private Server _server; private HttpChannel _channel; - private ScheduledExecutorService _timer; + private Scheduler _scheduler; @Before public void init() throws Exception { _server = new Server(); - _timer = new ScheduledThreadPoolExecutor(1); - LocalConnector connector = new LocalConnector(_server, null, _timer, null, null, 1); + _scheduler = new TimerScheduler(); + LocalConnector connector = new LocalConnector(_server, null, _scheduler, null, null, 1); _server.addConnector(connector); _server.setHandler(new DumpHandler()); _server.start(); - AbstractEndPoint endp = new ByteArrayEndPoint(_timer, 5000); + AbstractEndPoint endp = new ByteArrayEndPoint(_scheduler, 5000); ByteBufferHttpInput input = new ByteBufferHttpInput(); _channel = new HttpChannel(connector, new HttpConfiguration(null, false), endp, new HttpTransport() { @@ -96,7 +96,6 @@ public class ResponseTest { _server.stop(); _server.join(); - _timer.shutdownNow(); } @Test diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java index 31f237d5e6f..56a90931b41 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/StressTest.java @@ -45,7 +45,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; -@Ignore("Ignore until other tests are working") +@Ignore public class StressTest { private static final Logger LOG = Log.getLogger(StressTest.class); @@ -119,6 +119,13 @@ public class StressTest q.clear(); } + + @Test + public void testMinNonPersistent() throws Throwable + { + doThreads(2,2,false); + } + @Test public void testNonPersistent() throws Throwable { diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 99ef4dc9e02..da85e5dee6a 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -38,8 +38,8 @@ import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.gzip.AbstractCompressedStream; -import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; +import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream; +import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java index 14f89bc6e33..37d830e0b3a 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java @@ -31,9 +31,9 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.gzip.AbstractCompressedStream; -import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; import org.eclipse.jetty.io.UncheckedPrintWriter; +import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream; +import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; /* ------------------------------------------------------------ */ /** Includable GZip Filter. diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java similarity index 99% rename from jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java rename to jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java index 2d4831f2ad3..524cf6022df 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/AbstractCompressedStream.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.http.gzip; +package org.eclipse.jetty.servlets.gzip; import java.io.IOException; import java.io.OutputStream; diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java similarity index 85% rename from jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java rename to jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java index 6557f78a519..2bf9e280e17 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.http.gzip; +package org.eclipse.jetty.servlets.gzip; import java.io.IOException; import java.io.OutputStream; @@ -58,7 +58,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) */ public void setMimeTypes(Set mimeTypes) { @@ -67,7 +67,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setBufferSize(int) */ @Override public void setBufferSize(int bufferSize) @@ -77,7 +77,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setMinCompressSize(int) */ public void setMinCompressSize(int minCompressSize) { @@ -86,7 +86,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setContentType(java.lang.String) */ @Override public void setContentType(String ct) @@ -110,7 +110,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) */ @Override public void setStatus(int sc, String sm) @@ -122,7 +122,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setStatus(int) */ @Override public void setStatus(int sc) @@ -134,7 +134,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setContentLength(int) */ @Override public void setContentLength(int length) @@ -164,7 +164,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#addHeader(java.lang.String, java.lang.String) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#addHeader(java.lang.String, java.lang.String) */ @Override public void addHeader(String name, String value) @@ -193,7 +193,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#flushBuffer() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#flushBuffer() */ @Override public void flushBuffer() throws IOException @@ -208,7 +208,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#reset() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#reset() */ @Override public void reset() @@ -224,7 +224,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#resetBuffer() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#resetBuffer() */ @Override public void resetBuffer() @@ -238,7 +238,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int, java.lang.String) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#sendError(int, java.lang.String) */ @Override public void sendError(int sc, String msg) throws IOException @@ -249,7 +249,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#sendError(int) */ @Override public void sendError(int sc) throws IOException @@ -260,7 +260,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendRedirect(java.lang.String) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#sendRedirect(java.lang.String) */ @Override public void sendRedirect(String location) throws IOException @@ -271,7 +271,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#noCompression() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#noCompression() */ public void noCompression() { @@ -291,7 +291,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#finish() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#finish() */ public void finish() throws IOException { @@ -303,7 +303,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setHeader(java.lang.String, java.lang.String) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setHeader(java.lang.String, java.lang.String) */ @Override public void setHeader(String name, String value) @@ -330,7 +330,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getOutputStream() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#getOutputStream() */ @Override public ServletOutputStream getOutputStream() throws IOException @@ -353,7 +353,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getWriter() + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#getWriter() */ @Override public PrintWriter getWriter() throws IOException @@ -377,7 +377,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setIntHeader(java.lang.String, int) + * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setIntHeader(java.lang.String, int) */ @Override public void setIntHeader(String name, int value) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java similarity index 98% rename from jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java rename to jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java index c84b8dbf6f2..bd8c7cdd7c3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java @@ -16,7 +16,7 @@ // ======================================================================== // -package org.eclipse.jetty.server.handler; +package org.eclipse.jetty.servlets.gzip; import java.io.IOException; import java.io.OutputStream; @@ -36,9 +36,8 @@ import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.gzip.AbstractCompressedStream; -import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java index 2e06a2db194..8b29cfe98e7 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterContentLengthTest.java @@ -24,8 +24,8 @@ import java.util.List; import javax.servlet.Servlet; import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite; import org.eclipse.jetty.servlets.gzip.TestServletLengthTypeStreamWrite; diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java index 34e0f8611d1..e3d1fa3b417 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipFilterDefaultTest.java @@ -27,9 +27,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlets.gzip.GzipTester; import org.eclipse.jetty.toolchain.test.TestingDir; import org.junit.Rule; diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java index ec42f28003a..b9f75e6bc0b 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java @@ -33,8 +33,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -76,6 +74,7 @@ import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; public class StandardSession implements ISession, Parser.Listener, Callback, Dumpable { @@ -95,7 +94,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback queue = new LinkedList<>(); private final ByteBufferPool bufferPool; private final Executor threadPool; - private final ScheduledExecutorService scheduler; + private final Scheduler scheduler; private final short version; private final Controller controller; private final IdleListener idleListener; @@ -110,10 +109,12 @@ public class StandardSession implements ISession, Parser.Listener, Callback controller, IdleListener idleListener, int initialStreamId, SessionFrameListener listener, Generator generator, FlowControlStrategy flowControlStrategy) { + // TODO this should probably be an aggregate lifecycle + this.version = version; this.bufferPool = bufferPool; this.threadPool = threadPool; @@ -1145,7 +1146,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback callback; private final C context; - protected volatile ScheduledFuture task; + protected volatile Scheduler.Task task; protected AbstractFrameBytes(IStream stream, Callback callback, C context) { @@ -1192,9 +1193,9 @@ public class StandardSession implements ISession, Parser.Listener, Callback task = this.task; + Scheduler.Task task = this.task; if (task != null) - task.cancel(false); + task.cancel(); } @Override diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java index 324a5074480..68af230723d 100644 --- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java +++ b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/AsyncTimeoutTest.java @@ -22,7 +22,6 @@ import java.nio.ByteBuffer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -37,6 +36,8 @@ import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -53,7 +54,8 @@ public class AsyncTimeoutTest ByteBufferPool bufferPool = new MappedByteBufferPool(); Executor threadPool = Executors.newCachedThreadPool(); - ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + Scheduler scheduler = new TimerScheduler(); + scheduler.start(); // TODO need to use jetty lifecycles better here Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor()); Session session = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler, new TestController(), null, 1, null, generator, new FlowControlStrategy.None()) { @@ -99,7 +101,8 @@ public class AsyncTimeoutTest ByteBufferPool bufferPool = new MappedByteBufferPool(); Executor threadPool = Executors.newCachedThreadPool(); - ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + Scheduler scheduler = new TimerScheduler(); + scheduler.start(); Generator generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor()); Session session = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler, new TestController(), null, 1, null, generator, new FlowControlStrategy.None()) { diff --git a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java index 83fb82c4702..c1897c0d33b 100644 --- a/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java +++ b/jetty-spdy/spdy-core/src/test/java/org/eclipse/jetty/spdy/StandardSessionTest.java @@ -24,7 +24,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -48,6 +47,9 @@ import org.eclipse.jetty.spdy.frames.SynReplyFrame; import org.eclipse.jetty.spdy.frames.SynStreamFrame; import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; +import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -76,7 +78,7 @@ public class StandardSessionTest private Executor threadPool; private StandardSession session; private Generator generator; - private ScheduledExecutorService scheduler; + private Scheduler scheduler; private Headers headers; @Before @@ -84,12 +86,19 @@ public class StandardSessionTest { bufferPool = new MappedByteBufferPool(); threadPool = Executors.newCachedThreadPool(); - scheduler = Executors.newSingleThreadScheduledExecutor(); + scheduler = new TimerScheduler(); + scheduler.start(); generator = new Generator(bufferPool, new StandardCompressionFactory.StandardCompressor()); session = new StandardSession(SPDY.V2,bufferPool,threadPool,scheduler,controller,null,1,null,generator,new FlowControlStrategy.None()); headers = new Headers(); } + @After + public void after() throws Exception + { + scheduler.stop(); + } + @SuppressWarnings("unchecked") private void setControllerWriteExpectationToFail(final boolean fail) { diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HttpTransportOverSPDY.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HttpTransportOverSPDY.java index 5b95d9dbaa9..824481a5845 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HttpTransportOverSPDY.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/HttpTransportOverSPDY.java @@ -82,6 +82,7 @@ public class HttpTransportOverSPDY implements HttpTransport headers.put(HTTPSPDYHeader.STATUS.name(version), httpStatus.toString()); LOG.debug("HTTP < {} {}", httpVersion, httpStatus); + // TODO merge the two Field classes into one HttpFields fields = info.getHttpFields(); if (fields != null) { @@ -107,12 +108,14 @@ public class HttpTransportOverSPDY implements HttpTransport public void send(ByteBuffer content, boolean lastContent) throws IOException { // Guard against a last 0 bytes write + // TODO work out if we can avoid double calls for lastContent==true if (stream.isClosed() && BufferUtil.isEmpty(content) && lastContent) return; stream.data(new ByteBufferDataInfo(content, lastContent)); } @Override + // TODO move to channel ? public void completed() { LOG.debug("completed"); diff --git a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYConnectionFactory.java b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYConnectionFactory.java index 12db87c674a..cc4232b5c60 100644 --- a/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYConnectionFactory.java +++ b/jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPSPDYConnectionFactory.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.spdy.http; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; @@ -37,6 +36,7 @@ import org.eclipse.jetty.spdy.api.SynInfo; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; public class ServerHTTPSPDYConnectionFactory extends ServerSPDYConnectionFactory { @@ -47,7 +47,7 @@ public class ServerHTTPSPDYConnectionFactory extends ServerSPDYConnectionFactory private final PushStrategy pushStrategy; private final HttpConfiguration configuration; - public ServerHTTPSPDYConnectionFactory(short version, ByteBufferPool bufferPool, Executor threadPool, ScheduledExecutorService scheduler, Connector connector, PushStrategy pushStrategy) + public ServerHTTPSPDYConnectionFactory(short version, ByteBufferPool bufferPool, Executor threadPool, Scheduler scheduler, Connector connector, PushStrategy pushStrategy) { super(version, bufferPool, threadPool, scheduler); this.connector = connector; diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java index ed7f0e251f5..0a064d8efee 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/SPDYClient.java @@ -29,9 +29,7 @@ import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; -import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; import javax.net.ssl.SSLEngine; import org.eclipse.jetty.io.ByteBufferPool; @@ -50,6 +48,8 @@ import org.eclipse.jetty.spdy.parser.Parser; import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; public class SPDYClient { @@ -165,7 +165,7 @@ public class SPDYClient { private final Queue sessions = new ConcurrentLinkedQueue<>(); private final ByteBufferPool bufferPool = new MappedByteBufferPool(); - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + private final Scheduler scheduler = new TimerScheduler(); private final Executor executor; private final SslContextFactory sslContextFactory; private final SelectorManager selector; @@ -193,6 +193,9 @@ public class SPDYClient public Factory(Executor executor, SslContextFactory sslContextFactory, long idleTimeout) { + // TODO make this injectable + addBean(scheduler); + this.idleTimeout = idleTimeout; if (executor == null) executor = new QueuedThreadPool(); @@ -205,6 +208,7 @@ public class SPDYClient selector = new ClientSelectorManager(); addBean(selector); + } public SPDYClient newSPDYClient(short version) diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYConnectionFactory.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYConnectionFactory.java index 01ba3b14822..57116a538dc 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYConnectionFactory.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYConnectionFactory.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.spdy; import java.nio.channels.SocketChannel; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jetty.io.ByteBufferPool; @@ -30,21 +29,22 @@ import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.spdy.parser.Parser; +import org.eclipse.jetty.util.thread.Scheduler; public class ServerSPDYConnectionFactory implements ConnectionFactory { private final ByteBufferPool bufferPool; private final Executor executor; - private final ScheduledExecutorService scheduler; + private final Scheduler scheduler; private final short version; private final ServerSessionFrameListener listener; - public ServerSPDYConnectionFactory(short version, ByteBufferPool bufferPool, Executor executor, ScheduledExecutorService scheduler) + public ServerSPDYConnectionFactory(short version, ByteBufferPool bufferPool, Executor executor, Scheduler scheduler) { this(version, bufferPool, executor, scheduler, null); } - public ServerSPDYConnectionFactory(short version, ByteBufferPool bufferPool, Executor executor, ScheduledExecutorService scheduler, ServerSessionFrameListener listener) + public ServerSPDYConnectionFactory(short version, ByteBufferPool bufferPool, Executor executor, Scheduler scheduler, ServerSessionFrameListener listener) { this.version = version; this.bufferPool = bufferPool; @@ -98,7 +98,7 @@ public class ServerSPDYConnectionFactory implements ConnectionFactory return executor; } - public ScheduledExecutorService getScheduler() + public Scheduler getScheduler() { return scheduler; } diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java index 39768d73b12..c5ba9af3860 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java @@ -100,6 +100,7 @@ public abstract class AbstractTest clientFactory = newSPDYClientFactory(threadPool); clientFactory.start(); } + return clientFactory.newSPDYClient(version).connect(socketAddress, listener).get(5, TimeUnit.SECONDS); } diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java index c6641fe2db1..bd4ecaee848 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; public class SSLEngineLeakTest extends AbstractTest @@ -48,6 +49,7 @@ public class SSLEngineLeakTest extends AbstractTest } @Test + @Ignore public void testSSLEngineLeak() throws Exception { System.gc(); @@ -64,10 +66,16 @@ public class SSLEngineLeakTest extends AbstractTest Thread.sleep(1000); // Perform GC to be sure that the WeakHashMap is cleared - System.gc(); Thread.sleep(1000); + System.gc(); // Check that the WeakHashMap is empty + if (objects.size()!=initialSize) + { + System.err.println(objects); + server.dumpStdErr(); + } + Assert.assertEquals(initialSize, objects.size()); } diff --git a/jetty-spring/src/main/config/etc/jetty-spring.xml b/jetty-spring/src/main/config/etc/jetty-spring.xml index 282a3a76e9e..95f97797f2f 100644 --- a/jetty-spring/src/main/config/etc/jetty-spring.xml +++ b/jetty-spring/src/main/config/etc/jetty-spring.xml @@ -8,7 +8,7 @@ - + diff --git a/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java b/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java index d9a86ca2fb1..fd22cd8a2c6 100644 --- a/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java +++ b/jetty-spring/src/main/java/org/eclipse/jetty/spring/Server.java @@ -19,8 +19,12 @@ package org.eclipse.jetty.spring; +import java.net.InetSocketAddress; import java.util.Collection; +import org.eclipse.jetty.util.component.Container; +import org.eclipse.jetty.util.thread.ThreadPool; + /* ------------------------------------------------------------ */ /** @@ -30,10 +34,34 @@ import java.util.Collection; */ public class Server extends org.eclipse.jetty.server.Server { + public Server() + { + super(); + } + + public Server(InetSocketAddress addr) + { + super(addr); + } + + public Server(int port) + { + super(port); + } + + public Server(ThreadPool pool, Container container) + { + super(pool,container); + } + + public Server(ThreadPool pool) + { + super(pool); + } + public void setBeans(Collection beans) { for (Object o:beans) addBean(o); } - } diff --git a/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java b/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java index 5b4da01e385..4b607b31735 100644 --- a/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java +++ b/jetty-spring/src/test/java/org/eclipse/jetty/spring/SpringXmlConfigurationTest.java @@ -33,7 +33,7 @@ import static junit.framework.Assert.assertEquals; public class SpringXmlConfigurationTest { - protected String _configure="org/mortbay/jetty/spring/configure.xml"; + protected String _configure="org/eclipse/jetty/spring/configure.xml"; @Before public void init() throws Exception @@ -127,7 +127,7 @@ public class SpringXmlConfigurationTest @Test public void testJettyXml() throws Exception { - URL url = SpringXmlConfigurationTest.class.getClassLoader().getResource("org/mortbay/jetty/spring/jetty.xml"); + URL url = SpringXmlConfigurationTest.class.getClassLoader().getResource("org/eclipse/jetty/spring/jetty.xml"); XmlConfiguration configuration = new XmlConfiguration(url); Server server = (Server)configuration.configure(); @@ -139,7 +139,7 @@ public class SpringXmlConfigurationTest @Test public void XmlConfigurationMain() throws Exception { - XmlConfiguration.main(new String[]{"src/test/resources/org/mortbay/jetty/spring/jetty.xml"}); + XmlConfiguration.main(new String[]{"src/test/resources/org/eclipse/jetty/spring/jetty.xml"}); } } diff --git a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml b/jetty-spring/src/test/resources/org/eclipse/jetty/spring/configure.xml similarity index 87% rename from jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml rename to jetty-spring/src/test/resources/org/eclipse/jetty/spring/configure.xml index d55b6453215..8263c469f45 100644 --- a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/configure.xml +++ b/jetty-spring/src/test/resources/org/eclipse/jetty/spring/configure.xml @@ -12,20 +12,20 @@ test - + SetValue 1 - + 2 nested - + deep 2 diff --git a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml b/jetty-spring/src/test/resources/org/eclipse/jetty/spring/jetty-deploy.xml similarity index 89% rename from jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml rename to jetty-spring/src/test/resources/org/eclipse/jetty/spring/jetty-deploy.xml index 88258fd1086..290873d779b 100644 --- a/jetty-spring/src/test/resources/org/mortbay/jetty/spring/jetty-deploy.xml +++ b/jetty-spring/src/test/resources/org/eclipse/jetty/spring/jetty-deploy.xml @@ -2,12 +2,12 @@ - + diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index cd97f11d3bf..73d47bc3cb1 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -142,9 +142,9 @@ public class Main { List ini_args=new ArrayList(); File start_ini = new File(_jettyHome,"start.ini"); - if (start_ini.exists()) - ini_args.addAll(loadStartIni(start_ini)); - + + boolean start_ini_processed=!start_ini.exists(); + File start_d = new File(_jettyHome,"start.d"); if (start_d.isDirectory()) { @@ -156,9 +156,21 @@ public class Main } }); Arrays.sort(inis); + for (File i : inis) + { + if (!start_ini_processed && i.getName().charAt(0)>'0') + { + start_ini_processed=true; + ini_args.addAll(loadStartIni(start_ini)); + } ini_args.addAll(loadStartIni(i)); + } } + + if (!start_ini_processed ) + ini_args.addAll(loadStartIni(start_ini)); + return ini_args; } @@ -392,7 +404,7 @@ public class Main } else if (info.equals("@STARTINI")) { - List ini = loadStartIni(new File(_jettyHome,"start.ini")); + List ini = parseStartIniFiles(); if (ini != null && ini.size() > 0) { for (String a : ini) diff --git a/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config b/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config index 23bb426162f..98e29cc88ff 100644 --- a/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config +++ b/jetty-start/src/main/resources/org/eclipse/jetty/start/start.config @@ -4,18 +4,18 @@ # # Each line contains entry in the format: # -# SUBJECT [ [!] CONDITION [AND|OR] ]* +# SUBJECT [ [!] CONDITION [AND|OR] ]* # # where SUBJECT: -# ends with ".class" is the Main class to run. -# ends with ".xml" is a configuration file for the command line -# ends with "/" is a directory from which to add all jar and zip files. -# ends with "/*" is a directory from which to add all unconsidered jar and zip files. -# ends with "/**" is a directory from which to recursively add all unconsidered jar and zip files. -# Containing = are used to assign system properties. -# Containing ~= are used to assign start properties. -# Containing /= are used to assign a canonical path. -# all other subjects are treated as files to be added to the classpath. +# ends with ".class" is the Main class to run. +# ends with ".xml" is a configuration file for the command line +# ends with "/" is a directory from which to add all jar and zip files. +# ends with "/*" is a directory from which to add all unconsidered jar and zip files. +# ends with "/**" is a directory from which to recursively add all unconsidered jar and zip files. +# Containing = are used to assign system properties. +# Containing ~= are used to assign start properties. +# Containing /= are used to assign a canonical path. +# all other subjects are treated as files to be added to the classpath. # # ${name} is expanded to a start property # $(name) is expanded to either a start property or a system property. @@ -25,15 +25,15 @@ # the home directory. # # CONDITION is one of: -# always -# never -# available classname # true if class on classpath -# property name # true if set as start property -# system name # true if set as system property -# exists file # true if file/dir exists -# java OPERATOR version # java version compared to literal -# nargs OPERATOR number # number of command line args compared to literal -# OPERATOR := one of "<",">","<=",">=","==","!=" +# always +# never +# available classname # true if class on classpath +# property name # true if set as start property +# system name # true if set as system property +# exists file # true if file/dir exists +# java OPERATOR version # java version compared to literal +# nargs OPERATOR number # number of command line args compared to literal +# OPERATOR := one of "<",">","<=",">=","==","!=" # # CONTITIONS can be combined with AND OR or !, with AND being the assume # operator for a list of CONDITIONS. @@ -45,117 +45,118 @@ # [ssl,default] # # Clauses after a section header will only be included if they match one of the tags in the -# options property. By default options are set to "default,*" or the OPTIONS property may +# options property. By default options are set to "default,*" or the OPTIONS property may # be used to pass in a list of tags, eg. : # -# java -jar start.jar OPTIONS=jetty,jsp,ssl +# java -jar start.jar OPTIONS=jetty,jsp,ssl # # The tag '*' is always appended to the options, so any section with the * tag is always # applied. # # add a property defined classpath -${path}.path property path +${path}.path property path # add a property defined library directory -${lib}/** exists ${lib} +${lib}/** exists ${lib} # Try different settings of jetty.home until the start.jar is found. -jetty.home=. ! exists $(jetty.home)/start.jar -jetty.home=.. ! exists $(jetty.home)/start.jar -jetty.home=jetty-distribution/src/main/resources ! exists $(jetty.home)/start.jar -jetty.home=../jetty-distribution/src/main/resources ! exists $(jetty.home)/start.jar -jetty.home=. ! exists $(jetty.home)/start.jar -jetty.home/=$(jetty.home) exists $(jetty.home)/start.jar +jetty.home=. ! exists $(jetty.home)/start.jar +jetty.home=.. ! exists $(jetty.home)/start.jar +jetty.home=jetty-distribution/src/main/resources ! exists $(jetty.home)/start.jar +jetty.home=../jetty-distribution/src/main/resources ! exists $(jetty.home)/start.jar +jetty.home=. ! exists $(jetty.home)/start.jar +jetty.home/=$(jetty.home) exists $(jetty.home)/start.jar # The main class to run org.eclipse.jetty.xml.XmlConfiguration.class -${start.class}.class property start.class +${start.class}.class property start.class # The default configuration files -$(jetty.home)/etc/jetty.xml nargs == 0 -./jetty-server/src/main/config/etc/jetty.xml nargs == 0 AND ! exists $(jetty.home)/etc/jetty.xml +$(jetty.home)/etc/jetty.xml nargs == 0 +./jetty-server/src/main/config/etc/jetty.xml nargs == 0 AND ! exists $(jetty.home)/etc/jetty.xml # Default OPTIONS if not specified on the command line -OPTIONS~=default,* ! property OPTIONS +OPTIONS~=default,* ! property OPTIONS # Add a resources directory if it is there [All,resources,default] $(jetty.home)/resources/ - + # Add jetty modules [*] -$(jetty.home)/lib/jetty-util-$(version).jar ! available org.eclipse.jetty.util.StringUtil -$(jetty.home)/lib/jetty-io-$(version).jar ! available org.eclipse.jetty.io.Buffer +$(jetty.home)/lib/jetty-util-$(version).jar ! available org.eclipse.jetty.util.StringUtil +$(jetty.home)/lib/jetty-io-$(version).jar ! available org.eclipse.jetty.io.Buffer [Server,All,xml,default] -$(jetty.home)/lib/jetty-xml-$(version).jar ! available org.eclipse.jetty.xml.XmlParser - +$(jetty.home)/lib/jetty-xml-$(version).jar ! available org.eclipse.jetty.xml.XmlParser + [Server,All,server,default] -$(jetty.home)/lib/servlet-api-3.0.jar ! available javax.servlet.ServletContext -$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser -$(jetty.home)/lib/jetty-continuation-$(version).jar ! available org.eclipse.jetty.continuation.Continuation -$(jetty.home)/lib/jetty-server-$(version).jar ! available org.eclipse.jetty.server.Server - +$(jetty.home)/lib/servlet-api-3.0.jar ! available javax.servlet.ServletContext +$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser +$(jetty.home)/lib/jetty-continuation-$(version).jar ! available org.eclipse.jetty.continuation.Continuation +$(jetty.home)/lib/jetty-server-$(version).jar ! available org.eclipse.jetty.server.Server + [Server,All,security,default] -$(jetty.home)/lib/jetty-security-$(version).jar ! available org.eclipse.jetty.security.LoginService - +$(jetty.home)/lib/jetty-security-$(version).jar ! available org.eclipse.jetty.security.LoginService + [Server,All,servlet,default] -$(jetty.home)/lib/servlet-api-3.0.jar ! available javax.servlet.ServletContext -$(jetty.home)/lib/jetty-servlet-$(version).jar ! available org.eclipse.jetty.servlet.ServletHandler - +$(jetty.home)/lib/servlet-api-3.0.jar ! available javax.servlet.ServletContext +$(jetty.home)/lib/jetty-servlet-$(version).jar ! available org.eclipse.jetty.servlet.ServletHandler + [Server,All,webapp,default] -$(jetty.home)/lib/jetty-webapp-$(version).jar ! available org.eclipse.jetty.webapp.WebAppContext - +$(jetty.home)/lib/jetty-webapp-$(version).jar ! available org.eclipse.jetty.webapp.WebAppContext + [Server,All,deploy,default] -$(jetty.home)/lib/jetty-deploy-$(version).jar ! available org.eclipse.jetty.deploy.ContextDeployer - +$(jetty.home)/lib/jetty-deploy-$(version).jar ! available org.eclipse.jetty.deploy.ContextDeployer + [Server,All,servlets,default] -$(jetty.home)/lib/jetty-servlets-$(version).jar ! available org.eclipse.jetty.servlets.WelcomeFilter +$(jetty.home)/lib/jetty-servlets-$(version).jar ! available org.eclipse.jetty.servlets.WelcomeFilter [All,rewrite] -$(jetty.home)/lib/jetty-rewrite-$(version).jar ! available org.eclipse.jetty.rewrite.handler.RewriteHandler +$(jetty.home)/lib/jetty-rewrite-$(version).jar ! available org.eclipse.jetty.rewrite.handler.RewriteHandler [All,jmx] -$(jetty.home)/lib/jetty-jmx-$(version).jar ! available org.eclipse.jetty.jmx.MBeanContainer - +$(jetty.home)/lib/jetty-jmx-$(version).jar ! available org.eclipse.jetty.jmx.MBeanContainer + [All,ajp] -$(jetty.home)/lib/jetty-ajp-$(version).jar ! available org.eclipse.jetty.ajp.Ajp13Connection - +$(jetty.home)/lib/jetty-ajp-$(version).jar ! available org.eclipse.jetty.ajp.Ajp13Connection + [All,plus,jndi] -$(jetty.home)/lib/jetty-jndi-${version}.jar ! available org.eclipse.jetty.jndi.ContextFactory -$(jetty.home)/lib/jetty-plus-${version}.jar ! available org.eclipse.jetty.plus.jndi.NamingEntry -$(jetty.home)/lib/jndi/** exists $(jetty.home)/lib/jndi +$(jetty.home)/lib/jetty-jndi-${version}.jar ! available org.eclipse.jetty.jndi.ContextFactory +$(jetty.home)/lib/jetty-plus-${version}.jar ! available org.eclipse.jetty.plus.jndi.NamingEntry +$(jetty.home)/lib/jndi/** exists $(jetty.home)/lib/jndi [All,annotations] -$(jetty.home)/lib/jetty-annotations-$(version).jar ! available org.eclipse.jetty.annotations.AnnotationFinder -$(jetty.home)/lib/annotations/** exists $(jetty.home)/lib/jndi - +$(jetty.home)/lib/jetty-annotations-$(version).jar ! available org.eclipse.jetty.annotations.AnnotationFinder +$(jetty.home)/lib/annotations/** exists $(jetty.home)/lib/jndi + [All,setuid] -$(jetty.home)/lib/jetty-setuid-$(version).jar ! available org.eclipse.jetty.setuid.SetUID -$(jetty.home)/lib/setuid/** - +$(jetty.home)/lib/jetty-setuid-$(version).jar ! available org.eclipse.jetty.setuid.SetUID +$(jetty.home)/lib/setuid/** + [All,policy] -$(jetty.home)/lib/jetty-policy-$(version).jar ! available org.eclipse.jetty.policy.JettyPolicy - +$(jetty.home)/lib/jetty-policy-$(version).jar ! available org.eclipse.jetty.policy.JettyPolicy + [All,Client,client] -$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser -$(jetty.home)/lib/jetty-client-$(version).jar ! available org.eclipse.jetty.client.HttpClient +$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser +$(jetty.home)/lib/jetty-client-$(version).jar ! available org.eclipse.jetty.client.HttpClient [Client] -$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser +$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser [All,websocket] -$(jetty.home)/lib/jetty-websocket-$(version).jar ! available org.eclipse.jetty.websocket.WebSocket - +$(jetty.home)/lib/websocket-core-$(version).jar ! available org.eclipse.jetty.websocket.api.WebSocketConnection +$(jetty.home)/lib/websocket-server-$(version).jar ! available org.eclipse.jetty.websocket.server.WebSocketServlet + [All,overlay,overlays] -$(jetty.home)/lib/jetty-overlay-deployer-$(version).jar ! available org.eclipse.jetty.overlay.OverlayedAppProvider - - +$(jetty.home)/lib/jetty-overlay-deployer-$(version).jar ! available org.eclipse.jetty.overlay.OverlayedAppProvider + + # Add ext if it exists -[Server,All,default,ext] +[Server,All,default,ext] $(jetty.home)/lib/ext/** # Add all other sub-directories in /lib/ as options in a dynamic way -[All,=$(jetty.home)/lib/**] +[All,=$(jetty.home)/lib/**] diff --git a/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt b/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt index 41b0107580e..2a899160a28 100644 --- a/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt +++ b/jetty-start/src/main/resources/org/eclipse/jetty/start/usage.txt @@ -120,9 +120,12 @@ Defaults: which are used if no command line arguments are provided and override the defaults in the start.config file. If the directory jetty.home/start.d exists, then multiple *.ini files will be read from that directory in - alphabetical order. If --ini options are provided on the command line, - then start.ini and start.d will NOT be read. + alphabetical order. The contents of start.ini are processed after any + start.d files starting with a character <= "0". - The current start.ini arguments are: + If --ini options are provided on the command line, then start.ini and + start.d will NOT be read. + + The current start.ini/start.d arguments are: @STARTINI@ diff --git a/jetty-util/src/main/config/etc/jetty-logging.xml b/jetty-util/src/main/config/etc/jetty-logging.xml index 2060a222e2e..a4329945720 100644 --- a/jetty-util/src/main/config/etc/jetty-logging.xml +++ b/jetty-util/src/main/config/etc/jetty-logging.xml @@ -22,7 +22,9 @@ - Redirecting stderr/stdout to + + Redirecting stderr/stdout to + diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ExecutorCallback.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ExecutorCallback.java index 806cafd1471..657e021043d 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ExecutorCallback.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ExecutorCallback.java @@ -103,6 +103,14 @@ public abstract class ExecutorCallback implements Callback { @Override public void run() { onFailed(context,x);} + @Override + public String toString() + { + System.err.println(_executor); + new Throwable().printStackTrace(); + x.printStackTrace(); + return String.format("ExecutorCallback@%x{%s,%s}",hashCode(),context,x); + } }; if (_executor==null) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java index 9ed7d113d6f..bc91ddc0c36 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/StdErrLog.java @@ -348,6 +348,7 @@ public class StdErrLog extends AbstractLogger * Legacy interface where a programmatic configuration of the logger level * is done as a wholesale approach. */ + @Override public void setDebugEnabled(boolean enabled) { if (enabled) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Scheduler.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Scheduler.java new file mode 100644 index 00000000000..e0c552ef357 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Scheduler.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.util.thread; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.component.LifeCycle; + +public interface Scheduler extends LifeCycle +{ + interface Task + { + boolean cancel(); + } + + Task schedule(Runnable task, long delay, TimeUnit units); +} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java index 321e4510062..66353e050ca 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java @@ -31,6 +31,7 @@ import org.eclipse.jetty.util.log.Logger; * The nested class Task should be extended by users of this class to obtain call back notification of * expires. */ +@Deprecated public class Timeout { private static final Logger LOG = Log.getLogger(Timeout.class); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/TimerScheduler.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/TimerScheduler.java new file mode 100644 index 00000000000..f0dd1abe382 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/TimerScheduler.java @@ -0,0 +1,92 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.util.thread; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.util.component.AbstractLifeCycle; + +public class TimerScheduler extends AbstractLifeCycle implements Scheduler +{ + /* this class uses the Timer class rather than an ScheduledExecutionService because + * it uses the same algorithm internally and the signature is cheaper to use as there are no + * Futures involved (which we do not need). + * However, Timer is still locking and a concurrent queue would be better. + */ + Timer _timer; + final String _name; + + public TimerScheduler() + { + this(null); + } + + public TimerScheduler(String name) + { + _name=name; + } + + @Override + protected void doStart() throws Exception + { + _timer=_name==null?new Timer():new Timer(_name); + super.doStart(); + } + + @Override + protected void doStop() throws Exception + { + _timer.cancel(); + super.doStop(); + _timer=null; + } + + @Override + public Task schedule(final Runnable task, final long delay, final TimeUnit units) + { + Timer timer=_timer; + if (timer!=null) + { + SimpleTask t = new SimpleTask(task); + _timer.schedule(t,units.toMillis(delay)); + return t; + } + throw new IllegalStateException("STOPPED: "+this); + } + + private static class SimpleTask extends TimerTask implements Task + { + private final Runnable _task; + + SimpleTask(Runnable runnable) + { + _task=runnable; + } + + @Override + public void run() + { + _task.run(); + } + } + + +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/BenchmarkHelper.java b/jetty-util/src/test/java/org/eclipse/jetty/util/BenchmarkHelper.java new file mode 100644 index 00000000000..a0acc317710 --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/BenchmarkHelper.java @@ -0,0 +1,290 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.util; + +import java.lang.management.CompilationMXBean; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; +import java.lang.management.OperatingSystemMXBean; +import java.util.Date; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +public class BenchmarkHelper implements Runnable +{ + private final OperatingSystemMXBean operatingSystem; + private final CompilationMXBean jitCompiler; + private final MemoryMXBean heapMemory; + private final AtomicInteger starts = new AtomicInteger(); + private volatile MemoryPoolMXBean youngMemoryPool; + private volatile MemoryPoolMXBean survivorMemoryPool; + private volatile MemoryPoolMXBean oldMemoryPool; + private volatile boolean hasMemoryPools; + private volatile ScheduledFuture memoryPoller; + private volatile GarbageCollectorMXBean youngCollector; + private volatile GarbageCollectorMXBean oldCollector; + private volatile boolean hasCollectors; + private volatile ScheduledExecutorService scheduler; + private volatile boolean polling; + private volatile long lastYoungUsed; + private volatile long startYoungCollections; + private volatile long startYoungCollectionsTime; + private volatile long totalYoungUsed; + private volatile long lastSurvivorUsed; + private volatile long totalSurvivorUsed; + private volatile long lastOldUsed; + private volatile long startOldCollections; + private volatile long startOldCollectionsTime; + private volatile long totalOldUsed; + private volatile long startTime; + private volatile long startProcessCPUTime; + private volatile long startJITCTime; + + public BenchmarkHelper() + { + this.operatingSystem = ManagementFactory.getOperatingSystemMXBean(); + this.jitCompiler = ManagementFactory.getCompilationMXBean(); + this.heapMemory = ManagementFactory.getMemoryMXBean(); + + List memoryPools = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean memoryPool : memoryPools) + { + if ("PS Eden Space".equals(memoryPool.getName()) || + "Par Eden Space".equals(memoryPool.getName()) || + "G1 Eden".equals(memoryPool.getName())) + youngMemoryPool = memoryPool; + else if ("PS Survivor Space".equals(memoryPool.getName()) || + "Par Survivor Space".equals(memoryPool.getName()) || + "G1 Survivor".equals(memoryPool.getName())) + survivorMemoryPool = memoryPool; + else if ("PS Old Gen".equals(memoryPool.getName()) || + "CMS Old Gen".equals(memoryPool.getName()) || + "G1 Old Gen".equals(memoryPool.getName())) + oldMemoryPool = memoryPool; + } + hasMemoryPools = youngMemoryPool != null && survivorMemoryPool != null && oldMemoryPool != null; + + List garbageCollectors = ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean garbageCollector : garbageCollectors) + { + if ("PS Scavenge".equals(garbageCollector.getName()) || + "ParNew".equals(garbageCollector.getName()) || + "G1 Young Generation".equals(garbageCollector.getName())) + youngCollector = garbageCollector; + else if ("PS MarkSweep".equals(garbageCollector.getName()) || + "ConcurrentMarkSweep".equals(garbageCollector.getName()) || + "G1 Old Generation".equals(garbageCollector.getName())) + oldCollector = garbageCollector; + } + hasCollectors = youngCollector != null && oldCollector != null; + } + + public void run() + { + if (!hasMemoryPools) + return; + + long young = youngMemoryPool.getUsage().getUsed(); + long survivor = survivorMemoryPool.getUsage().getUsed(); + long old = oldMemoryPool.getUsage().getUsed(); + + if (!polling) + { + polling = true; + } + else + { + if (lastYoungUsed <= young) + { + totalYoungUsed += young - lastYoungUsed; + } + + if (lastSurvivorUsed <= survivor) + { + totalSurvivorUsed += survivor - lastSurvivorUsed; + } + + if (lastOldUsed <= old) + { + totalOldUsed += old - lastOldUsed; + } + else + { + // May need something more here, like "how much was collected" + } + } + lastYoungUsed = young; + lastSurvivorUsed = survivor; + lastOldUsed = old; + } + + public boolean startStatistics() + { + // Support for multiple nodes requires to ignore start requests after the first + // but also requires that requests after the first wait until the initialization + // is completed (otherwise node #2 may start the run while the server is GC'ing) + synchronized (this) + { + if (starts.incrementAndGet() > 1) + return false; + + System.gc(); + System.err.println("\n========================================"); + System.err.println("Statistics Started at " + new Date()); + System.err.println("Operative System: " + operatingSystem.getName() + " " + operatingSystem.getVersion() + " " + operatingSystem.getArch()); + System.err.println("JVM : " + System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name") + " runtime " + System.getProperty("java.vm.version") + " " + System.getProperty("java.runtime.version")); + System.err.println("Processors: " + operatingSystem.getAvailableProcessors()); + if (operatingSystem instanceof com.sun.management.OperatingSystemMXBean) + { + com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean)operatingSystem; + long totalMemory = os.getTotalPhysicalMemorySize(); + long freeMemory = os.getFreePhysicalMemorySize(); + System.err.println("System Memory: " + percent(totalMemory - freeMemory, totalMemory) + "% used of " + gibiBytes(totalMemory) + " GiB"); + } + else + { + System.err.println("System Memory: N/A"); + } + + MemoryUsage heapMemoryUsage = heapMemory.getHeapMemoryUsage(); + System.err.println("Used Heap Size: " + mebiBytes(heapMemoryUsage.getUsed()) + " MiB"); + System.err.println("Max Heap Size: " + mebiBytes(heapMemoryUsage.getMax()) + " MiB"); + if (hasMemoryPools) + { + long youngGenerationHeap = heapMemoryUsage.getMax() - oldMemoryPool.getUsage().getMax(); + System.err.println("Young Generation Heap Size: " + mebiBytes(youngGenerationHeap) + " MiB"); + } + else + { + System.err.println("Young Generation Heap Size: N/A"); + } + System.err.println("- - - - - - - - - - - - - - - - - - - - "); + + scheduler = Executors.newSingleThreadScheduledExecutor(); + polling = false; + memoryPoller = scheduler.scheduleWithFixedDelay(this, 0, 250, TimeUnit.MILLISECONDS); + + lastYoungUsed = 0; + if (hasCollectors) + { + startYoungCollections = youngCollector.getCollectionCount(); + startYoungCollectionsTime = youngCollector.getCollectionTime(); + } + totalYoungUsed = 0; + lastSurvivorUsed = 0; + totalSurvivorUsed = 0; + lastOldUsed = 0; + if (hasCollectors) + { + startOldCollections = oldCollector.getCollectionCount(); + startOldCollectionsTime = oldCollector.getCollectionTime(); + } + totalOldUsed = 0; + + startTime = System.nanoTime(); + if (operatingSystem instanceof com.sun.management.OperatingSystemMXBean) + { + com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean)operatingSystem; + startProcessCPUTime = os.getProcessCpuTime(); + } + startJITCTime = jitCompiler.getTotalCompilationTime(); + + return true; + } + } + + public boolean stopStatistics() + { + synchronized (this) + { + if (starts.decrementAndGet() > 0) + return false; + + memoryPoller.cancel(false); + scheduler.shutdown(); + + System.err.println("- - - - - - - - - - - - - - - - - - - - "); + System.err.println("Statistics Ended at " + new Date()); + long elapsedTime = System.nanoTime() - startTime; + System.err.println("Elapsed time: " + TimeUnit.NANOSECONDS.toMillis(elapsedTime) + " ms"); + long elapsedJITCTime = jitCompiler.getTotalCompilationTime() - startJITCTime; + System.err.println("\tTime in JIT compilation: " + elapsedJITCTime + " ms"); + if (hasCollectors) + { + long elapsedYoungCollectionsTime = youngCollector.getCollectionTime() - startYoungCollectionsTime; + long youngCollections = youngCollector.getCollectionCount() - startYoungCollections; + System.err.println("\tTime in Young Generation GC: " + elapsedYoungCollectionsTime + " ms (" + youngCollections + " collections)"); + long elapsedOldCollectionsTime = oldCollector.getCollectionTime() - startOldCollectionsTime; + long oldCollections = oldCollector.getCollectionCount() - startOldCollections; + System.err.println("\tTime in Old Generation GC: " + elapsedOldCollectionsTime + " ms (" + oldCollections + " collections)"); + } + else + { + System.err.println("\tTime in GC: N/A"); + } + + if (hasMemoryPools) + { + System.err.println("Garbage Generated in Young Generation: " + mebiBytes(totalYoungUsed) + " MiB"); + System.err.println("Garbage Generated in Survivor Generation: " + mebiBytes(totalSurvivorUsed) + " MiB"); + System.err.println("Garbage Generated in Old Generation: " + mebiBytes(totalOldUsed) + " MiB"); + } + else + { + System.err.println("Garbage Generated: N/A"); + } + + if (operatingSystem instanceof com.sun.management.OperatingSystemMXBean) + { + com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean)operatingSystem; + long elapsedProcessCPUTime = os.getProcessCpuTime() - startProcessCPUTime; + System.err.println("Average CPU Load: " + ((float)elapsedProcessCPUTime * 100 / elapsedTime) + "/" + (100 * operatingSystem.getAvailableProcessors())); + } + else + { + System.err.println("Average CPU Load: N/A"); + } + + System.err.println("----------------------------------------\n"); + return true; + } + } + + public float percent(long dividend, long divisor) + { + return (float)dividend * 100 / divisor; + } + + public float mebiBytes(long bytes) + { + return (float)bytes / 1024 / 1024; + } + + public float gibiBytes(long bytes) + { + return (float)bytes / 1024 / 1024 / 1024; + } +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java new file mode 100644 index 00000000000..d3d076198e4 --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java @@ -0,0 +1,308 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.util.thread; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Random; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.eclipse.jetty.toolchain.test.annotation.Slow; +import org.eclipse.jetty.util.BenchmarkHelper; +import org.eclipse.jetty.util.statistic.SampleStatistic; +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + + +@RunWith(value = Parameterized.class) +public class SchedulerTest +{ + private static final BenchmarkHelper benchmark = new BenchmarkHelper(); + private static final Executor executor = Executors.newFixedThreadPool(256); + + @Parameterized.Parameters + public static Collection data() + { + Object[][] data = new Object[][]{ + {new TimerScheduler()}/*, + {new ScheduledExecutionServiceScheduler()}, + {new ConcurrentScheduler(0)}, + {new ConcurrentScheduler(1500)}, + {new ConcurrentScheduler(executor,1500)}*/ + }; + return Arrays.asList(data); + } + + // Scheduler _scheduler=new SimpleScheduler(); + Scheduler _scheduler; + + public SchedulerTest(Scheduler scheduler) + { + _scheduler=scheduler; + } + + @Before + public void before() throws Exception + { + _scheduler.start(); + } + + @After + public void after() throws Exception + { + _scheduler.stop(); + } + + @Test + public void testExecution() throws Exception + { + final AtomicLong executed = new AtomicLong(); + long expected=System.currentTimeMillis()+3000; + Scheduler.Task task=_scheduler.schedule(new Runnable() + { + @Override + public void run() + { + executed.set(System.currentTimeMillis()); + } + },3000,TimeUnit.MILLISECONDS); + + Thread.sleep(4000); + Assert.assertFalse(task.cancel()); + Assert.assertThat(executed.get(),Matchers.greaterThanOrEqualTo(expected)); + Assert.assertThat(expected-executed.get(),Matchers.lessThan(1000L)); + + } + + @Test + public void testTwoExecution() throws Exception + { + final AtomicLong executed = new AtomicLong(); + long expected=System.currentTimeMillis()+3000; + Scheduler.Task task=_scheduler.schedule(new Runnable() + { + @Override + public void run() + { + executed.set(System.currentTimeMillis()); + } + },3000,TimeUnit.MILLISECONDS); + + Thread.sleep(4000); + Assert.assertFalse(task.cancel()); + Assert.assertThat(executed.get(),Matchers.greaterThanOrEqualTo(expected)); + Assert.assertThat(expected-executed.get(),Matchers.lessThan(1000L)); + + final AtomicLong executed1 = new AtomicLong(); + long expected1=System.currentTimeMillis()+3000; + Scheduler.Task task1=_scheduler.schedule(new Runnable() + { + @Override + public void run() + { + executed1.set(System.currentTimeMillis()); + } + },3000,TimeUnit.MILLISECONDS); + + Thread.sleep(4000); + Assert.assertFalse(task1.cancel()); + Assert.assertThat(executed1.get(),Matchers.greaterThanOrEqualTo(expected1)); + Assert.assertThat(expected1-executed1.get(),Matchers.lessThan(1000L)); + } + + @Test + public void testQuickCancel() throws Exception + { + final AtomicLong executed = new AtomicLong(); + Scheduler.Task task=_scheduler.schedule(new Runnable() + { + @Override + public void run() + { + executed.set(System.currentTimeMillis()); + } + },2000,TimeUnit.MILLISECONDS); + + Thread.sleep(100); + Assert.assertTrue(task.cancel()); + Thread.sleep(2500); + Assert.assertEquals(0,executed.get()); + } + + @Test + public void testLongCancel() throws Exception + { + final AtomicLong executed = new AtomicLong(); + Scheduler.Task task=_scheduler.schedule(new Runnable() + { + @Override + public void run() + { + executed.set(System.currentTimeMillis()); + } + },2000,TimeUnit.MILLISECONDS); + + Thread.sleep(1600); + Assert.assertTrue(task.cancel()); + Thread.sleep(1000); + Assert.assertEquals(0,executed.get()); + } + + @Test + @Slow + public void testManySchedulesAndCancels() throws Exception + { + schedule(100,5000,3800,200); + } + + @Test + @Slow + @Ignore + public void testBenchmark() throws Exception + { + schedule(2000,10000,2000,50); + benchmark.startStatistics(); + System.err.println(_scheduler); + schedule(2000,30000,2000,50); + benchmark.stopStatistics(); + } + + private void schedule(int threads,final int duration, final int delay, final int interval) throws Exception + { + final Random random = new Random(1); + Thread[] test = new Thread[threads]; + + final AtomicInteger schedules = new AtomicInteger(); + final SampleStatistic executions = new SampleStatistic(); + final SampleStatistic cancellations = new SampleStatistic(); + + for (int i=test.length;i-->0;) + { + test[i]=new Thread() + { + @Override + public void run() + { + try + { + long now = System.currentTimeMillis(); + long start=now; + long end=start+duration; + boolean last=false; + while (!last) + { + final long expected=now+delay; + int cancel=random.nextInt(interval); + final boolean expected_to_execute; + + last=now+2*interval>end; + if (cancel==0 || last) + { + expected_to_execute=true; + cancel=delay+1000; + } + else + expected_to_execute=false; + + schedules.incrementAndGet(); + Scheduler.Task task=_scheduler.schedule(new Runnable() + { + @Override + public void run() + { + long lateness=System.currentTimeMillis()-expected; + if (expected_to_execute) + executions.set(lateness); + else + executions.set(6666); + + } + },delay,TimeUnit.MILLISECONDS); + + Thread.sleep(cancel); + now = System.currentTimeMillis(); + if (task.cancel()) + { + long lateness=now-expected; + if (expected_to_execute) + cancellations.set(lateness); + else + cancellations.set(0); + } + else + { + if (!expected_to_execute) + { + cancellations.set(9999); + } + } + + Thread.yield(); + } + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + } + }; + } + + for (Thread thread : test) + thread.start(); + + for (Thread thread : test) + thread.join(); + + // System.err.println(schedules); + // System.err.println(executions); + // System.err.println(cancellations); + + // there were some executions and cancellations + Assert.assertThat(executions.getCount(),Matchers.greaterThan(0L)); + Assert.assertThat(cancellations.getCount(),Matchers.greaterThan(0L)); + + // All executed or cancelled + // Not that SimpleScheduler can execute and cancel an event! + Assert.assertThat(0L+schedules.get(),Matchers.lessThanOrEqualTo(executions.getCount()+cancellations.getCount())); + + // No really late executions + Assert.assertThat(executions.getMax(),Matchers.lessThan(500L)); + + // Executions on average are close to the expected time + Assert.assertThat(executions.getMean(),Matchers.lessThan(500.0)); + + // No cancellations long after expected executions + Assert.assertThat(cancellations.getMax(),Matchers.lessThan(500L)); + } + + + +} diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 183ecbf3779..1f810248355 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -107,8 +107,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL "org.eclipse.jetty.continuation.", // webapp cannot change continuation classes "org.eclipse.jetty.jndi.", // webapp cannot change naming classes "org.eclipse.jetty.plus.jaas.", // webapp cannot change jaas classes - "org.eclipse.jetty.websocket.WebSocket", // WebSocket is a jetty extension - "org.eclipse.jetty.websocket.WebSocketFactory", // WebSocket is a jetty extension + "org.eclipse.jetty.websocket.", // WebSocket is a jetty extension "org.eclipse.jetty.servlet.DefaultServlet" // webapp cannot change default servlets } ; @@ -121,8 +120,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL "-org.eclipse.jetty.continuation.", // don't hide continuation classes "-org.eclipse.jetty.jndi.", // don't hide naming classes "-org.eclipse.jetty.plus.jaas.", // don't hide jaas classes - "-org.eclipse.jetty.websocket.WebSocket", // WebSocket is a jetty extension - "-org.eclipse.jetty.websocket.WebSocketFactory", // WebSocket is a jetty extension + "-org.eclipse.jetty.websocket.", // WebSocket is a jetty extension "-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet "-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners "org.eclipse.jetty." // hide other jetty classes @@ -558,12 +556,11 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL Connector[] connectors = getServer().getConnectors(); for (int i=0;i=0) + war=war.substring(war.indexOf("/webapps/")+8); + return super.toString()+"{"+war+"}"; + } + return super.toString(); } /* ------------------------------------------------------------ */ diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClientFactory.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClientFactory.java index 7f35f87e251..b6982a9ed43 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClientFactory.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClientFactory.java @@ -24,8 +24,6 @@ import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; @@ -34,6 +32,8 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.eclipse.jetty.websocket.api.Extension; import org.eclipse.jetty.websocket.api.ExtensionRegistry; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -51,7 +51,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle private final ByteBufferPool bufferPool = new MappedByteBufferPool(); private final Executor executor; - private final ScheduledExecutorService scheduler; + private final Scheduler scheduler; private final EventMethodsCache methodsCache; private final WebSocketPolicy policy; private final WebSocketExtensionRegistry extensionRegistry; @@ -67,15 +67,15 @@ public class WebSocketClientFactory extends AggregateLifeCycle public WebSocketClientFactory(Executor threadPool) { - this(threadPool,Executors.newSingleThreadScheduledExecutor()); + this(threadPool,new TimerScheduler()); } - public WebSocketClientFactory(Executor threadPool, ScheduledExecutorService scheduler) + public WebSocketClientFactory(Executor threadPool, Scheduler scheduler) { this(threadPool,scheduler,null); } - public WebSocketClientFactory(Executor executor, ScheduledExecutorService scheduler, SslContextFactory sslContextFactory) + public WebSocketClientFactory(Executor executor, Scheduler scheduler, SslContextFactory sslContextFactory) { LOG.debug("new WebSocketClientFactory()"); if (executor == null) @@ -90,6 +90,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle throw new IllegalArgumentException("Scheduler is required"); } this.scheduler = scheduler; + addBean(scheduler); if (sslContextFactory != null) { @@ -107,7 +108,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle public WebSocketClientFactory(SslContextFactory sslContextFactory) { - this(new QueuedThreadPool(),Executors.newSingleThreadScheduledExecutor(),sslContextFactory); + this(new QueuedThreadPool(),new TimerScheduler(),sslContextFactory); } @Override @@ -160,7 +161,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle return policy; } - public ScheduledExecutorService getScheduler() + public Scheduler getScheduler() { return scheduler; } diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/ConnectionManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/ConnectionManager.java index 18268bcc823..f30138f3490 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/ConnectionManager.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/ConnectionManager.java @@ -28,7 +28,6 @@ import java.util.Collections; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.FutureCallback; @@ -36,6 +35,7 @@ import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.client.WebSocketClient; @@ -82,7 +82,7 @@ public class ConnectionManager extends AggregateLifeCycle private final Queue clients = new ConcurrentLinkedQueue<>(); private final WebSocketClientSelectorManager selector; - public ConnectionManager(ByteBufferPool bufferPool, Executor executor, ScheduledExecutorService scheduler, SslContextFactory sslContextFactory, + public ConnectionManager(ByteBufferPool bufferPool, Executor executor, Scheduler scheduler, SslContextFactory sslContextFactory, WebSocketPolicy policy) { selector = new WebSocketClientSelectorManager(bufferPool,executor,scheduler,policy); diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/UpgradeConnection.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/UpgradeConnection.java index e67889e767b..c420e904ffa 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/UpgradeConnection.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/UpgradeConnection.java @@ -26,7 +26,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ByteBufferPool; @@ -37,6 +36,7 @@ import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.Extension; import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.api.UpgradeResponse; @@ -82,7 +82,7 @@ public class UpgradeConnection extends AbstractConnection private static final Logger LOG = Log.getLogger(UpgradeConnection.class); private final ByteBufferPool bufferPool; - private final ScheduledExecutorService scheduler; + private final Scheduler scheduler; private final IWebSocketClient client; private final HttpResponseHeaderParser parser; private ClientUpgradeRequest request; @@ -156,7 +156,7 @@ public class UpgradeConnection extends AbstractConnection /** * Read / Parse the waiting read/fill buffer - * + * * @param buffer * the buffer to fill into from the endpoint * @return true if there is more to read, false if reading should stop diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/WebSocketClientSelectorManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/WebSocketClientSelectorManager.java index eaa88831431..4a6a61ec8a2 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/WebSocketClientSelectorManager.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/internal/io/WebSocketClientSelectorManager.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import javax.net.ssl.SSLEngine; import org.eclipse.jetty.io.ByteBufferPool; @@ -34,6 +33,7 @@ import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.client.WebSocketClientFactory; import org.eclipse.jetty.websocket.client.internal.IWebSocketClient; @@ -42,12 +42,12 @@ public class WebSocketClientSelectorManager extends SelectorManager { private static final Logger LOG = Log.getLogger(WebSocketClientSelectorManager.class); private final Executor executor; - private final ScheduledExecutorService scheduler; + private final Scheduler scheduler; private final WebSocketPolicy policy; private final ByteBufferPool bufferPool; private SslContextFactory sslContextFactory; - public WebSocketClientSelectorManager(ByteBufferPool bufferPool, Executor executor, ScheduledExecutorService scheduler, WebSocketPolicy policy) + public WebSocketClientSelectorManager(ByteBufferPool bufferPool, Executor executor, Scheduler scheduler, WebSocketPolicy policy) { super(); this.bufferPool = bufferPool; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java new file mode 100644 index 00000000000..e80874dda58 --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java @@ -0,0 +1,133 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.net.URI; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.UpgradeResponse; +import org.eclipse.jetty.websocket.api.WebSocketConnection; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.eclipse.jetty.websocket.io.AbstractWebSocketConnection; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static org.hamcrest.Matchers.instanceOf; + +/** + * Tests for conditions due to bad networking. + */ +@Ignore("Not working yet") +public class BadNetworkTest +{ + private BlockheadServer server; + private WebSocketClientFactory factory; + + @Before + public void startFactory() throws Exception + { + factory = new WebSocketClientFactory(); + factory.getPolicy().setIdleTimeout(250); + factory.start(); + } + + @Before + public void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @After + public void stopFactory() throws Exception + { + factory.stop(); + } + + @After + public void stopServer() throws Exception + { + server.stop(); + } + + @Test + public void testAbruptClientClose() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection ssocket = server.accept(); + ssocket.upgrade(); + + // Validate that we are connected + future.get(500,TimeUnit.MILLISECONDS); + wsocket.waitForConnected(500,TimeUnit.MILLISECONDS); + + // Have client disconnect abruptly + WebSocketConnection conn = wsocket.getConnection(); + Assert.assertThat("Connection",conn,instanceOf(AbstractWebSocketConnection.class)); + AbstractWebSocketConnection awsc = (AbstractWebSocketConnection)conn; + awsc.disconnect(false); + + // Client Socket should see close + wsocket.waitForClose(10,TimeUnit.SECONDS); + + // Client Socket should see a close event, with status NO_CLOSE + // This event is automatically supplied by the underlying WebSocketClientConnection + // in the situation of a bad network connection. + wsocket.assertCloseCode(StatusCode.NO_CLOSE); + } + + @Test + public void testAbruptServerClose() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection ssocket = server.accept(); + ssocket.upgrade(); + + // Validate that we are connected + future.get(500,TimeUnit.MILLISECONDS); + wsocket.waitForConnected(500,TimeUnit.MILLISECONDS); + + // Have server disconnect abruptly + ssocket.disconnect(); + + // Wait for close + wsocket.waitForClose(10,TimeUnit.SECONDS); + + // Client Socket should see a close event, with status NO_CLOSE + // This event is automatically supplied by the underlying WebSocketClientConnection + // in the situation of a bad network connection. + wsocket.assertCloseCode(StatusCode.NO_CLOSE); + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java new file mode 100644 index 00000000000..f6d8ae9896e --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java @@ -0,0 +1,201 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.net.ConnectException; +import java.net.URI; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.websocket.api.UpgradeException; +import org.eclipse.jetty.websocket.api.UpgradeResponse; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Various connect condition testing + */ +public class ClientConnectTest +{ + private BlockheadServer server; + private WebSocketClientFactory factory; + + @Before + public void startFactory() throws Exception + { + factory = new WebSocketClientFactory(); + factory.start(); + } + + @Before + public void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @After + public void stopFactory() throws Exception + { + factory.stop(); + } + + @After + public void stopServer() throws Exception + { + server.stop(); + } + + @Test(expected = UpgradeException.class) + public void testBadHandshake() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + FutureCallback future = client.connect(wsUri); + + ServerConnection connection = server.accept(); + connection.readRequest(); + // no upgrade, just fail with a 404 error + connection.respond("HTTP/1.1 404 NOT FOUND\r\n\r\n"); + + // The attempt to get upgrade response future should throw error + try + { + future.get(500,TimeUnit.MILLISECONDS); + Assert.fail("Expected ExecutionException -> UpgradeException"); + } + catch (ExecutionException e) + { + // Expected Path - throw underlying exception + FutureCallback.rethrow(e); + } + } + + @Test(expected = UpgradeException.class) + public void testBadUpgrade() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + FutureCallback future = client.connect(wsUri); + + ServerConnection connection = server.accept(); + connection.readRequest(); + // Upgrade badly + connection.respond("HTTP/1.1 101 Upgrade\r\n" + "Sec-WebSocket-Accept: rubbish\r\n" + "\r\n"); + + // The attempt to get upgrade response future should throw error + try + { + future.get(500,TimeUnit.MILLISECONDS); + Assert.fail("Expected ExecutionException -> UpgradeException"); + } + catch (ExecutionException e) + { + // Expected Path - throw underlying exception + FutureCallback.rethrow(e); + } + } + + @Test + public void testConnectionNotAccepted() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + // Intentionally not accept incoming socket. + // server.accept(); + + try + { + future.get(500,TimeUnit.MILLISECONDS); + Assert.fail("Should have Timed Out"); + } + catch (TimeoutException e) + { + // Expected Path + wsocket.assertNotOpened(); + } + } + + @Test(expected = ConnectException.class) + @Ignore("Need to get information about connection issue out of SelectManager somehow") + public void testConnectionRefused() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + // Intentionally bad port + URI wsUri = new URI("ws://127.0.0.1:1"); + Future future = client.connect(wsUri); + + // The attempt to get upgrade response future should throw error + try + { + future.get(1000,TimeUnit.MILLISECONDS); + Assert.fail("Expected ExecutionException -> ConnectException"); + } + catch (ExecutionException e) + { + // Expected Path - throw underlying exception + FutureCallback.rethrow(e); + } + } + + @Test(expected = TimeoutException.class) + public void testConnectionTimeout() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection ssocket = server.accept(); + Assert.assertNotNull(ssocket); + // Intentionally don't upgrade + // ssocket.upgrade(); + + // The attempt to get upgrade response future should throw error + try + { + future.get(500,TimeUnit.MILLISECONDS); + Assert.fail("Expected ExecutionException -> TimeoutException"); + } + catch (ExecutionException e) + { + // Expected Path - throw underlying exception + FutureCallback.rethrow(e); + } + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientWriteThread.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientWriteThread.java new file mode 100644 index 00000000000..2e8b46d14a5 --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientWriteThread.java @@ -0,0 +1,115 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.io.IOException; +import java.util.concurrent.Exchanger; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.WebSocketConnection; + +public class ClientWriteThread extends Thread +{ + private static final Logger LOG = Log.getLogger(ClientWriteThread.class); + private final WebSocketConnection conn; + private Exchanger exchanger; + private int slowness = -1; + private int messageCount = 100; + private String message = "Hello"; + + public ClientWriteThread(WebSocketConnection conn) + { + this.conn = conn; + } + + public Exchanger getExchanger() + { + return exchanger; + } + + public String getMessage() + { + return message; + } + + public int getMessageCount() + { + return messageCount; + } + + public int getSlowness() + { + return slowness; + } + + @Override + public void run() + { + final AtomicInteger m = new AtomicInteger(); + + try + { + while (m.get() < messageCount) + { + conn.write(null,new FutureCallback(),message); + + if (exchanger != null) + { + // synchronized on exchange + exchanger.exchange(message); + } + + m.incrementAndGet(); + + if (slowness > 0) + { + TimeUnit.MILLISECONDS.sleep(slowness); + } + } + } + catch (InterruptedException | IOException e) + { + LOG.warn(e); + } + } + + public void setExchanger(Exchanger exchanger) + { + this.exchanger = exchanger; + } + + public void setMessage(String message) + { + this.message = message; + } + + public void setMessageCount(int messageCount) + { + this.messageCount = messageCount; + } + + public void setSlowness(int slowness) + { + this.slowness = slowness; + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerReadThread.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerReadThread.java new file mode 100644 index 00000000000..814c925a351 --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerReadThread.java @@ -0,0 +1,140 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.eclipse.jetty.websocket.protocol.CloseInfo; +import org.eclipse.jetty.websocket.protocol.OpCode; +import org.eclipse.jetty.websocket.protocol.WebSocketFrame; +import org.junit.Assert; + +import static org.hamcrest.Matchers.is; + +public class ServerReadThread extends Thread +{ + private static final Logger LOG = Log.getLogger(ServerReadThread.class); + private final ServerConnection conn; + private boolean active = true; + private int slowness = -1; // disabled is default + private AtomicInteger frameCount = new AtomicInteger(); + private CountDownLatch expectedMessageCount; + + public ServerReadThread(ServerConnection conn) + { + this.conn = conn; + this.expectedMessageCount = new CountDownLatch(1); + } + + public void cancel() + { + active = false; + } + + public int getFrameCount() + { + return frameCount.get(); + } + + public int getSlowness() + { + return slowness; + } + + @Override + public void run() + { + ByteBufferPool bufferPool = conn.getBufferPool(); + WebSocketPolicy policy = conn.getPolicy(); + ByteBuffer buf = bufferPool.acquire(policy.getBufferSize(),false); + BufferUtil.clearToFill(buf); + + int len = 0; + + try + { + while (active) + { + BufferUtil.clearToFill(buf); + len = conn.read(buf); + + if (len > 0) + { + LOG.debug("Read {} bytes",len); + BufferUtil.flipToFlush(buf,0); + conn.getParser().parse(buf); + } + + LinkedList frames = conn.getIncomingFrames().getFrames(); + WebSocketFrame frame; + while ((frame = frames.poll()) != null) + { + frameCount.incrementAndGet(); + if (frame.getOpCode() == OpCode.CLOSE) + { + active = false; + // automatically response to close frame + CloseInfo close = new CloseInfo(frame); + conn.close(close.getStatusCode()); + } + + expectedMessageCount.countDown(); + } + if (slowness > 0) + { + TimeUnit.MILLISECONDS.sleep(slowness); + } + } + } + catch (IOException | InterruptedException e) + { + LOG.warn(e); + } + finally + { + bufferPool.release(buf); + } + } + + public void setExpectedMessageCount(int expectedMessageCount) + { + this.expectedMessageCount = new CountDownLatch(expectedMessageCount); + } + + public void setSlowness(int slowness) + { + this.slowness = slowness; + } + + public void waitForExpectedMessageCount(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException + { + Assert.assertThat("Expected Message Count attained",expectedMessageCount.await(timeoutDuration,timeoutUnit),is(true)); + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java new file mode 100644 index 00000000000..cbbd71f43f4 --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java @@ -0,0 +1,115 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.io.IOException; +import java.util.concurrent.Exchanger; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.eclipse.jetty.websocket.protocol.WebSocketFrame; + +public class ServerWriteThread extends Thread +{ + private static final Logger LOG = Log.getLogger(ServerWriteThread.class); + private final ServerConnection conn; + private Exchanger exchanger; + private int slowness = -1; + private int messageCount = 100; + private String message = "Hello"; + + public ServerWriteThread(ServerConnection conn) + { + this.conn = conn; + } + + public Exchanger getExchanger() + { + return exchanger; + } + + public String getMessage() + { + return message; + } + + public int getMessageCount() + { + return messageCount; + } + + public int getSlowness() + { + return slowness; + } + + @Override + public void run() + { + final AtomicInteger m = new AtomicInteger(); + + try + { + while (m.get() < messageCount) + { + conn.write(WebSocketFrame.text(message)); + + if (exchanger != null) + { + // synchronized on exchange + exchanger.exchange(message); + } + + m.incrementAndGet(); + + if (slowness > 0) + { + TimeUnit.MILLISECONDS.sleep(slowness); + } + } + } + catch (InterruptedException | IOException e) + { + LOG.warn(e); + } + } + + public void setExchanger(Exchanger exchanger) + { + this.exchanger = exchanger; + } + + public void setMessage(String message) + { + this.message = message; + } + + public void setMessageCount(int messageCount) + { + this.messageCount = messageCount; + } + + public void setSlowness(int slowness) + { + this.slowness = slowness; + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java new file mode 100644 index 00000000000..341e456c0df --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java @@ -0,0 +1,117 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.net.URI; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.toolchain.test.annotation.Slow; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.UpgradeResponse; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.Matchers.is; + +public class SlowClientTest +{ + private BlockheadServer server; + private WebSocketClientFactory factory; + + @Before + public void startFactory() throws Exception + { + factory = new WebSocketClientFactory(); + factory.getPolicy().setIdleTimeout(60000); + factory.start(); + } + + @Before + public void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @After + public void stopFactory() throws Exception + { + factory.stop(); + } + + @After + public void stopServer() throws Exception + { + server.stop(); + } + + @Test + @Slow + public void testClientSlowToSend() throws Exception + { + // final Exchanger exchanger = new Exchanger(); + TrackingSocket tsocket = new TrackingSocket(); + // tsocket.messageExchanger = exchanger; + WebSocketClient client = factory.newWebSocketClient(tsocket); + client.getPolicy().setIdleTimeout(60000); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection sconnection = server.accept(); + sconnection.setSoTimeout(60000); + sconnection.upgrade(); + + // Confirm connected + future.get(500,TimeUnit.MILLISECONDS); + tsocket.waitForConnected(500,TimeUnit.MILLISECONDS); + + // Setup server read thread + ServerReadThread reader = new ServerReadThread(sconnection); + reader.setExpectedMessageCount(Integer.MAX_VALUE); // keep reading till I tell you to stop + reader.start(); + + // Have client write slowly. + int messageCount = 1000; + + ClientWriteThread writer = new ClientWriteThread(tsocket.getConnection()); + writer.setMessageCount(messageCount); + writer.setMessage("Hello"); + // writer.setExchanger(exchanger); + writer.setSlowness(50); + writer.start(); + writer.join(); + + // Verify receive + Assert.assertThat("Frame Receive Count",reader.getFrameCount(),is(messageCount)); + + // Close + tsocket.getConnection().close(StatusCode.NORMAL,"Done"); + + Assert.assertTrue("Client Socket Closed",tsocket.closeLatch.await(10,TimeUnit.SECONDS)); + tsocket.assertCloseCode(StatusCode.NORMAL); + + reader.cancel(); // stop reading + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java new file mode 100644 index 00000000000..65be180524b --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java @@ -0,0 +1,161 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.net.URI; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.toolchain.test.annotation.Slow; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.UpgradeResponse; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.Matchers.is; + +public class SlowServerTest +{ + private BlockheadServer server; + private WebSocketClientFactory factory; + + @Before + public void startFactory() throws Exception + { + factory = new WebSocketClientFactory(); + factory.getPolicy().setIdleTimeout(60000); + factory.start(); + } + + @Before + public void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @After + public void stopFactory() throws Exception + { + factory.stop(); + } + + @After + public void stopServer() throws Exception + { + server.stop(); + } + + @Test + @Slow + public void testServerSlowToRead() throws Exception + { + // final Exchanger exchanger = new Exchanger(); + TrackingSocket tsocket = new TrackingSocket(); + // tsocket.messageExchanger = exchanger; + WebSocketClient client = factory.newWebSocketClient(tsocket); + client.getPolicy().setIdleTimeout(60000); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection sconnection = server.accept(); + sconnection.setSoTimeout(60000); + sconnection.upgrade(); + + // Confirm connected + future.get(500,TimeUnit.MILLISECONDS); + tsocket.waitForConnected(500,TimeUnit.MILLISECONDS); + + int messageCount = 10; // TODO: increase to 1000 + + // Setup slow server read thread + ServerReadThread reader = new ServerReadThread(sconnection); + reader.setExpectedMessageCount(messageCount); + reader.setSlowness(100); // slow it down + reader.start(); + + // Have client write as quickly as it can. + ClientWriteThread writer = new ClientWriteThread(tsocket.getConnection()); + writer.setMessageCount(messageCount); + writer.setMessage("Hello"); + // writer.setExchanger(exchanger); + writer.setSlowness(-1); // disable slowness + writer.start(); + writer.join(); + + // Verify receive + reader.waitForExpectedMessageCount(10,TimeUnit.SECONDS); + Assert.assertThat("Frame Receive Count",reader.getFrameCount(),is(messageCount)); + + // Close + tsocket.getConnection().close(StatusCode.NORMAL,"Done"); + + Assert.assertTrue("Client Socket Closed",tsocket.closeLatch.await(10,TimeUnit.SECONDS)); + tsocket.assertCloseCode(StatusCode.NORMAL); + + reader.cancel(); // stop reading + } + + @Test + @Slow + public void testServerSlowToSend() throws Exception + { + // final Exchanger exchanger = new Exchanger(); + TrackingSocket tsocket = new TrackingSocket(); + // tsocket.messageExchanger = exchanger; + WebSocketClient client = factory.newWebSocketClient(tsocket); + client.getPolicy().setIdleTimeout(60000); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection sconnection = server.accept(); + sconnection.setSoTimeout(60000); + sconnection.upgrade(); + + // Confirm connected + future.get(500,TimeUnit.MILLISECONDS); + tsocket.waitForConnected(500,TimeUnit.MILLISECONDS); + + // Have server write slowly. + int messageCount = 1000; + + ServerWriteThread writer = new ServerWriteThread(sconnection); + writer.setMessageCount(messageCount); + writer.setMessage("Hello"); + // writer.setExchanger(exchanger); + writer.setSlowness(50); + writer.start(); + writer.join(); + + // Verify receive + Assert.assertThat("Message Receive Count",tsocket.messageQueue.size(),is(messageCount)); + + // Close + sconnection.close(StatusCode.NORMAL); + + Assert.assertTrue("Client Socket Closed",tsocket.closeLatch.await(10,TimeUnit.SECONDS)); + tsocket.assertCloseCode(StatusCode.NORMAL); + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TimeoutTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TimeoutTest.java new file mode 100644 index 00000000000..8eb81d32523 --- /dev/null +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TimeoutTest.java @@ -0,0 +1,105 @@ +// +// ======================================================================== +// Copyright (c) 1995-2012 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.websocket.client; + +import java.net.URI; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.UpgradeResponse; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer; +import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer.ServerConnection; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static org.hamcrest.Matchers.lessThanOrEqualTo; + +/** + * Various tests for Timeout handling + */ +@Ignore("Idle timeouts not working yet") +public class TimeoutTest +{ + private BlockheadServer server; + private WebSocketClientFactory factory; + + @Before + public void startFactory() throws Exception + { + factory = new WebSocketClientFactory(); + factory.getPolicy().setIdleTimeout(250); // idle timeout (for all tests here) + factory.start(); + } + + @Before + public void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @After + public void stopFactory() throws Exception + { + factory.stop(); + } + + @After + public void stopServer() throws Exception + { + server.stop(); + } + + /** + * In a situation where the upgrade/connection is successfull, and there is no activity for a while, the idle timeout triggers on the client side and + * automatically initiates a close handshake. + */ + @Test + public void testIdleDetectedByClient() throws Exception + { + TrackingSocket wsocket = new TrackingSocket(); + + WebSocketClient client = factory.newWebSocketClient(wsocket); + + URI wsUri = server.getWsUri(); + Future future = client.connect(wsUri); + + ServerConnection ssocket = server.accept(); + ssocket.upgrade(); + + // Validate that connect occurred + future.get(500,TimeUnit.MILLISECONDS); + wsocket.waitForConnected(500,TimeUnit.MILLISECONDS); + + // Wait for inactivity idle timeout. + long start = System.currentTimeMillis(); + wsocket.waitForClose(10,TimeUnit.SECONDS); + long end = System.currentTimeMillis(); + long dur = (end - start); + // Make sure idle timeout takes less than 5 total seconds + Assert.assertThat("Idle Timeout",dur,lessThanOrEqualTo(5000L)); + + // Client should see a close event, with status NO_CLOSE + wsocket.assertCloseCode(StatusCode.NORMAL); + } +} diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TrackingSocket.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TrackingSocket.java index 2895a21973d..24798a8ec99 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TrackingSocket.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TrackingSocket.java @@ -57,7 +57,7 @@ public class TrackingSocket extends WebSocketAdapter public void assertCloseCode(int expectedCode) throws InterruptedException { - Assert.assertThat("Was Closed",closeLatch.await(500,TimeUnit.MILLISECONDS),is(true)); + Assert.assertThat("Was Closed",closeLatch.await(50,TimeUnit.MILLISECONDS),is(true)); Assert.assertThat("Close Code",closeCode,is(expectedCode)); } @@ -163,7 +163,17 @@ public class TrackingSocket extends WebSocketAdapter } } - public void waitForMessage(TimeUnit timeoutUnit, int timeoutDuration) throws InterruptedException + public void waitForClose(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException + { + Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true)); + } + + public void waitForConnected(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException + { + Assert.assertThat("Client Socket Connected",openLatch.await(timeoutDuration,timeoutUnit),is(true)); + } + + public void waitForMessage(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException { Assert.assertThat("Message Received",dataLatch.await(timeoutDuration,timeoutUnit),is(true)); } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java index e53885aa67f..fb7b21badeb 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java @@ -18,20 +18,12 @@ package org.eclipse.jetty.websocket.client; -import java.net.ConnectException; import java.net.URI; -import java.util.concurrent.Exchanger; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.FutureCallback; -import org.eclipse.jetty.websocket.api.StatusCode; -import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.client.blockhead.BlockheadServer; @@ -40,13 +32,10 @@ import org.eclipse.jetty.websocket.protocol.WebSocketFrame; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; -import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.notNullValue; @RunWith(AdvancedRunner.class) @@ -81,58 +70,6 @@ public class WebSocketClientTest server.stop(); } - @Test(expected = UpgradeException.class) - public void testBadHandshake() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - - URI wsUri = server.getWsUri(); - FutureCallback future = client.connect(wsUri); - - ServerConnection connection = server.accept(); - connection.readRequest(); - // no upgrade, just fail with a 404 error - connection.respond("HTTP/1.1 404 NOT FOUND\r\n\r\n"); - - // The attempt to get upgrade response future should throw error - try - { - future.get(500,TimeUnit.MILLISECONDS); - Assert.fail("Expected ExecutionException -> UpgradeException"); - } - catch (ExecutionException e) - { - FutureCallback.rethrow(e); - } - } - - @Test(expected = UpgradeException.class) - public void testBadUpgrade() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - - URI wsUri = server.getWsUri(); - FutureCallback future = client.connect(wsUri); - - ServerConnection connection = server.accept(); - connection.readRequest(); - // Upgrade badly - connection.respond("HTTP/1.1 101 Upgrade\r\n" + "Sec-WebSocket-Accept: rubbish\r\n" + "\r\n"); - - // The attempt to get upgrade response future should throw error - try - { - future.get(500,TimeUnit.MILLISECONDS); - Assert.fail("Expected ExecutionException -> UpgradeException"); - } - catch (ExecutionException e) - { - FutureCallback.rethrow(e); - } - } - @Test public void testBasicEcho_FromClient() throws Exception { @@ -161,7 +98,7 @@ public class WebSocketClientTest cliSock.getConnection().write(null,new FutureCallback(),"Hello World!"); srvSock.echoMessage(1,TimeUnit.MILLISECONDS,500); // wait for response from server - cliSock.waitForMessage(TimeUnit.MILLISECONDS,500); + cliSock.waitForMessage(500,TimeUnit.MILLISECONDS); cliSock.assertMessage("Hello World!"); } @@ -193,263 +130,6 @@ public class WebSocketClientTest wsocket.assertMessage("Hello World"); } - @Test - public void testBlockReceiving() throws Exception - { - final Exchanger exchanger = new Exchanger(); - TrackingSocket tsocket = new TrackingSocket(); - tsocket.messageExchanger = exchanger; - WebSocketClient client = factory.newWebSocketClient(tsocket); - client.getPolicy().setIdleTimeout(60000); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - ServerConnection sconnection = server.accept(); - sconnection.setSoTimeout(60000); - sconnection.upgrade(); - - future.get(500,TimeUnit.MILLISECONDS); - - // define some messages to send server to client - byte[] send = new byte[] - { (byte)0x81, (byte)0x05, (byte)'H', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; - final int messages = 100000; - final AtomicInteger m = new AtomicInteger(); - - // Set up a consumer of received messages that waits a while before consuming - Thread consumer = new Thread() - { - @Override - public void run() - { - try - { - Thread.sleep(200); - while (m.get() < messages) - { - String msg = exchanger.exchange(null); - if ("Hello".equals(msg)) - { - m.incrementAndGet(); - } - else - { - throw new IllegalStateException("exchanged " + msg); - } - if ((m.get() % 1000) == 0) - { - // Artificially slow reader - Thread.sleep(10); - } - } - } - catch (InterruptedException e) - { - return; - } - catch (Exception e) - { - e.printStackTrace(); - } - } - }; - consumer.start(); - - long start = System.currentTimeMillis(); - for (int i = 0; i < messages; i++) - { - sconnection.write(send,0,send.length); - sconnection.flush(); - } - - while (consumer.isAlive()) - { - Thread.sleep(10); - } - - // Duration of the read operation. - long readDur = (System.currentTimeMillis() - start); - - Assert.assertThat("read duration",readDur,greaterThan(1000L)); // reading was blocked - Assert.assertEquals(m.get(),messages); - - // Close with code - sconnection.close(StatusCode.NORMAL); - - Assert.assertTrue("Client Socket Closed",tsocket.closeLatch.await(10,TimeUnit.SECONDS)); - tsocket.assertCloseCode(StatusCode.NORMAL); - } - - @Test - @Ignore("Not working, it hangs") - public void testBlockSending() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - client.getPolicy().setIdleTimeout(10000); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - final ServerConnection ssocket = server.accept(); - ssocket.upgrade(); - - future.get(250,TimeUnit.MILLISECONDS); - - final int messages = 200000; - final AtomicLong totalB = new AtomicLong(); - - Thread consumer = new Thread() - { - @Override - public void run() - { - // Thread.sleep is for artificially poor performance reader needed for this testcase. - try - { - Thread.sleep(200); - byte[] recv = new byte[32 * 1024]; - - int len = 0; - while (len >= 0) - { - totalB.addAndGet(len); - len = ssocket.getInputStream().read(recv,0,recv.length); - Thread.sleep(10); - } - } - catch (InterruptedException e) - { - return; - } - catch (Exception e) - { - e.printStackTrace(); - } - } - }; - consumer.start(); - - // Send lots of messages client to server - long start = System.currentTimeMillis(); - String mesg = "This is a test message to send"; - for (int i = 0; i < messages; i++) - { - wsocket.getConnection().write(null,new FutureCallback(),mesg); - } - - // Duration for the write phase - long writeDur = (System.currentTimeMillis() - start); - - // wait for consumer to complete - while (totalB.get() < (messages * (mesg.length() + 6L))) - { - Thread.sleep(10); - } - - Assert.assertThat("write duration",writeDur,greaterThan(1000L)); // writing was blocked - Assert.assertEquals(messages * (mesg.length() + 6L),totalB.get()); - - consumer.interrupt(); - } - - @Test - public void testConnectionNotAccepted() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - // Intentionally not accept incoming socket. - // server.accept(); - - try - { - future.get(500,TimeUnit.MILLISECONDS); - Assert.fail("Should have Timed Out"); - } - catch (TimeoutException e) - { - // Expected Path - wsocket.assertNotOpened(); - } - } - - @Test(expected = ConnectException.class) - @Ignore("Needs work in SelectManager to support this use case") - public void testConnectionRefused() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - - // Intentionally bad port - URI wsUri = new URI("ws://127.0.0.1:1"); - Future future = client.connect(wsUri); - - // The attempt to get upgrade response future should throw error - try - { - future.get(1000,TimeUnit.MILLISECONDS); - Assert.fail("Expected ExecutionException -> ConnectException"); - } - catch (ExecutionException e) - { - FutureCallback.rethrow(e); - } - } - - @Test(expected = TimeoutException.class) - public void testConnectionTimeout() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - ServerConnection ssocket = server.accept(); - Assert.assertNotNull(ssocket); - // Intentionally don't upgrade - // ssocket.upgrade(); - - // The attempt to get upgrade response future should throw error - try - { - future.get(500,TimeUnit.MILLISECONDS); - Assert.fail("Expected ExecutionException -> TimeoutException"); - } - catch (ExecutionException e) - { - FutureCallback.rethrow(e); - } - } - - @Test - @Ignore("Work In Progress") - public void testIdle() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - - WebSocketClient client = factory.newWebSocketClient(wsocket); - client.getPolicy().setIdleTimeout(500); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - ServerConnection ssocket = server.accept(); - ssocket.upgrade(); - - future.get(250,TimeUnit.MILLISECONDS); - - long start = System.currentTimeMillis(); - wsocket.closeLatch.await(10,TimeUnit.SECONDS); - Assert.assertTrue((System.currentTimeMillis() - start) < 5000); - wsocket.assertCloseCode(StatusCode.NORMAL); - } - @Test public void testMessageBiggerThanBufferSize() throws Exception { @@ -491,80 +171,4 @@ public class WebSocketClientTest factSmall.stop(); } } - - @Test - @Ignore("Work In Progress") - public void testNotIdle() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - - WebSocketClient client = factory.newWebSocketClient(wsocket); - client.getPolicy().setIdleTimeout(500); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - ServerConnection ssocket = server.accept(); - ssocket.upgrade(); - - future.get(250,TimeUnit.MILLISECONDS); - - wsocket.assertIsOpen(); - - // Send some messages from client to server - byte[] recv = new byte[1024]; - int len = -1; - for (int i = 0; i < 10; i++) - { - Thread.sleep(250); - wsocket.getConnection().write(null,new FutureCallback(),"Hello"); - len = ssocket.getInputStream().read(recv,0,recv.length); - Assert.assertTrue(len > 0); - } - - // Send some messages from server to client - byte[] send = new byte[] - { (byte)0x81, (byte)0x02, (byte)'H', (byte)'i' }; - - for (int i = 0; i < 10; i++) - { - Thread.sleep(250); - ssocket.write(send,0,send.length); - ssocket.flush(); - Assert.assertEquals("Hi",wsocket.messageQueue.poll(1,TimeUnit.SECONDS)); - } - - // Close with code - long start = System.currentTimeMillis(); - ssocket.write(new byte[] - { (byte)0x88, (byte)0x02, (byte)4, (byte)87 },0,4); - ssocket.flush(); - - wsocket.closeLatch.await(10,TimeUnit.SECONDS); - long dur = (System.currentTimeMillis() - start); - Assert.assertThat("Overall duration",dur,lessThanOrEqualTo(5000L)); - wsocket.assertClose(StatusCode.PROTOCOL,"Invalid close code 1111"); - } - - @Test - @Ignore("Test for is-open is broken") - public void testUpgradeThenTCPClose() throws Exception - { - TrackingSocket wsocket = new TrackingSocket(); - WebSocketClient client = factory.newWebSocketClient(wsocket); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsUri); - - ServerConnection ssocket = server.accept(); - ssocket.upgrade(); - - future.get(500,TimeUnit.MILLISECONDS); - - wsocket.assertIsOpen(); - - ssocket.disconnect(); - - Assert.assertThat("Close should have been detected",wsocket.closeLatch.await(10,TimeUnit.SECONDS),is(true)); - } } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/blockhead/BlockheadServer.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/blockhead/BlockheadServer.java index f246ffc790f..1ed1c6fe6a6 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/blockhead/BlockheadServer.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/blockhead/BlockheadServer.java @@ -152,6 +152,16 @@ public class BlockheadServer getOutputStream().flush(); } + public ByteBufferPool getBufferPool() + { + return bufferPool; + } + + public IncomingFramesCapture getIncomingFrames() + { + return incomingFrames; + } + public InputStream getInputStream() throws IOException { if (in == null) @@ -170,6 +180,16 @@ public class BlockheadServer return out; } + public Parser getParser() + { + return parser; + } + + public WebSocketPolicy getPolicy() + { + return policy; + } + @Override public void incoming(WebSocketException e) { diff --git a/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties index 65780458623..a0dcc15718c 100644 --- a/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties @@ -1,5 +1,5 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -# org.eclipse.jetty.LEVEL=DEBUG +org.eclipse.jetty.LEVEL=WARN # org.eclipse.jetty.io.ChannelEndPoint.LEVEL=INFO org.eclipse.jetty.websocket.LEVEL=WARN # org.eclipse.jetty.websocket.LEVEL=DEBUG diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/api/BaseConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/api/BaseConnection.java index 623be5bdcbd..cb694169bd0 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/api/BaseConnection.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/api/BaseConnection.java @@ -25,6 +25,18 @@ import java.net.InetSocketAddress; */ public interface BaseConnection { + public static enum State + { + /** Connection created, but not yet connected */ + OPENING, + /** Connection created and connected */ + OPENED, + /** Close handshake initiated, response pending. */ + CLOSING, + /** Close handshake responded. */ + CLOSED + } + /** * Connection suspend token */ @@ -37,7 +49,7 @@ public interface BaseConnection } /** - * Terminate connection, {@link StatusCode#NORMAL}, without a reason. + * Send a websocket Close frame, {@link StatusCode#NORMAL}, without a reason. *

* Basic usage: results in an non-blocking async write, then connection close. * @@ -47,7 +59,7 @@ public interface BaseConnection void close(); /** - * Terminate connection, with status code. + * Send a websocket Close frame, with status code. *

* Advanced usage: results in an non-blocking async write, then connection close. * @@ -59,6 +71,11 @@ public interface BaseConnection */ void close(int statusCode, String reason); + /** + * Terminate the connection (no close frame sent) + */ + void disconnect(); + /** * Get the remote Address in use for this connection. * @@ -66,6 +83,13 @@ public interface BaseConnection */ InetSocketAddress getRemoteAddress(); + /** + * Get the state of the connection. + * + * @return the state of the connection. + */ + State getState(); + /** * Simple test to see if connection is open (and not closed) * @@ -80,6 +104,11 @@ public interface BaseConnection */ boolean isReading(); + /** + * Notify that the connection has entered the closing handshake + */ + void notifyClosing(); + /** * Suspend a the incoming read events on the connection. * diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/driver/WebSocketEventDriver.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/driver/WebSocketEventDriver.java index 82e23e19fc0..4d12afc40f1 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/driver/WebSocketEventDriver.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/driver/WebSocketEventDriver.java @@ -28,6 +28,7 @@ import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.annotations.WebSocket; +import org.eclipse.jetty.websocket.api.BaseConnection; import org.eclipse.jetty.websocket.api.CloseException; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketException; @@ -169,7 +170,22 @@ public class WebSocketEventDriver implements IncomingFrames { events.onClose.call(websocket,session,close.getStatusCode(),close.getReason()); } - throw new CloseException(close.getStatusCode(),close.getReason()); + + // Is this close frame a response to a prior close? + if (session.getState() == BaseConnection.State.CLOSING) + { + // Then this is close response handshake (to a prior + // outgoing close frame) + session.disconnect(); + } + else + { + // This is the initiator for a close handshake + // Trigger close response handshake. + session.notifyClosing(); + session.close(close.getStatusCode(),close.getReason()); + } + return; } case OpCode.PING: { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java index b4a4ad83466..86853fda3e8 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java @@ -24,7 +24,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -37,6 +36,7 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.BaseConnection; import org.eclipse.jetty.websocket.api.CloseException; import org.eclipse.jetty.websocket.api.StatusCode; @@ -58,7 +58,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp private static final Logger LOG_FRAMES = Log.getLogger("org.eclipse.jetty.websocket.io.Frames"); private final ByteBufferPool bufferPool; - private final ScheduledExecutorService scheduler; + private final Scheduler scheduler; private final Generator generator; private final Parser parser; private final WebSocketPolicy policy; @@ -68,8 +68,9 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp private List extensions; private boolean flushing; private boolean isFilling; + private BaseConnection.State connectionState; - public AbstractWebSocketConnection(EndPoint endp, Executor executor, ScheduledExecutorService scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool) + public AbstractWebSocketConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool) { super(endp,executor); this.policy = policy; @@ -80,18 +81,19 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp this.extensions = new ArrayList<>(); this.queue = new FrameQueue(); this.suspendToken = new AtomicBoolean(false); + this.connectionState = BaseConnection.State.OPENING; } @Override public void close() { - terminateConnection(StatusCode.NORMAL,null); + close(StatusCode.NORMAL,null); } @Override public void close(int statusCode, String reason) { - terminateConnection(statusCode,reason); + enqueClose(statusCode,reason); } public void complete(FrameBytes frameBytes) @@ -106,8 +108,15 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp } } + @Override + public void disconnect() + { + disconnect(false); + } + public void disconnect(boolean onlyOutput) { + connectionState = BaseConnection.State.CLOSED; EndPoint endPoint = getEndPoint(); // We need to gently close first, to allow // SSL close alerts to be sent by Jetty @@ -120,6 +129,24 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp } } + /** + * Enqueue a close frame. + * + * @param statusCode + * the WebSocket status code. + * @param reason + * the (optional) reason string. (null is allowed) + * @see StatusCode + */ + private void enqueClose(int statusCode, String reason) + { + CloseInfo close = new CloseInfo(statusCode,reason); + FutureCallback nop = new FutureCallback<>(); + ControlFrameBytes frameBytes = new ControlFrameBytes(this,nop,null,close.asFrame()); + queue.append(frameBytes); + flush(); + } + public void flush() { FrameBytes frameBytes = null; @@ -153,7 +180,11 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp LOG.debug("Flushing {}, {} frame(s) in queue",frameBytes,queue.size()); } } - write(buffer,frameBytes); + + if (connectionState != BaseConnection.State.CLOSED) + { + write(buffer,frameBytes); + } } public ByteBufferPool getBufferPool() @@ -199,7 +230,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp return getEndPoint().getRemoteAddress(); } - public ScheduledExecutorService getScheduler() + public Scheduler getScheduler() { return scheduler; } @@ -209,10 +240,16 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp return session; } + @Override + public State getState() + { + return connectionState; + } + @Override public boolean isOpen() { - return getEndPoint().isOpen(); + return (getState() != BaseConnection.State.CLOSED) && getEndPoint().isOpen(); } @Override @@ -221,6 +258,19 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp return isFilling; } + @Override + public void notifyClosing() + { + this.connectionState = BaseConnection.State.CLOSING; + } + + @Override + public void onClose() + { + super.onClose(); + this.connectionState = BaseConnection.State.CLOSED; + } + @Override public void onFillable() { @@ -252,6 +302,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp public void onOpen() { super.onOpen(); + this.connectionState = BaseConnection.State.OPENED; LOG.debug("fillInterested"); fillInterested(); } @@ -327,13 +378,13 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp catch (IOException e) { LOG.warn(e); - terminateConnection(StatusCode.PROTOCOL,e.getMessage()); + enqueClose(StatusCode.PROTOCOL,e.getMessage()); return -1; } catch (CloseException e) { LOG.warn(e); - terminateConnection(e.getStatusCode(),e.getMessage()); + enqueClose(e.getStatusCode(),e.getMessage()); return -1; } } @@ -341,7 +392,8 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp @Override public void resume() { - if(suspendToken.getAndSet(false)) { + if (suspendToken.getAndSet(false)) + { fillInterested(); } } @@ -379,24 +431,6 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp return this; } - /** - * For terminating connections forcefully. - * - * @param statusCode - * the WebSocket status code. - * @param reason - * the (optional) reason string. (null is allowed) - * @see StatusCode - */ - private void terminateConnection(int statusCode, String reason) - { - CloseInfo close = new CloseInfo(statusCode,reason); - FutureCallback nop = new FutureCallback<>(); - ControlFrameBytes frameBytes = new ControlFrameBytes(this,nop,null,close.asFrame()); - queue.append(frameBytes); - flush(); - } - @Override public String toString() { @@ -411,6 +445,13 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp { LOG_FRAMES.debug("{} Writing {} frame bytes of {}",policy.getBehavior(),buffer.remaining(),frameBytes); } + + if (connectionState == BaseConnection.State.CLOSED) + { + // connection is closed, STOP WRITING, geez. + return; + } + try { endpoint.write(frameBytes.context,frameBytes,buffer); diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java index c3c4fe4101c..ff6a0e5b3e1 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java @@ -23,6 +23,7 @@ import java.nio.ByteBuffer; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.BaseConnection; import org.eclipse.jetty.websocket.protocol.OpCode; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; @@ -45,8 +46,17 @@ public class ControlFrameBytes extends FrameBytes if (frame.getOpCode() == OpCode.CLOSE) { - // Disconnect the connection (no more packets/frames) - connection.disconnect(false); + // is this outgoing close frame a response to a close? + if (connection.getState() == BaseConnection.State.CLOSING) + { + // Disconnect the connection (no more packets/frames) + connection.disconnect(false); + } + else + { + // Then this is the initiator for a close handshake. + connection.notifyClosing(); + } } else { diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java index 08cfe4a9dcd..226f78a24d0 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java @@ -20,12 +20,12 @@ package org.eclipse.jetty.websocket.io; import java.nio.ByteBuffer; import java.nio.channels.InterruptedByTimeoutException; -import java.util.concurrent.ScheduledFuture; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.protocol.WebSocketFrame; public abstract class FrameBytes implements Callback, Runnable @@ -36,7 +36,7 @@ public abstract class FrameBytes implements Callback, Runnable protected final C context; protected final WebSocketFrame frame; // Task used to timeout the bytes - protected volatile ScheduledFuture task; + protected volatile Scheduler.Task task; protected FrameBytes(AbstractWebSocketConnection connection, Callback callback, C context, WebSocketFrame frame) { @@ -48,10 +48,10 @@ public abstract class FrameBytes implements Callback, Runnable private void cancelTask() { - ScheduledFuture task = this.task; + Scheduler.Task task = this.task; if (task != null) { - task.cancel(false); + task.cancel(); } } diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java index 9f983b4c927..c705cfa60c4 100644 --- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java +++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/WebSocketSession.java @@ -37,6 +37,7 @@ import org.eclipse.jetty.websocket.protocol.WebSocketFrame; public class WebSocketSession implements WebSocketConnection, IncomingFrames, OutgoingFrames { private static final Logger LOG = Log.getLogger(WebSocketSession.class); + /** * The reference to the base connection. *

@@ -69,6 +70,12 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou baseConnection.close(statusCode,reason); } + @Override + public void disconnect() + { + baseConnection.disconnect(); + } + public IncomingFrames getIncoming() { return websocket; @@ -91,6 +98,12 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou return baseConnection.getRemoteAddress(); } + @Override + public BaseConnection.State getState() + { + return baseConnection.getState(); + } + @Override public String getSubProtocol() { @@ -123,6 +136,12 @@ public class WebSocketSession implements WebSocketConnection, IncomingFrames, Ou return baseConnection.isReading(); } + @Override + public void notifyClosing() + { + baseConnection.notifyClosing(); + } + public void onConnect() { LOG.debug("onConnect()"); diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/io/LocalWebSocketConnection.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/io/LocalWebSocketConnection.java index 25d12aaaf08..0f6bf9e9d6f 100644 --- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/io/LocalWebSocketConnection.java +++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/io/LocalWebSocketConnection.java @@ -56,6 +56,11 @@ public class LocalWebSocketConnection implements WebSocketConnection { } + @Override + public void disconnect() + { + } + @Override public WebSocketPolicy getPolicy() { @@ -68,6 +73,12 @@ public class LocalWebSocketConnection implements WebSocketConnection return null; } + @Override + public State getState() + { + return null; + } + @Override public String getSubProtocol() { @@ -86,10 +97,14 @@ public class LocalWebSocketConnection implements WebSocketConnection return false; } + @Override + public void notifyClosing() + { + } + @Override public void ping(C context, Callback callback, byte[] payload) throws IOException { - } @Override diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerConnection.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerConnection.java index ce8b5c9ee01..093d13e72c9 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerConnection.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerConnection.java @@ -19,10 +19,10 @@ package org.eclipse.jetty.websocket.server; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.io.AbstractWebSocketConnection; @@ -31,7 +31,7 @@ public class WebSocketServerConnection extends AbstractWebSocketConnection private final WebSocketServerFactory factory; private boolean connected; - public WebSocketServerConnection(EndPoint endp, Executor executor, ScheduledExecutorService scheduler, WebSocketPolicy policy, + public WebSocketServerConnection(EndPoint endp, Executor executor, Scheduler scheduler, WebSocketPolicy policy, ByteBufferPool bufferPool, WebSocketServerFactory factory) { super(endp,executor,scheduler,policy,bufferPool); diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index 1c2cec86261..6b7e83e30c6 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -28,8 +28,6 @@ import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -38,9 +36,11 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.server.HttpConnection; -import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.Scheduler; +import org.eclipse.jetty.util.thread.TimerScheduler; import org.eclipse.jetty.websocket.annotations.WebSocket; import org.eclipse.jetty.websocket.api.Extension; import org.eclipse.jetty.websocket.api.ExtensionRegistry; @@ -61,7 +61,7 @@ import org.eclipse.jetty.websocket.server.handshake.HandshakeRFC6455; /** * Factory to create WebSocket connections */ -public class WebSocketServerFactory extends AbstractLifeCycle implements WebSocketCreator +public class WebSocketServerFactory extends AggregateLifeCycle implements WebSocketCreator { private static final Logger LOG = Log.getLogger(WebSocketServerFactory.class); @@ -75,7 +75,7 @@ public class WebSocketServerFactory extends AbstractLifeCycle implements WebSock /** * Have the factory maintain 1 and only 1 scheduler. All connections share this scheduler. */ - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + private final Scheduler scheduler = new TimerScheduler(); private final String supportedVersions; private final WebSocketPolicy basePolicy; private final EventMethodsCache methodsCache; @@ -91,6 +91,9 @@ public class WebSocketServerFactory extends AbstractLifeCycle implements WebSock public WebSocketServerFactory(WebSocketPolicy policy, ByteBufferPool bufferPool) { + addBean(scheduler); + addBean(bufferPool); + this.basePolicy = policy; this.methodsCache = new EventMethodsCache(); this.bufferPool = bufferPool; diff --git a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties index 0e6cda6a6b8..24592db4291 100644 --- a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties @@ -11,7 +11,7 @@ org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF # org.eclipse.jetty.util.thread.QueuedThreadPool.LEVEL=DEBUG # org.eclipse.jetty.io.SelectorManager.LEVEL=INFO # org.eclipse.jetty.websocket.LEVEL=DEBUG -# org.eclipse.jetty.websocket.io.FrameBytes.LEVEL=DEBUG +org.eclipse.jetty.websocket.io.FrameBytes.LEVEL=OFF # org.eclipse.jetty.websocket.io.ControlFrameBytes.LEVEL=DEBUG # org.eclipse.jetty.websocket.driver.WebSocketEventDriver.LEVEL=DEBUG # org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index a7872a754bb..3001cc507a5 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -346,6 +346,22 @@ public class XmlConfiguration if (id != null) _idMap.put(id,obj); + // Object already constructed so skip any arguments + for (; i < cfg.size(); i++) + { + Object o = cfg.get(i); + if (o instanceof String) + continue; + XmlParser.Node node = (XmlParser.Node)o; + if ("Arg".equals(node.getTag())) + { + LOG.warn("Ignored arg: "+node); + continue; + } + break; + } + + // Process real arguments for (; i < cfg.size(); i++) { Object o = cfg.get(i); diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java index ec5525ba216..50a2d0a0142 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/TestConfiguration.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.eclipse.jetty.util.annotation.Name; import org.junit.Ignore; @Ignore @@ -33,6 +34,7 @@ public class TestConfiguration extends HashMap { public static int VALUE=77; + public final String name; public TestConfiguration nested; public Object testObject; public int testInt; @@ -49,7 +51,19 @@ public class TestConfiguration extends HashMap private Set set; private ConstructorArgTestClass constructorArgTestClass; public Map map; + + + public TestConfiguration() + { + this(""); + } + + public TestConfiguration(@Name("name") String n) + { + name=n; + } + public void setTest(Object value) { testObject=value; @@ -73,7 +87,7 @@ public class TestConfiguration extends HashMap public TestConfiguration call(Boolean b) { - nested=new TestConfiguration(); + nested=new TestConfiguration("called-"+name); nested.put("Arg",b); return nested; } diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java index b634863e543..1d75992d4a5 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java @@ -56,7 +56,7 @@ public class XmlConfigurationTest URL url = XmlConfigurationTest.class.getClassLoader().getResource(_configure); XmlConfiguration configuration = new XmlConfiguration(url); - TestConfiguration tc = new TestConfiguration(); + TestConfiguration tc = new TestConfiguration("tc"); configuration.getProperties().putAll(properties); configuration.configure(tc); diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml index c1232b822be..709bd0d6112 100644 --- a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml +++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml @@ -2,6 +2,7 @@ + name SetValue diff --git a/pom.xml b/pom.xml index 32a50f15fa7..d584d88f4d6 100644 --- a/pom.xml +++ b/pom.xml @@ -378,9 +378,12 @@ jetty-annotations jetty-jndi jetty-jsp + jetty-distribution + jetty-spring jetty-client-new + - jetty-distribution