From 0cfc25d4ed25ca1775f786e13b1ecf56e818169c Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 28 Feb 2018 14:26:02 +1100 Subject: [PATCH 01/87] Resolved errorprone ReferenceEquality warnings #2206 Objects which inherit or implement an `equals()` method should not be compared with == or != When the comparison of references is intentional `@SuppressWarnings("ReferenceEquality")` can be used Signed-off-by: Lachlan Roberts --- .../jetty/http/GZIPContentDecoder.java | 4 +- .../org/eclipse/jetty/http/HttpField.java | 5 +- .../eclipse/jetty/io/ByteArrayEndPoint.java | 20 +++++-- .../eclipse/jetty/io/ssl/SslConnection.java | 6 +- .../jetty/server/HttpChannelOverHttp.java | 7 ++- .../org/eclipse/jetty/server/Request.java | 16 ++++- .../eclipse/jetty/server/ResponseWriter.java | 20 ++++++- .../eclipse/jetty/server/ResponseTest.java | 59 +++++++++++++++++++ .../eclipse/jetty/servlet/DefaultServlet.java | 4 +- .../eclipse/jetty/servlet/ServletHandler.java | 4 +- .../java/org/eclipse/jetty/util/Fields.java | 4 +- .../org/eclipse/jetty/util/UrlEncoded.java | 2 +- .../org/eclipse/jetty/util/log/StdErrLog.java | 4 +- .../jetty/util/resource/FileResource.java | 4 +- .../jetty/util/security/Credential.java | 4 +- .../jetty/webapp/ClasspathPattern.java | 8 +-- 16 files changed, 148 insertions(+), 23 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java index 7df8d821e14..ccadf2d3b16 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java @@ -417,7 +417,9 @@ public class GZIPContentDecoder implements Destroyable */ public void release(ByteBuffer buffer) { - if (_pool!=null && buffer!=BufferUtil.EMPTY_BUFFER) + @SuppressWarnings("ReferenceEquality") + boolean isBufferEmpty = (buffer!=BufferUtil.EMPTY_BUFFER); + if (_pool!=null && isBufferEmpty) _pool.release(buffer); } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java index 93fe67b3dbf..adffa595b44 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java @@ -276,9 +276,12 @@ public class HttpField public boolean isSameName(HttpField field) { + @SuppressWarnings("ReferenceEquality") + boolean sameObject = (field==this); + if (field==null) return false; - if (field==this) + if (sameObject) return true; if (_header!=null && _header==field.getHeader()) return true; 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 ce1c9c2a047..ec5baedb32d 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 @@ -202,7 +202,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint throw new ClosedChannelException(); ByteBuffer in = _inQ.peek(); - if (BufferUtil.hasContent(in) || in==EOF) + if (BufferUtil.hasContent(in) || isEOF(in)) execute(_runFillable); } } @@ -224,7 +224,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint boolean fillable=false; try(Locker.Lock lock = _locker.lock()) { - if (_inQ.peek()==EOF) + if (isEOF(_inQ.peek())) throw new RuntimeIOException(new EOFException()); boolean was_empty=_inQ.isEmpty(); if (in==null) @@ -248,7 +248,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint boolean fillable=false; try(Locker.Lock lock = _locker.lock()) { - if (_inQ.peek()==EOF) + if (isEOF(_inQ.peek())) throw new RuntimeIOException(new EOFException()); boolean was_empty=_inQ.isEmpty(); if (in==null) @@ -415,7 +415,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint break; ByteBuffer in= _inQ.peek(); - if (in==EOF) + if (isEOF(in)) { filled=-1; break; @@ -549,4 +549,16 @@ public class ByteArrayEndPoint extends AbstractEndPoint return String.format("%s[q=%d,q[0]=%s,o=%s]",super.toString(),q,b,o); } + /* ------------------------------------------------------------ */ + /** + * Compares a ByteBuffer Object to EOF by Reference + * @param buffer the input ByteBuffer to be compared to EOF + * @return Whether the reference buffer is equal to that of EOF + */ + private static boolean isEOF(ByteBuffer buffer) + { + @SuppressWarnings("ReferenceEquality") + boolean is_EOF = (buffer==EOF); + return is_EOF; + } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java index 06fc0ddb155..8673f263965 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java @@ -626,8 +626,12 @@ public class SslConnection extends AbstractConnection // We also need an app buffer, but can use the passed buffer if it is big enough ByteBuffer app_in; + boolean used_passed_buffer = false; if (BufferUtil.space(buffer) > _sslEngine.getSession().getApplicationBufferSize()) + { app_in = buffer; + used_passed_buffer = true; + } else if (_decryptedInput == null) app_in = _decryptedInput = _bufferPool.acquire(_sslEngine.getSession().getApplicationBufferSize(), _decryptedDirectBuffers); else @@ -729,7 +733,7 @@ public class SslConnection extends AbstractConnection // another call to fill() or flush(). if (unwrapResult.bytesProduced() > 0) { - if (app_in == buffer) + if (used_passed_buffer) return unwrapResult.bytesProduced(); return BufferUtil.append(buffer,_decryptedInput); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index bee4f951c92..70545de2016 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -427,7 +427,10 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque if (LOG.isDebugEnabled()) LOG.debug("upgrade {} {}", this, _upgrade); - if (_upgrade != PREAMBLE_UPGRADE_H2C && (_connection == null || !_connection.contains("upgrade"))) + @SuppressWarnings("ReferenceEquality") + boolean isUpgraded_H2C = (_upgrade == PREAMBLE_UPGRADE_H2C); + + if (!isUpgraded_H2C && (_connection == null || !_connection.contains("upgrade"))) throw new BadMessageException(HttpStatus.BAD_REQUEST_400); // Find the upgrade factory @@ -464,7 +467,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque // Send 101 if needed try { - if (_upgrade != PREAMBLE_UPGRADE_H2C) + if (!isUpgraded_H2C) sendResponse(new MetaData.Response(HttpVersion.HTTP_1_1, HttpStatus.SWITCHING_PROTOCOLS_101, response101, 0), null, true); } catch (IOException e) 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 5003436dcc3..63930e8bd3c 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 @@ -143,6 +143,18 @@ public class Request implements HttpServletRequest private static final MultiMap NO_PARAMS = new MultiMap<>(); + /* ------------------------------------------------------------ */ + /** + * Compare inputParameters to NO_PARAMS by Reference + * @param inputParameters The parameters to compare to NO_PARAMS + * @return True if the inputParameters reference is equal to NO_PARAMS otherwise False + */ + private static boolean isNoParams(MultiMap inputParameters) { + @SuppressWarnings("ReferenceEquality") + boolean is_no_params = (inputParameters==NO_PARAMS); + return is_no_params; + } + /* ------------------------------------------------------------ */ /** * Obtain the base {@link Request} instance of a {@link ServletRequest}, by @@ -397,9 +409,9 @@ public class Request implements HttpServletRequest } // Do parameters need to be combined? - if (_queryParameters==NO_PARAMS || _queryParameters.size()==0) + if (isNoParams(_queryParameters) || _queryParameters.size()==0) _parameters=_contentParameters; - else if (_contentParameters==NO_PARAMS || _contentParameters.size()==0) + else if (isNoParams(_contentParameters) || _contentParameters.size()==0) _parameters=_queryParameters; else { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java index 7a964e4feb5..c13b6145892 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java @@ -456,11 +456,29 @@ public class ResponseWriter extends PrintWriter { try { + + if(l==null) + l = _locale; + synchronized (lock) { isOpen(); - if ((_formatter == null) || (_formatter.locale() != l)) + + if(_formatter == null) + { _formatter = new Formatter(this, l); + } + else if(_formatter.locale() != null) + { + if(!_formatter.locale().equals(l)) + _formatter = new Formatter(this, l); + } + else + { + if(l != null) + _formatter = new Formatter(this, l); + } + _formatter.format(l, format, args); } } 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 3dddc7c732b..9d0021130a7 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 @@ -63,6 +63,7 @@ import org.eclipse.jetty.server.session.Session; import org.eclipse.jetty.server.session.SessionData; import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.toolchain.test.AdvancedRunner; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.TimerScheduler; @@ -112,10 +113,13 @@ public class ResponseTest private Server _server; private HttpChannel _channel; + private ByteBuffer _content = BufferUtil.allocate(16*1024); @Before public void init() throws Exception { + BufferUtil.clear(_content); + _server = new Server(); Scheduler _scheduler = new TimerScheduler(); HttpConfiguration config = new HttpConfiguration(); @@ -139,6 +143,12 @@ public class ResponseTest @Override public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback) { + if(BufferUtil.hasContent(content)) + { + BufferUtil.append(_content, content); + } + + if (_channelError==null) callback.succeeded(); else @@ -172,6 +182,7 @@ public class ResponseTest { return false; } + }); } @@ -364,6 +375,54 @@ public class ResponseTest assertTrue(response.toString().indexOf("charset=utf-8") > 0); } + @Test + public void testLocaleFormat() throws Exception + { + Response response = getResponse(); + + ContextHandler context = new ContextHandler(); + context.addLocaleEncoding(Locale.ENGLISH.toString(), "ISO-8859-1"); + context.addLocaleEncoding(Locale.ITALIAN.toString(), "ISO-8859-2"); + response.getHttpChannel().getRequest().setContext(context.getServletContext()); + + response.setLocale(java.util.Locale.ITALIAN); + + PrintWriter out = response.getWriter(); + + out.format("TestA1 %,.2f%n", 1234567.89); + out.format("TestA2 %,.2f%n", 1234567.89); + + out.format((java.util.Locale)null,"TestB1 %,.2f%n", 1234567.89); + out.format((java.util.Locale)null,"TestB2 %,.2f%n", 1234567.89); + + out.format(Locale.ENGLISH,"TestC1 %,.2f%n", 1234567.89); + out.format(Locale.ENGLISH,"TestC2 %,.2f%n", 1234567.89); + + out.format(Locale.ITALIAN,"TestD1 %,.2f%n", 1234567.89); + out.format(Locale.ITALIAN,"TestD2 %,.2f%n", 1234567.89); + + out.close(); + + /* Test A */ + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestA1 1.234.567,89")); + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestA2 1.234.567,89")); + + /* Test B */ + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestB1 1.234.567,89")); + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestB2 1.234.567,89")); + + /* Test C */ + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestC1 1,234,567.89")); + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestC2 1,234,567.89")); + + /* Test D */ + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestD1 1.234.567,89")); + Assert.assertThat(BufferUtil.toString(_content),Matchers.containsString("TestD2 1.234.567,89")); + + + } + + @Test public void testContentTypeCharacterEncoding() throws Exception { diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index cf57826e53a..ad47828d840 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -514,7 +514,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc if ((_welcomeServlets || _welcomeExactServlets) && welcome_servlet==null) { MappedResource entry=_servletHandler.getMappedServlet(welcome_in_context); - if (entry!=null && entry.getResource()!=_defaultHolder && + @SuppressWarnings("ReferenceEquality") + boolean isDefaultHolder = (entry.getResource()!=_defaultHolder); + if (entry!=null && isDefaultHolder && (_welcomeServlets || (_welcomeExactServlets && entry.getPathSpec().getDeclaration().equals(welcome_in_context)))) welcome_servlet=welcome_in_context; diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index ba920f6d5c9..4ddaf61793f 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -1513,7 +1513,9 @@ public class ServletHandler extends ScopedHandler boolean found = false; for (ServletHolder s:_servlets) { - if (s == holder) + @SuppressWarnings("ReferenceEquality") + boolean foundServletHolder = (s == holder); + if (foundServletHolder) found = true; } return found; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index 9c360b4b8cc..74d00b128fe 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -253,7 +253,9 @@ public class Fields implements Iterable public boolean equals(Field that, boolean caseSensitive) { - if (this == that) + @SuppressWarnings("ReferenceEquality") + boolean isCurrentObject = (this == that); + if (isCurrentObject) return true; if (that == null) return false; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java index 363721175cf..455857647a2 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java @@ -221,7 +221,7 @@ public class UrlEncoded extends MultiMap implements Cloneable if (charset==null) charset=ENCODING; - if (charset==StandardCharsets.UTF_8) + if (StandardCharsets.UTF_8.equals(charset)) { decodeUtf8To(content,0,content.length(),map); return; 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 383144a9933..9817d493482 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 @@ -211,7 +211,9 @@ public class StdErrLog extends AbstractLogger */ public StdErrLog(String name, Properties props) { - if (props!=null && props!=Log.__props) + @SuppressWarnings("ReferenceEquality") + boolean sameObject = (props!=Log.__props); + if (props!=null && sameObject) Log.__props.putAll(props); _name = name == null?"":name; _abbrevname = condensePackageString(this._name); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java index 71b2151d779..296dd6a8dfe 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java @@ -416,7 +416,9 @@ public class FileResource extends Resource return false; FileResource f=(FileResource)o; - return f._file == _file || (null != _file && _file.equals(f._file)); + @SuppressWarnings("ReferenceEquality") + boolean sameFile = f._file==_file; + return sameFile || (null != _file && _file.equals(f._file)); } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java index 8792924340d..862d3bd7605 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java @@ -95,7 +95,9 @@ public abstract class Credential implements Serializable */ protected static boolean stringEquals(String known, String unknown) { - if (known == unknown) + @SuppressWarnings("ReferenceEquality") + boolean sameObject = (known == unknown); + if (sameObject) return true; if (known == null || unknown == null) return false; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java index 863013791fc..576d37d2f5e 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java @@ -696,9 +696,9 @@ public class ClasspathPattern extends AbstractSet LOG.debug("match {} from {} byName={} byLocation={} in {}",clazz,location,byName,byLocation,this); // Combine the tri-state match of both IncludeExclude Sets - boolean included = byName==Boolean.TRUE || byLocation==Boolean.TRUE + boolean included = Boolean.TRUE.equals(byName) || Boolean.TRUE.equals(byLocation) || (byName==null && !_patterns.hasIncludes() && byLocation==null && !_locations.hasIncludes()); - boolean excluded = byName==Boolean.FALSE || byLocation==Boolean.FALSE; + boolean excluded = Boolean.FALSE.equals(byName) || Boolean.FALSE.equals(byLocation); return included && !excluded; } catch (Exception e) @@ -737,9 +737,9 @@ public class ClasspathPattern extends AbstractSet } // Combine the tri-state match of both IncludeExclude Sets - boolean included = byName==Boolean.TRUE || byLocation==Boolean.TRUE + boolean included = Boolean.TRUE.equals(byName) || Boolean.TRUE.equals(byLocation) || (byName==null && !_patterns.hasIncludes() && byLocation==null && !_locations.hasIncludes()); - boolean excluded = byName==Boolean.FALSE || byLocation==Boolean.FALSE; + boolean excluded = Boolean.FALSE.equals(byName) || Boolean.FALSE.equals(byLocation); return included && !excluded; } From 016c8076e0436b78df845097464f1bedeb939244 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 28 Feb 2018 16:02:47 +1100 Subject: [PATCH 02/87] updates after review #2206 Signed-off-by: Lachlan Roberts --- .../jetty/http/GZIPContentDecoder.java | 4 +-- .../eclipse/jetty/server/ResponseWriter.java | 25 ++++++++++--------- .../java/org/eclipse/jetty/util/Fields.java | 4 +-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java index ccadf2d3b16..c4ce22f2013 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java @@ -418,8 +418,8 @@ public class GZIPContentDecoder implements Destroyable public void release(ByteBuffer buffer) { @SuppressWarnings("ReferenceEquality") - boolean isBufferEmpty = (buffer!=BufferUtil.EMPTY_BUFFER); - if (_pool!=null && isBufferEmpty) + boolean isTheEmptyBuffer = (buffer!=BufferUtil.EMPTY_BUFFER); + if (_pool!=null && isTheEmptyBuffer) _pool.release(buffer); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java index c13b6145892..22a499abc4e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java @@ -452,13 +452,15 @@ public class ResponseWriter extends PrintWriter } @Override - public PrintWriter format(Locale l, String format, Object... args) + public PrintWriter format(Locale locale, String format, Object... args) { try { - if(l==null) - l = _locale; + /* If the passed locale is null then + use any locale set on the response as the default. */ + if(locale == null) + locale = _locale; synchronized (lock) { @@ -466,20 +468,19 @@ public class ResponseWriter extends PrintWriter if(_formatter == null) { - _formatter = new Formatter(this, l); + _formatter = new Formatter(this, locale); } - else if(_formatter.locale() != null) + else if(_formatter.locale()==null) { - if(!_formatter.locale().equals(l)) - _formatter = new Formatter(this, l); - } - else + if(locale != null) + _formatter = new Formatter(this, locale); + } + else if (!_formatter.locale().equals(locale)) { - if(l != null) - _formatter = new Formatter(this, l); + _formatter = new Formatter(this, locale); } - _formatter.format(l, format, args); + _formatter.format(locale, format, args); } } catch (InterruptedIOException ex) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index 74d00b128fe..fd3f3212868 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -254,8 +254,8 @@ public class Fields implements Iterable public boolean equals(Field that, boolean caseSensitive) { @SuppressWarnings("ReferenceEquality") - boolean isCurrentObject = (this == that); - if (isCurrentObject) + boolean isThisInstance = (this == that); + if (isThisInstance) return true; if (that == null) return false; From 1373025dffa15b25153dd44702e31629bddfab91 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 5 Mar 2018 17:52:23 -0600 Subject: [PATCH 03/87] Issue #2282 - removing EventQueue from websocket tests --- .../jsr356/DecoderReaderManySmallTest.java | 11 +- .../websocket/jsr356/DecoderReaderTest.java | 21 +- .../jetty/websocket/jsr356/EncoderTest.java | 68 ++-- .../jsr356/endpoints/OnCloseTest.java | 8 +- .../jsr356/endpoints/TrackingSocket.java | 16 +- .../test/resources/jetty-logging.properties | 2 +- .../jsr356/server/AltFilterTest.java | 7 +- .../server/AnnotatedServerEndpointTest.java | 8 +- .../jsr356/server/BasicEndpointTest.java | 7 +- .../jsr356/server/ConfiguratorTest.java | 44 +- .../jsr356/server/EchoClientSocket.java | 14 - .../websocket/jsr356/server/EchoTest.java | 13 +- .../jsr356/server/IdleTimeoutTest.java | 14 +- .../jsr356/server/JettyEchoSocket.java | 13 +- .../jsr356/server/LargeAnnotatedTest.java | 7 +- .../jsr356/server/LargeContainerTest.java | 7 +- .../websocket/jsr356/server/PingPongTest.java | 37 +- .../websocket/jsr356/server/SessionTest.java | 6 +- .../jsr356/server/TrackingSocket.java | 16 +- .../samples/echo/EchoReturnEndpoint.java | 5 +- .../websocket/client/ClientCloseTest.java | 379 ++++++++++-------- .../jetty/websocket/client/CookieTest.java | 23 +- .../websocket/client/JettyTrackingSocket.java | 20 +- .../websocket/client/MaxMessageSocket.java | 6 +- .../websocket/client/ServerReadThread.java | 9 +- .../jetty/websocket/client/SessionTest.java | 55 ++- .../websocket/client/WebSocketClientTest.java | 101 +++-- .../test/resources/jetty-logging.properties | 1 + .../websocket/common/events/EventCapture.java | 9 +- .../message/TrackingInputStreamSocket.java | 6 +- .../common/message/TrackingSocket.java | 12 +- .../common/test/BlockheadClient.java | 9 +- .../test/BlockheadServerConnection.java | 139 ++----- .../jetty/websocket/common/test/Fuzzer.java | 14 +- .../common/test/IBlockheadClient.java | 4 +- .../test/IBlockheadServerConnection.java | 45 +-- .../common/test/IncomingFramesCapture.java | 6 +- .../jetty/websocket/common/test/Timeouts.java | 27 ++ .../test/resources/jetty-logging.properties | 1 + .../server/AnnotatedMaxMessageSizeTest.java | 12 +- .../jetty/websocket/server/ChromeTest.java | 8 +- .../server/DecoratorsLegacyTest.java | 7 +- .../websocket/server/DecoratorsTest.java | 7 +- .../jetty/websocket/server/FirefoxTest.java | 7 +- .../server/FragmentExtensionTest.java | 7 +- .../server/IdentityExtensionTest.java | 7 +- .../websocket/server/IdleTimeoutTest.java | 7 +- .../server/ManyConnectionsCleanupTest.java | 16 +- .../PerMessageDeflateExtensionTest.java | 4 +- .../websocket/server/SubProtocolTest.java | 7 +- .../websocket/server/SuspendResumeTest.java | 9 +- .../websocket/server/TooFastClientTest.java | 14 +- .../websocket/server/WebSocketCloseTest.java | 27 +- .../server/WebSocketOverSSLTest.java | 18 +- .../server/WebSocketServerSessionTest.java | 13 +- .../server/WebSocketServletRFCTest.java | 28 +- .../server/WebSocketUpgradeFilterTest.java | 25 +- .../server/helper/CaptureSocket.java | 9 +- .../misbehaving/MisbehavingClassTest.java | 16 +- 59 files changed, 713 insertions(+), 725 deletions(-) create mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java index 39dd9dd07ec..3402fb5b582 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java @@ -24,6 +24,7 @@ import java.io.Reader; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.websocket.ClientEndpoint; @@ -36,7 +37,6 @@ import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; @@ -44,6 +44,7 @@ import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -90,7 +91,7 @@ public class DecoderReaderManySmallTest @ClientEndpoint(decoders = { EventIdDecoder.class }) public static class EventIdSocket { - public EventQueue messageQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); private CountDownLatch closeLatch = new CountDownLatch(1); @OnClose @@ -102,7 +103,7 @@ public class DecoderReaderManySmallTest @OnMessage public void onMessage(EventId msg) { - messageQueue.add(msg); + messageQueue.offer(msg); } public void awaitClose() throws InterruptedException @@ -208,12 +209,12 @@ public class DecoderReaderManySmallTest idserver.writeSequentialIds(from,to); idserver.close(); int count = from - to; - ids.messageQueue.awaitEventCount(count,4,TimeUnit.SECONDS); ids.awaitClose(); // collect seen ids List seen = new ArrayList<>(); - for(EventId id: ids.messageQueue) + for(int i=0; i messageQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); private CountDownLatch closeLatch = new CountDownLatch(1); @OnClose @@ -139,7 +140,7 @@ public class DecoderReaderTest public synchronized void onMessage(Quotes msg) { Integer h=hashCode(); - messageQueue.add(msg); + messageQueue.offer(msg); System.out.printf("%x: Quotes from: %s%n",h,msg.author); for (String quote : msg.quotes) { @@ -259,7 +260,7 @@ public class DecoderReaderTest server.stop(); } - // TODO analyse and fix + // TODO analyse and fix @Ignore @Test public void testSingleQuotes() throws Exception @@ -270,15 +271,14 @@ public class DecoderReaderTest client.connectToServer(quoter,server.getWsUri()); qserver.awaitConnect(); qserver.writeQuotes("quotes-ben.txt"); - quoter.messageQueue.awaitEventCount(1,1000,TimeUnit.MILLISECONDS); qserver.close(); quoter.awaitClose(); - Quotes quotes = quoter.messageQueue.poll(); + Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Quotes Author",quotes.author,is("Benjamin Franklin")); Assert.assertThat("Quotes Count",quotes.quotes.size(),is(3)); } - // TODO analyse and fix + // TODO analyse and fix @Test @Ignore ("Quotes appear to be able to arrive in any order?") public void testTwoQuotes() throws Exception @@ -290,11 +290,12 @@ public class DecoderReaderTest qserver.awaitConnect(); qserver.writeQuotes("quotes-ben.txt"); qserver.writeQuotes("quotes-twain.txt"); - quoter.messageQueue.awaitEventCount(2,1000,TimeUnit.MILLISECONDS); qserver.close(); quoter.awaitClose(); - Quotes quotes = quoter.messageQueue.poll(); + Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Quotes Author",quotes.author,is("Benjamin Franklin")); Assert.assertThat("Quotes Count",quotes.quotes.size(),is(3)); + quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Quotes Author",quotes.author,is("Mark Twain")); } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java index e7eeb7edc80..d8ac993af07 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java @@ -26,8 +26,9 @@ import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; import javax.websocket.ClientEndpointConfig; import javax.websocket.ContainerProvider; @@ -39,7 +40,6 @@ import javax.websocket.MessageHandler; import javax.websocket.Session; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.component.LifeCycle; @@ -47,6 +47,7 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -55,9 +56,8 @@ import org.junit.Test; public class EncoderTest { - private static class EchoServer implements Runnable + private static class EchoServer { - private Thread thread; private BlockheadServer server; private IBlockheadServerConnection sconnection; private CountDownLatch connectLatch = new CountDownLatch(1); @@ -67,37 +67,32 @@ public class EncoderTest this.server = server; } - @Override - public void run() - { - try - { - sconnection = server.accept(); - sconnection.setSoTimeout(60000); - sconnection.upgrade(); - sconnection.startEcho(); - } - catch (Exception e) - { - LOG.warn(e); - } - finally - { - connectLatch.countDown(); - } - } - public void start() { - this.thread = new Thread(this,"EchoServer"); - this.thread.start(); + CompletableFuture.runAsync(() -> { + try + { + sconnection = server.accept(); + sconnection.setSoTimeout(10000); + sconnection.upgrade(); + sconnection.enableIncomingEcho(true); + sconnection.startReadThread(); + } + catch (Exception e) + { + LOG.warn(e); + } + finally + { + connectLatch.countDown(); + } + }); } public void stop() { if (this.sconnection != null) { - this.sconnection.stopEcho(); try { this.sconnection.close(); @@ -166,12 +161,12 @@ public class EncoderTest public static class QuotesSocket extends Endpoint implements MessageHandler.Whole { private Session session; - private EventQueue messageQueue = new EventQueue<>(); + private LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); @Override public void onMessage(String message) { - messageQueue.add(message); + messageQueue.offer(message); } @Override @@ -236,6 +231,7 @@ public class EncoderTest public void initClient() { client = ContainerProvider.getWebSocketContainer(); + client.setDefaultMaxSessionIdleTimeout(10000); } @After @@ -257,7 +253,7 @@ public class EncoderTest server.stop(); } - @Test + @Test(timeout = 10000) public void testSingleQuotes() throws Exception { EchoServer eserver = new EchoServer(server); @@ -277,9 +273,7 @@ public class EncoderTest Quotes ben = getQuotes("quotes-ben.txt"); quoter.write(ben); - quoter.messageQueue.awaitEventCount(1,1000,TimeUnit.MILLISECONDS); - - String result = quoter.messageQueue.poll(); + String result = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertReceivedQuotes(result,ben); } finally @@ -288,7 +282,7 @@ public class EncoderTest } } - @Test + @Test(timeout = 10000) public void testTwoQuotes() throws Exception { EchoServer eserver = new EchoServer(server); @@ -309,11 +303,9 @@ public class EncoderTest quoter.write(ben); quoter.write(twain); - quoter.messageQueue.awaitEventCount(2,1000,TimeUnit.MILLISECONDS); - - String result = quoter.messageQueue.poll(); + String result = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertReceivedQuotes(result,ben); - result = quoter.messageQueue.poll(); + result = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertReceivedQuotes(result,twain); } finally diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java index bfb37f34ed3..446871fbcb8 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/OnCloseTest.java @@ -23,15 +23,16 @@ import static org.hamcrest.Matchers.is; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; import javax.websocket.ClientEndpoint; import javax.websocket.ClientEndpointConfig; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.events.EventDriver; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.ClientContainer; import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner; import org.eclipse.jetty.websocket.jsr356.annotations.JsrEvents; @@ -118,9 +119,8 @@ public class OnCloseTest driver.onClose(new CloseInfo(StatusCode.NORMAL,"normal")); // Test captured event - EventQueue events = endpoint.eventQueue; - Assert.assertThat("Number of Events Captured",events.size(),is(1)); - String closeEvent = events.poll(); + LinkedBlockingQueue events = endpoint.eventQueue; + String closeEvent = events.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Close Event",closeEvent,is(testcase.expectedCloseEvent)); } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/TrackingSocket.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/TrackingSocket.java index 5cf017729e2..29db50c9989 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/TrackingSocket.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/endpoints/TrackingSocket.java @@ -23,12 +23,12 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.websocket.CloseReason; import javax.websocket.CloseReason.CloseCode; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.junit.Assert; @@ -41,8 +41,8 @@ public abstract class TrackingSocket private static final Logger LOG = Log.getLogger(TrackingSocket.class); public CloseReason closeReason; - public EventQueue eventQueue = new EventQueue(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue eventQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); public CountDownLatch dataLatch = new CountDownLatch(1); @@ -50,12 +50,12 @@ public abstract class TrackingSocket protected void addError(Throwable t) { LOG.warn(t); - errorQueue.add(t); + errorQueue.offer(t); } protected void addEvent(String format, Object... args) { - eventQueue.add(String.format(format,args)); + eventQueue.offer(String.format(format,args)); } public void assertClose(CloseCode expectedCode, String expectedReason) throws InterruptedException @@ -76,12 +76,6 @@ public abstract class TrackingSocket Assert.assertThat("Close Reason",closeReason.getReasonPhrase(),is(expectedReason)); } - public void assertEvent(String expected) - { - String actual = eventQueue.poll(); - Assert.assertEquals("Event",expected,actual); - } - public void assertIsOpen() throws InterruptedException { assertWasOpened(); diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/resources/jetty-logging.properties b/jetty-websocket/javax-websocket-client-impl/src/test/resources/jetty-logging.properties index 3acadb6cade..2b8dfa9b594 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/javax-websocket-client-impl/src/test/resources/jetty-logging.properties @@ -1,6 +1,6 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog org.eclipse.jetty.LEVEL=WARN -# org.eclipse.jetty.websocket.LEVEL=INFO +# org.eclipse.jetty.websocket.LEVEL=DEBUG # org.eclipse.jetty.websocket.LEVEL=ALL # org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AltFilterTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AltFilterTest.java index 9890e54f543..b8321115a29 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AltFilterTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AltFilterTest.java @@ -23,8 +23,8 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; import java.net.URI; -import java.util.Queue; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -34,6 +34,7 @@ import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.samples.echo.BasicEchoSocket; import org.junit.Assert; import org.junit.Rule; @@ -81,8 +82,8 @@ public class AltFilterTest // wait for connect future.get(1,TimeUnit.SECONDS); clientEcho.sendMessage("Hello Echo"); - Queue msgs = clientEcho.awaitMessages(1); - Assert.assertEquals("Expected message","Hello Echo",msgs.poll()); + LinkedBlockingQueue msgs = clientEcho.incomingMessages; + Assert.assertEquals("Expected message","Hello Echo",msgs.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT)); } finally { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointTest.java index ba959f6348f..607eb45d35b 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/AnnotatedServerEndpointTest.java @@ -22,8 +22,8 @@ import static org.hamcrest.Matchers.containsString; import java.io.File; import java.net.URI; -import java.util.Queue; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -33,6 +33,7 @@ import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.samples.beans.DateDecoder; import org.eclipse.jetty.websocket.jsr356.server.samples.beans.TimeEncoder; import org.eclipse.jetty.websocket.jsr356.server.samples.echo.ConfiguredEchoSocket; @@ -40,7 +41,6 @@ import org.eclipse.jetty.websocket.jsr356.server.samples.echo.EchoSocketConfigur import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; /** @@ -90,9 +90,9 @@ public class AnnotatedServerEndpointTest foo.get(1,TimeUnit.SECONDS); clientEcho.sendMessage(message); - Queue msgs = clientEcho.awaitMessages(1); + LinkedBlockingQueue msgs = clientEcho.incomingMessages; - String response = msgs.poll(); + String response = msgs.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); for (String expected : expectedTexts) { Assert.assertThat("Expected message",response,containsString(expected)); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/BasicEndpointTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/BasicEndpointTest.java index 35a26b2a368..ccd4f40c1aa 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/BasicEndpointTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/BasicEndpointTest.java @@ -19,8 +19,8 @@ package org.eclipse.jetty.websocket.jsr356.server; import java.net.URI; -import java.util.Queue; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -29,6 +29,7 @@ import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.samples.echo.BasicEchoEndpoint; import org.eclipse.jetty.websocket.jsr356.server.samples.echo.BasicEchoEndpointConfigContextListener; import org.junit.Assert; @@ -73,8 +74,8 @@ public class BasicEndpointTest // wait for connect future.get(1,TimeUnit.SECONDS); clientEcho.sendMessage("Hello World"); - Queue msgs = clientEcho.awaitMessages(1); - Assert.assertEquals("Expected message","Hello World",msgs.poll()); + LinkedBlockingQueue msgs = clientEcho.incomingMessages; + Assert.assertEquals("Expected message","Hello World",msgs.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT)); } finally { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java index a3c08093be1..9042d4f4a4b 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java @@ -35,7 +35,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -54,7 +54,6 @@ import javax.websocket.server.ServerEndpointConfig; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.util.QuoteUtil; @@ -63,6 +62,7 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.HttpResponse; import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.junit.AfterClass; import org.junit.Assert; @@ -437,8 +437,8 @@ public class ConfiguratorTest assertThat("response.extensions", response.getExtensionsHeader(), nullValue()); client.write(new TextFrame().setPayload("NegoExts")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("Frame Response", frame.getPayloadAsUTF8(), is("negotiatedExtensions=[]")); } } @@ -456,8 +456,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("X-Dummy")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Request Header [X-Dummy]: \"Bogus\"")); } } @@ -475,8 +475,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("apple")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = \"fruit from tree\"")); } @@ -489,8 +489,8 @@ public class ConfiguratorTest client.write(new TextFrame().setPayload("apple")); client.write(new TextFrame().setPayload("blueberry")); - EventQueue frames = client.readFrames(2, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); // should have no value Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = ")); @@ -515,8 +515,8 @@ public class ConfiguratorTest InetSocketAddress expectedRemote = client.getRemoteSocketAddress(); client.write(new TextFrame().setPayload("addr")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); StringWriter expected = new StringWriter(); PrintWriter out = new PrintWriter(expected); @@ -548,8 +548,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("getProtocols")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\"]")); } } @@ -572,8 +572,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("getProtocols")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } } @@ -596,8 +596,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("getProtocols")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } } @@ -620,8 +620,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("getProtocols")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } } @@ -642,8 +642,8 @@ public class ConfiguratorTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("2016-06-20T14:27:44")); - EventQueue frames = client.readFrames(1, 1, TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("cal=2016.06.20 AD at 14:27:44 +0000")); } } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoClientSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoClientSocket.java index 5c0b8929a68..519928c44ed 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoClientSocket.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoClientSocket.java @@ -20,8 +20,6 @@ package org.eclipse.jetty.websocket.jsr356.server; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import javax.websocket.ClientEndpoint; import javax.websocket.CloseReason; @@ -38,15 +36,9 @@ import org.eclipse.jetty.util.BufferUtil; @ClientEndpoint public class EchoClientSocket extends TrackingSocket { - public final CountDownLatch eventCountLatch; private Session session; private Basic remote; - public EchoClientSocket(int expectedEventCount) - { - this.eventCountLatch = new CountDownLatch(expectedEventCount); - } - public void close() throws IOException { if (session != null) @@ -88,12 +80,6 @@ public class EchoClientSocket extends TrackingSocket public void onText(String text) { addEvent(text); - eventCountLatch.countDown(); - } - - public boolean awaitAllEvents(long timeout, TimeUnit unit) throws InterruptedException - { - return eventCountLatch.await(timeout,unit); } public void sendObject(Object obj) throws IOException, EncodeException diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java index 5169c45a32a..b4b95d9c803 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java @@ -18,22 +18,23 @@ package org.eclipse.jetty.websocket.jsr356.server; -import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.EchoCase.PartialBinary; import org.eclipse.jetty.websocket.jsr356.server.EchoCase.PartialText; import org.eclipse.jetty.websocket.jsr356.server.samples.binary.ByteBufferSocket; @@ -255,7 +256,7 @@ public class EchoTest public void testEcho() throws Exception { int messageCount = testcase.getMessageCount(); - EchoClientSocket socket = new EchoClientSocket(messageCount); + EchoClientSocket socket = new EchoClientSocket(); URI toUri = serverUri.resolve(testcase.path.substring(1)); try @@ -284,13 +285,13 @@ public class EchoTest } // Collect Responses - socket.awaitAllEvents(1,TimeUnit.SECONDS); - EventQueue received = socket.eventQueue; + LinkedBlockingQueue received = socket.eventQueue; // Validate Responses for (String expected : testcase.expectedStrings) { - Assert.assertThat("Received Echo Responses",received,contains(expected)); + String actual = received.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Received Echo Responses",actual,containsString(expected)); } } finally diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/IdleTimeoutTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/IdleTimeoutTest.java index b24d799b02b..42e8583bf3c 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/IdleTimeoutTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/IdleTimeoutTest.java @@ -18,15 +18,14 @@ package org.eclipse.jetty.websocket.jsr356.server; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; import java.net.URI; -import java.util.Queue; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.log.Log; @@ -35,6 +34,7 @@ import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.annotations.JsrEvents; import org.eclipse.jetty.websocket.jsr356.server.samples.idletimeout.IdleTimeoutContextListener; import org.eclipse.jetty.websocket.jsr356.server.samples.idletimeout.OnOpenIdleTimeoutEndpoint; @@ -100,10 +100,12 @@ public class IdleTimeoutTest clientEcho.sendMessage("You shouldn't be there"); try { - Queue msgs = clientEcho.awaitMessages(1); - assertThat("Should not have received messages echoed back",msgs,is(empty())); + LinkedBlockingQueue msgs = clientEcho.incomingMessages; + // should not have a message. + String received = msgs.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Should not have received messages echoed back",received,is(nullValue())); } - catch (TimeoutException | InterruptedException e) + catch (InterruptedException e) { // valid success path } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyEchoSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyEchoSocket.java index b26e90e64bb..721be5fd487 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyEchoSocket.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/JettyEchoSocket.java @@ -19,13 +19,10 @@ package org.eclipse.jetty.websocket.jsr356.server; import java.io.IOException; -import java.util.Queue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.BatchMode; @@ -50,13 +47,7 @@ public class JettyEchoSocket private Session session; private Lock remoteLock = new ReentrantLock(); private RemoteEndpoint remote; - private EventQueue incomingMessages = new EventQueue<>(); - - public Queue awaitMessages(int expected) throws TimeoutException, InterruptedException - { - incomingMessages.awaitEventCount(expected,2,TimeUnit.SECONDS); - return incomingMessages; - } + public LinkedBlockingQueue incomingMessages = new LinkedBlockingQueue<>(); public boolean getClosed() { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeAnnotatedTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeAnnotatedTest.java index aeaff1a2605..f9ea5de8dfb 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeAnnotatedTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeAnnotatedTest.java @@ -21,8 +21,8 @@ package org.eclipse.jetty.websocket.jsr356.server; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.Queue; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -31,6 +31,7 @@ import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.samples.echo.LargeEchoConfiguredSocket; import org.junit.Assert; import org.junit.Ignore; @@ -78,8 +79,8 @@ public class LargeAnnotatedTest Arrays.fill(txt,(byte)'o'); String msg = new String(txt,StandardCharsets.UTF_8); clientEcho.sendMessage(msg); - Queue msgs = clientEcho.awaitMessages(1); - Assert.assertEquals("Expected message",msg,msgs.poll()); + LinkedBlockingQueue msgs = clientEcho.incomingMessages; + Assert.assertEquals("Expected message",msg,msgs.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT)); } finally { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeContainerTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeContainerTest.java index 304844cc18e..0bdf3f6a5a4 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeContainerTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/LargeContainerTest.java @@ -21,8 +21,8 @@ package org.eclipse.jetty.websocket.jsr356.server; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.Queue; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; @@ -31,6 +31,7 @@ import org.eclipse.jetty.toolchain.test.TestingDir; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.samples.echo.LargeEchoDefaultSocket; import org.junit.Assert; import org.junit.Ignore; @@ -78,8 +79,8 @@ public class LargeContainerTest Arrays.fill(txt,(byte)'o'); String msg = new String(txt,StandardCharsets.UTF_8); clientEcho.sendMessage(msg); - Queue msgs = clientEcho.awaitMessages(1); - Assert.assertEquals("Expected message",msg,msgs.poll()); + LinkedBlockingQueue msgs = clientEcho.incomingMessages; + Assert.assertEquals("Expected message",msg,msgs.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT)); } finally { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PingPongTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PingPongTest.java index 7f7ec875cd3..524afb8cd71 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PingPongTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/PingPongTest.java @@ -18,7 +18,6 @@ package org.eclipse.jetty.websocket.jsr356.server; -import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import java.io.File; @@ -28,9 +27,9 @@ import java.util.concurrent.TimeUnit; import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.samples.pong.PongContextListener; import org.eclipse.jetty.websocket.jsr356.server.samples.pong.PongMessageEndpoint; import org.eclipse.jetty.websocket.jsr356.server.samples.pong.PongSocket; @@ -78,7 +77,7 @@ public class PingPongTest @Test(timeout = 2000) public void testPingEndpoint() throws Exception { - EchoClientSocket socket = new EchoClientSocket(1); + EchoClientSocket socket = new EchoClientSocket(); URI toUri = serverUri.resolve("ping"); try @@ -91,12 +90,8 @@ public class PingPongTest String msg = "hello"; socket.sendPing(msg); - // Collect Responses - socket.awaitAllEvents(1,TimeUnit.SECONDS); - EventQueue received = socket.eventQueue; - // Validate Responses - String actual = received.poll(); + String actual = socket.eventQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Received Ping Response",actual,containsString("PongMessage[/ping]:" + msg)); } finally @@ -109,7 +104,7 @@ public class PingPongTest @Test(timeout = 2000) public void testPongEndpoint() throws Exception { - EchoClientSocket socket = new EchoClientSocket(1); + EchoClientSocket socket = new EchoClientSocket(); URI toUri = serverUri.resolve("pong"); try @@ -122,12 +117,9 @@ public class PingPongTest String msg = "hello"; socket.sendPong(msg); - // Collect Responses - socket.awaitAllEvents(1,TimeUnit.SECONDS); - EventQueue received = socket.eventQueue; - // Validate Responses - Assert.assertThat("Received Ping Responses",received,contains("PongMessage[/pong]:" + msg)); + String received = socket.eventQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Received Ping Responses",received,containsString("PongMessage[/pong]:" + msg)); } finally { @@ -139,7 +131,7 @@ public class PingPongTest @Test(timeout = 2000) public void testPingSocket() throws Exception { - EchoClientSocket socket = new EchoClientSocket(1); + EchoClientSocket socket = new EchoClientSocket(); URI toUri = serverUri.resolve("ping-socket"); try @@ -152,12 +144,8 @@ public class PingPongTest String msg = "hello"; socket.sendPing(msg); - // Collect Responses - socket.awaitAllEvents(1,TimeUnit.SECONDS); - EventQueue received = socket.eventQueue; - // Validate Responses - String actual = received.poll(); + String actual = socket.eventQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Received Ping Response",actual,containsString("@OnMessage(PongMessage)[/ping-socket]:" + msg)); } finally @@ -170,7 +158,7 @@ public class PingPongTest @Test(timeout = 2000) public void testPongSocket() throws Exception { - EchoClientSocket socket = new EchoClientSocket(1); + EchoClientSocket socket = new EchoClientSocket(); URI toUri = serverUri.resolve("pong-socket"); try @@ -183,12 +171,9 @@ public class PingPongTest String msg = "hello"; socket.sendPong(msg); - // Collect Responses - socket.awaitAllEvents(1,TimeUnit.SECONDS); - EventQueue received = socket.eventQueue; - // Validate Responses - Assert.assertThat("Received Ping Responses",received,contains("@OnMessage(PongMessage)[/pong-socket]:" + msg)); + String received = socket.eventQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Received Ping Responses",received,containsString("@OnMessage(PongMessage)[/pong-socket]:" + msg)); } finally { diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/SessionTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/SessionTest.java index f45338dc54a..57d81d14444 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/SessionTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/SessionTest.java @@ -30,8 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.webapp.WebAppContext; @@ -101,8 +99,6 @@ public class SessionTest return cases; } - public ByteBufferPool bufferPool = new MappedByteBufferPool(); - private final Case testcase; private final static AtomicInteger ID = new AtomicInteger(0); private WSServer server; @@ -136,7 +132,7 @@ public class SessionTest private void assertResponse(String requestPath, String requestMessage, String expectedResponse) throws Exception { - WebSocketClient client = new WebSocketClient(bufferPool); + WebSocketClient client = new WebSocketClient(); try { client.start(); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java index c9038199583..6343af16033 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/TrackingSocket.java @@ -23,12 +23,12 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.websocket.CloseReason; import javax.websocket.CloseReason.CloseCode; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.junit.Assert; @@ -41,8 +41,8 @@ public abstract class TrackingSocket private static final Logger LOG = Log.getLogger(TrackingSocket.class); public CloseReason closeReason; - public EventQueue eventQueue = new EventQueue(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue eventQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); public CountDownLatch dataLatch = new CountDownLatch(1); @@ -50,12 +50,12 @@ public abstract class TrackingSocket protected void addError(Throwable t) { LOG.warn(t); - errorQueue.add(t); + errorQueue.offer(t); } protected void addEvent(String format, Object... args) { - eventQueue.add(String.format(format,args)); + eventQueue.offer(String.format(format,args)); } public void assertClose(CloseCode expectedCode, String expectedReason) throws InterruptedException @@ -76,12 +76,6 @@ public abstract class TrackingSocket Assert.assertThat("Close Reason",closeReason.getReasonPhrase(),is(expectedReason)); } - public void assertEvent(String expected) - { - String actual = eventQueue.poll(); - Assert.assertEquals("Event",expected,actual); - } - public void assertIsOpen() throws InterruptedException { assertWasOpened(); diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/echo/EchoReturnEndpoint.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/echo/EchoReturnEndpoint.java index 37679cdcaab..1a3affc3880 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/echo/EchoReturnEndpoint.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/samples/echo/EchoReturnEndpoint.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.websocket.jsr356.server.samples.echo; import java.io.IOException; +import java.util.concurrent.LinkedBlockingQueue; import javax.websocket.CloseReason; import javax.websocket.OnMessage; @@ -26,14 +27,12 @@ import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; -import org.eclipse.jetty.toolchain.test.EventQueue; - @ServerEndpoint(value = "/echoreturn") public class EchoReturnEndpoint { private Session session = null; public CloseReason close = null; - public EventQueue messageQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); public void onClose(CloseReason close) { diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java index c90a8be9a28..2b7ffe5e1e8 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java @@ -37,6 +37,7 @@ import java.nio.channels.SocketChannel; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; @@ -50,7 +51,6 @@ import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SocketChannelEndPoint; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; @@ -70,8 +70,8 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; -import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture; import org.eclipse.jetty.websocket.common.test.RawFrameBuilder; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; @@ -94,7 +94,7 @@ public class ClientCloseTest public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch errorLatch = new CountDownLatch(1); - public EventQueue messageQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); public AtomicReference error = new AtomicReference<>(); public void assertNoCloseEvent() @@ -198,25 +198,22 @@ public class ClientCloseTest final String echoMsg = "echo-test"; Future testFut = clientSocket.getRemote().sendStringByFuture(echoMsg); + serverConns.startReadThread(); + // Wait for send future testFut.get(30,TimeUnit.SECONDS); // Read Frame on server side - IncomingFramesCapture serverCapture = serverConns.readFrames(1,30,TimeUnit.SECONDS); - serverCapture.assertNoErrors(); - serverCapture.assertFrameCount(1); - WebSocketFrame frame = serverCapture.getFrames().poll(); + LinkedBlockingQueue serverCapture = serverConns.getFrameQueue(); + WebSocketFrame frame = serverCapture.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("Server received frame",frame.getOpCode(),is(OpCode.TEXT)); assertThat("Server received frame payload",frame.getPayloadAsUTF8(),is(echoMsg)); // Server send echo reply serverConns.write(new TextFrame().setPayload(echoMsg)); - // Wait for received echo - clientSocket.messageQueue.awaitEventCount(1,1,TimeUnit.SECONDS); - // Verify received message - String recvMsg = clientSocket.messageQueue.poll(); + String recvMsg = clientSocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("Received message",recvMsg,is(echoMsg)); // Verify that there are no errors @@ -228,14 +225,11 @@ public class ClientCloseTest } } - private void confirmServerReceivedCloseFrame(IBlockheadServerConnection serverConn, int expectedCloseCode, Matcher closeReasonMatcher) throws IOException, - TimeoutException + private void confirmServerReceivedCloseFrame(IBlockheadServerConnection serverConn, int expectedCloseCode, Matcher closeReasonMatcher) throws InterruptedException { - IncomingFramesCapture serverCapture = serverConn.readFrames(1,30,TimeUnit.SECONDS); - serverCapture.assertNoErrors(); - serverCapture.assertFrameCount(1); - serverCapture.assertHasFrame(OpCode.CLOSE,1); - WebSocketFrame frame = serverCapture.getFrames().poll(); + LinkedBlockingQueue serverCapture = serverConn.getFrameQueue(); + WebSocketFrame frame = serverCapture.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Server close frame", frame, is(notNullValue())); assertThat("Server received close frame",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo closeInfo = new CloseInfo(frame); assertThat("Server received close code",closeInfo.getStatusCode(),is(expectedCloseCode)); @@ -316,7 +310,7 @@ public class ClientCloseTest public void testHalfClose() throws Exception { // Set client timeout - final int timeout = 1000; + final int timeout = 5000; client.setMaxIdleTimeout(timeout); // Client connects @@ -327,38 +321,42 @@ public class ClientCloseTest IBlockheadServerConnection serverConn = server.accept(); serverConn.upgrade(); - // client confirms connection via echo - confirmConnection(clientSocket,clientConnectFuture,serverConn); + try + { + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture, serverConn); - // client sends close frame (code 1000, normal) - final String origCloseReason = "Normal Close"; - clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason); + // client sends close frame (code 1000, normal) + final String origCloseReason = "Normal Close"; + clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); - // server receives close frame - confirmServerReceivedCloseFrame(serverConn,StatusCode.NORMAL,is(origCloseReason)); + // server receives close frame + confirmServerReceivedCloseFrame(serverConn, StatusCode.NORMAL, is(origCloseReason)); - // server sends 2 messages - serverConn.write(new TextFrame().setPayload("Hello")); - serverConn.write(new TextFrame().setPayload("World")); + // server sends 2 messages + serverConn.write(new TextFrame().setPayload("Hello")); + serverConn.write(new TextFrame().setPayload("World")); - // server sends close frame (code 1000, no reason) - CloseInfo sclose = new CloseInfo(StatusCode.NORMAL,"From Server"); - serverConn.write(sclose.asFrame()); + // server sends close frame (code 1000, no reason) + CloseInfo sclose = new CloseInfo(StatusCode.NORMAL, "From Server"); + serverConn.write(sclose.asFrame()); - // client receives 2 messages - clientSocket.messageQueue.awaitEventCount(2,1,TimeUnit.SECONDS); + // Verify received messages + String recvMsg = clientSocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Received message 1", recvMsg, is("Hello")); + recvMsg = clientSocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Received message 2", recvMsg, is("World")); - // Verify received messages - String recvMsg = clientSocket.messageQueue.poll(); - assertThat("Received message 1",recvMsg,is("Hello")); - recvMsg = clientSocket.messageQueue.poll(); - assertThat("Received message 2",recvMsg,is("World")); + // Verify that there are no errors + assertThat("Error events", clientSocket.error.get(), nullValue()); - // Verify that there are no errors - assertThat("Error events",clientSocket.error.get(),nullValue()); - - // client close event on ws-endpoint - clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.NORMAL),containsString("From Server")); + // client close event on ws-endpoint + clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.NORMAL), containsString("From Server")); + } + finally + { + serverConn.disconnect(); + } } @Ignore("Need sbordet's help here") @@ -377,35 +375,42 @@ public class ClientCloseTest IBlockheadServerConnection serverConn = server.accept(); serverConn.upgrade(); - // client confirms connection via echo - confirmConnection(clientSocket,clientConnectFuture,serverConn); - - // client sends BIG frames (until it cannot write anymore) - // server must not read (for test purpose, in order to congest connection) - // when write is congested, client enqueue close frame - // client initiate write, but write never completes - EndPoint endp = clientSocket.getEndPoint(); - assertThat("EndPoint is testable",endp,instanceOf(TestEndPoint.class)); - TestEndPoint testendp = (TestEndPoint)endp; - - char msg[] = new char[10240]; - int writeCount = 0; - long writeSize = 0; - int i = 0; - while (!testendp.congestedFlush.get()) + try { - int z = i - ((i / 26) * 26); - char c = (char)('a' + z); - Arrays.fill(msg,c); - clientSocket.getRemote().sendStringByFuture(String.valueOf(msg)); - writeCount++; - writeSize += msg.length; - } - LOG.info("Wrote {} frames totalling {} bytes of payload before congestion kicked in",writeCount,writeSize); + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture, serverConn); - // Verify timeout error - assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); - assertThat("OnError", clientSocket.error.get(), instanceOf(SocketTimeoutException.class)); + // client sends BIG frames (until it cannot write anymore) + // server must not read (for test purpose, in order to congest connection) + // when write is congested, client enqueue close frame + // client initiate write, but write never completes + EndPoint endp = clientSocket.getEndPoint(); + assertThat("EndPoint is testable", endp, instanceOf(TestEndPoint.class)); + TestEndPoint testendp = (TestEndPoint) endp; + + char msg[] = new char[10240]; + int writeCount = 0; + long writeSize = 0; + int i = 0; + while (!testendp.congestedFlush.get()) + { + int z = i - ((i / 26) * 26); + char c = (char) ('a' + z); + Arrays.fill(msg, c); + clientSocket.getRemote().sendStringByFuture(String.valueOf(msg)); + writeCount++; + writeSize += msg.length; + } + LOG.info("Wrote {} frames totalling {} bytes of payload before congestion kicked in", writeCount, writeSize); + + // Verify timeout error + assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat("OnError", clientSocket.error.get(), instanceOf(SocketTimeoutException.class)); + } + finally + { + serverConn.disconnect(); + } } @Test @@ -423,36 +428,41 @@ public class ClientCloseTest IBlockheadServerConnection serverConn = server.accept(); serverConn.upgrade(); - // client confirms connection via echo - confirmConnection(clientSocket,clientConnectFuture,serverConn); - - // client should not have received close message (yet) - clientSocket.assertNoCloseEvent(); - - // server sends bad close frame (too big of a reason message) - byte msg[] = new byte[400]; - Arrays.fill(msg,(byte)'x'); - ByteBuffer bad = ByteBuffer.allocate(500); - RawFrameBuilder.putOpFin(bad,OpCode.CLOSE,true); - RawFrameBuilder.putLength(bad,msg.length + 2,false); - bad.putShort((short)StatusCode.NORMAL); - bad.put(msg); - BufferUtil.flipToFlush(bad,0); - try (StacklessLogging quiet = new StacklessLogging(Parser.class)) + try { - serverConn.write(bad); + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture, serverConn); - // client should have noticed the error - assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); - assertThat("OnError", clientSocket.error.get(), instanceOf(ProtocolException.class)); - assertThat("OnError", clientSocket.error.get().getMessage(), containsString("Invalid control frame")); + // client should not have received close message (yet) + clientSocket.assertNoCloseEvent(); - // client parse invalid frame, notifies server of close (protocol error) - confirmServerReceivedCloseFrame(serverConn,StatusCode.PROTOCOL,allOf(containsString("Invalid control frame"),containsString("length"))); + // server sends bad close frame (too big of a reason message) + byte msg[] = new byte[400]; + Arrays.fill(msg, (byte) 'x'); + ByteBuffer bad = ByteBuffer.allocate(500); + RawFrameBuilder.putOpFin(bad, OpCode.CLOSE, true); + RawFrameBuilder.putLength(bad, msg.length + 2, false); + bad.putShort((short) StatusCode.NORMAL); + bad.put(msg); + BufferUtil.flipToFlush(bad, 0); + try (StacklessLogging quiet = new StacklessLogging(Parser.class)) + { + serverConn.write(bad); + + // client should have noticed the error + assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat("OnError", clientSocket.error.get(), instanceOf(ProtocolException.class)); + assertThat("OnError", clientSocket.error.get().getMessage(), containsString("Invalid control frame")); + + // client parse invalid frame, notifies server of close (protocol error) + confirmServerReceivedCloseFrame(serverConn, StatusCode.PROTOCOL, allOf(containsString("Invalid control frame"), containsString("length"))); + } + } + finally + { + // server disconnects + serverConn.disconnect(); } - - // server disconnects - serverConn.disconnect(); // client triggers close event on client ws-endpoint clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.PROTOCOL),allOf(containsString("Invalid control frame"),containsString("length"))); @@ -473,29 +483,36 @@ public class ClientCloseTest IBlockheadServerConnection serverConn = server.accept(); serverConn.upgrade(); - // client confirms connection via echo - confirmConnection(clientSocket,clientConnectFuture,serverConn); + try + { + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture, serverConn); - // client sends close frame - final String origCloseReason = "Normal Close"; - clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason); + // client sends close frame + final String origCloseReason = "Normal Close"; + clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); - // server receives close frame - confirmServerReceivedCloseFrame(serverConn,StatusCode.NORMAL,is(origCloseReason)); + // server receives close frame + confirmServerReceivedCloseFrame(serverConn, StatusCode.NORMAL, is(origCloseReason)); - // client should not have received close message (yet) - clientSocket.assertNoCloseEvent(); + // client should not have received close message (yet) + clientSocket.assertNoCloseEvent(); - // server shuts down connection (no frame reply) - serverConn.disconnect(); + // server shuts down connection (no frame reply) + serverConn.disconnect(); - // client reads -1 (EOF) - // client triggers close event on client ws-endpoint - clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.ABNORMAL), - anyOf( - containsString("EOF"), - containsString("Disconnected") - )); + // client reads -1 (EOF) + // client triggers close event on client ws-endpoint + clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.ABNORMAL), + anyOf( + containsString("EOF"), + containsString("Disconnected") + )); + } + finally + { + serverConn.disconnect(); + } } @Test @@ -513,25 +530,32 @@ public class ClientCloseTest IBlockheadServerConnection serverConn = server.accept(); serverConn.upgrade(); - // client confirms connection via echo - confirmConnection(clientSocket,clientConnectFuture,serverConn); + try + { + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture, serverConn); - // client sends close frame - final String origCloseReason = "Normal Close"; - clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason); + // client sends close frame + final String origCloseReason = "Normal Close"; + clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); - // server receives close frame - confirmServerReceivedCloseFrame(serverConn,StatusCode.NORMAL,is(origCloseReason)); + // server receives close frame + confirmServerReceivedCloseFrame(serverConn, StatusCode.NORMAL, is(origCloseReason)); - // client should not have received close message (yet) - clientSocket.assertNoCloseEvent(); + // client should not have received close message (yet) + clientSocket.assertNoCloseEvent(); - // server never sends close frame handshake - // server sits idle + // server never sends close frame handshake + // server sits idle - // client idle timeout triggers close event on client ws-endpoint - assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); - assertThat("OnError", clientSocket.error.get(), instanceOf(TimeoutException.class)); + // client idle timeout triggers close event on client ws-endpoint + assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat("OnError", clientSocket.error.get(), instanceOf(TimeoutException.class)); + } + finally + { + serverConn.disconnect(); + } } @Test(timeout = 5000L) @@ -545,35 +569,45 @@ public class ClientCloseTest CloseTrackingSocket clientSockets[] = new CloseTrackingSocket[clientCount]; IBlockheadServerConnection serverConns[] = new IBlockheadServerConnection[clientCount]; - // Connect Multiple Clients - for (int i = 0; i < clientCount; i++) + try { - // Client Request Upgrade - clientSockets[i] = new CloseTrackingSocket(); - Future clientConnectFuture = client.connect(clientSockets[i],server.getWsUri()); + // Connect Multiple Clients + for (int i = 0; i < clientCount; i++) + { + // Client Request Upgrade + clientSockets[i] = new CloseTrackingSocket(); + Future clientConnectFuture = client.connect(clientSockets[i], server.getWsUri()); - // Server accepts connection - serverConns[i] = server.accept(); - serverConns[i].upgrade(); + // Server accepts connection + serverConns[i] = server.accept(); + serverConns[i].upgrade(); - // client confirms connection via echo - confirmConnection(clientSockets[i],clientConnectFuture,serverConns[i]); + // client confirms connection via echo + confirmConnection(clientSockets[i], clientConnectFuture, serverConns[i]); + } + + // client lifecycle stop + client.stop(); + + // clients send close frames (code 1001, shutdown) + for (int i = 0; i < clientCount; i++) + { + // server receives close frame + confirmServerReceivedCloseFrame(serverConns[i], StatusCode.SHUTDOWN, containsString("Shutdown")); + } + + // clients disconnect + for (int i = 0; i < clientCount; i++) + { + clientSockets[i].assertReceivedCloseEvent(timeout, is(StatusCode.SHUTDOWN), containsString("Shutdown")); + } } - - // client lifecycle stop - client.stop(); - - // clients send close frames (code 1001, shutdown) - for (int i = 0; i < clientCount; i++) + finally { - // server receives close frame - confirmServerReceivedCloseFrame(serverConns[i],StatusCode.SHUTDOWN,containsString("Shutdown")); - } - - // clients disconnect - for (int i = 0; i < clientCount; i++) - { - clientSockets[i].assertReceivedCloseEvent(timeout,is(StatusCode.SHUTDOWN),containsString("Shutdown")); + for(IBlockheadServerConnection serverConn: serverConns) + { + serverConn.disconnect(); + } } } @@ -592,24 +626,31 @@ public class ClientCloseTest IBlockheadServerConnection serverConn = server.accept(); serverConn.upgrade(); - // client confirms connection via echo - confirmConnection(clientSocket,clientConnectFuture,serverConn); + try + { + // client confirms connection via echo + confirmConnection(clientSocket, clientConnectFuture, serverConn); - // setup client endpoint for write failure (test only) - EndPoint endp = clientSocket.getEndPoint(); - endp.shutdownOutput(); + // setup client endpoint for write failure (test only) + EndPoint endp = clientSocket.getEndPoint(); + endp.shutdownOutput(); - // client enqueue close frame - // client write failure - final String origCloseReason = "Normal Close"; - clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason); - - assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); - assertThat("OnError", clientSocket.error.get(), instanceOf(EofException.class)); + // client enqueue close frame + // client write failure + final String origCloseReason = "Normal Close"; + clientSocket.getSession().close(StatusCode.NORMAL, origCloseReason); - // client triggers close event on client ws-endpoint - // assert - close code==1006 (abnormal) - // assert - close reason message contains (write failure) - clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.ABNORMAL),containsString("EOF")); + assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat("OnError", clientSocket.error.get(), instanceOf(EofException.class)); + + // client triggers close event on client ws-endpoint + // assert - close code==1006 (abnormal) + // assert - close reason message contains (write failure) + clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.ABNORMAL), containsString("EOF")); + } + finally + { + serverConn.disconnect(); + } } } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java index 06ec0555587..18f827598d0 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.websocket.client; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -29,10 +28,9 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; @@ -42,6 +40,7 @@ import org.eclipse.jetty.websocket.api.util.QuoteUtil; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -53,8 +52,8 @@ public class CookieTest public static class CookieTrackingSocket extends WebSocketAdapter { - public EventQueue messageQueue = new EventQueue<>(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); private CountDownLatch openLatch = new CountDownLatch(1); @Override @@ -189,18 +188,8 @@ public class CookieTest clientConnectFuture.get(10,TimeUnit.SECONDS); clientSocket.awaitOpen(2,TimeUnit.SECONDS); - try - { - // Wait for client receipt of cookie frame via client websocket - clientSocket.messageQueue.awaitEventCount(1, 3, TimeUnit.SECONDS); - } - catch (TimeoutException e) - { - e.printStackTrace(System.err); - assertThat("Message Count", clientSocket.messageQueue.size(), is(1)); - } - - String cookies = clientSocket.messageQueue.poll(); + // Wait for client receipt of cookie frame via client websocket + String cookies = clientSocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); LOG.debug("Cookies seen at server: {}",cookies); // Server closes connection diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java index 4f32deedf7b..7a2162c1ee1 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java @@ -25,15 +25,14 @@ import static org.junit.Assert.assertThat; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Exchanger; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; -import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.junit.Assert; @@ -52,8 +51,8 @@ public class JettyTrackingSocket extends WebSocketAdapter public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); public CountDownLatch dataLatch = new CountDownLatch(1); - public EventQueue messageQueue = new EventQueue<>(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); public void assertClose(int expectedStatusCode, String expectedReason) throws InterruptedException { @@ -78,12 +77,6 @@ public class JettyTrackingSocket extends WebSocketAdapter assertNotClosed(); } - public void assertMessage(String expected) - { - String actual = messageQueue.poll(); - Assert.assertEquals("Message",expected,actual); - } - public void assertNotClosed() { LOG.debug("assertNotClosed() - {}", closeLatch.getCount()); @@ -102,11 +95,6 @@ public class JettyTrackingSocket extends WebSocketAdapter Assert.assertThat("Was Opened",openLatch.await(30,TimeUnit.SECONDS),is(true)); } - public void awaitMessage(int expectedMessageCount, TimeUnit timeoutUnit, int timeoutDuration) throws TimeoutException, InterruptedException - { - messageQueue.awaitEventCount(expectedMessageCount,timeoutDuration,timeoutUnit); - } - public void clear() { messageQueue.clear(); diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/MaxMessageSocket.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/MaxMessageSocket.java index 1fb0407666a..5e71a96933f 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/MaxMessageSocket.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/MaxMessageSocket.java @@ -21,9 +21,9 @@ package org.eclipse.jetty.websocket.client; import static org.hamcrest.Matchers.is; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; @@ -42,8 +42,8 @@ public class MaxMessageSocket public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); public CountDownLatch dataLatch = new CountDownLatch(1); - public EventQueue messageQueue = new EventQueue<>(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); public int closeCode = -1; public StringBuilder closeMessage = new StringBuilder(); 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 index a170ce9ffc5..82a3e3cbb70 100644 --- 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 @@ -18,12 +18,12 @@ package org.eclipse.jetty.websocket.client; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.is; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Queue; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -35,6 +35,7 @@ import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.Assert; public class ServerReadThread extends Thread @@ -89,9 +90,9 @@ public class ServerReadThread extends Thread conn.getParser().parse(buf); } - Queue frames = conn.getIncomingFrames().getFrames(); + LinkedBlockingQueue frames = conn.getFrameQueue(); WebSocketFrame frame; - while ((frame = frames.poll()) != null) + while ((frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT)) != null) { frameCount.incrementAndGet(); if (frame.getOpCode() == OpCode.CLOSE) diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java index 08aea0f82c7..ea6eef03f9c 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java @@ -18,7 +18,10 @@ package org.eclipse.jetty.websocket.client; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; import java.net.URI; import java.util.Collection; @@ -32,6 +35,7 @@ import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -74,18 +78,17 @@ public class SessionTest final IBlockheadServerConnection srvSock = server.accept(); srvSock.upgrade(); - - Session sess = future.get(30000,TimeUnit.MILLISECONDS); - Assert.assertThat("Session",sess,notNullValue()); - Assert.assertThat("Session.open",sess.isOpen(),is(true)); - Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + Session sess = future.get(30000, TimeUnit.MILLISECONDS); + Assert.assertThat("Session", sess, notNullValue()); + Assert.assertThat("Session.open", sess.isOpen(), is(true)); + Assert.assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); + Assert.assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); cliSock.assertWasOpened(); cliSock.assertNotClosed(); Collection sessions = client.getBeans(WebSocketSession.class); - Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); + Assert.assertThat("client.connectionManager.sessions.size", sessions.size(), is(1)); RemoteEndpoint remote = cliSock.getSession().getRemote(); remote.sendStringByFuture("Hello World!"); @@ -93,19 +96,31 @@ public class SessionTest { remote.flush(); } - srvSock.echoMessage(1,30000,TimeUnit.MILLISECONDS); - // wait for response from server - cliSock.waitForMessage(30000,TimeUnit.MILLISECONDS); - - Set open = client.getOpenSessions(); - Assert.assertThat("(Before Close) Open Sessions.size", open.size(), is(1)); - cliSock.assertMessage("Hello World!"); - cliSock.close(); - srvSock.close(); - - cliSock.waitForClose(30000,TimeUnit.MILLISECONDS); - open = client.getOpenSessions(); + try + { + srvSock.enableIncomingEcho(true); + srvSock.startReadThread(); + // wait for response from server + cliSock.waitForMessage(30000, TimeUnit.MILLISECONDS); + + Set open = client.getOpenSessions(); + Assert.assertThat("(Before Close) Open Sessions.size", open.size(), is(1)); + + String received = cliSock.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Message", received, containsString("Hello World!")); + + cliSock.close(); + srvSock.close(); + } + finally + { + srvSock.disconnect(); + } + + cliSock.waitForClose(30000, TimeUnit.MILLISECONDS); + Set open = client.getOpenSessions(); + // TODO this sometimes fails! Assert.assertThat("(After Close) Open Sessions.size", open.size(), is(0)); } 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 35b61ccad16..90fe11e4da5 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,10 +18,12 @@ package org.eclipse.jetty.websocket.client; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; import java.net.InetSocketAddress; import java.net.URI; @@ -43,6 +45,7 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.FutureWriteCallback; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -103,26 +106,36 @@ public class WebSocketClientTest srvSock.upgrade(); Session sess = future.get(30,TimeUnit.SECONDS); - Assert.assertThat("Session",sess,notNullValue()); - Assert.assertThat("Session.open",sess.isOpen(),is(true)); - Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + assertThat("Session",sess,notNullValue()); + assertThat("Session.open",sess.isOpen(),is(true)); + assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); + assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); cliSock.assertWasOpened(); cliSock.assertNotClosed(); Collection sessions = client.getOpenSessions(); - Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); + assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); RemoteEndpoint remote = cliSock.getSession().getRemote(); remote.sendStringByFuture("Hello World!"); if (remote.getBatchMode() == BatchMode.ON) remote.flush(); - srvSock.echoMessage(1,30,TimeUnit.SECONDS); - // wait for response from server - cliSock.waitForMessage(30,TimeUnit.SECONDS); - cliSock.assertMessage("Hello World!"); + try + { + srvSock.enableIncomingEcho(true); + srvSock.startReadThread(); + + // wait for response from server + String received = cliSock.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Message", received, containsString("Hello World")); + } + finally + { + srvSock.close(); + srvSock.disconnect(); + } } @Test @@ -140,16 +153,16 @@ public class WebSocketClientTest srvSock.upgrade(); Session sess = future.get(30,TimeUnit.SECONDS); - Assert.assertThat("Session",sess,notNullValue()); - Assert.assertThat("Session.open",sess.isOpen(),is(true)); - Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + assertThat("Session",sess,notNullValue()); + assertThat("Session.open",sess.isOpen(),is(true)); + assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); + assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); cliSock.assertWasOpened(); cliSock.assertNotClosed(); Collection sessions = client.getBeans(WebSocketSession.class); - Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); + assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); FutureWriteCallback callback = new FutureWriteCallback(); @@ -169,10 +182,10 @@ public class WebSocketClientTest // Validate connect Session sess = future.get(30,TimeUnit.SECONDS); - Assert.assertThat("Session",sess,notNullValue()); - Assert.assertThat("Session.open",sess.isOpen(),is(true)); - Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + assertThat("Session",sess,notNullValue()); + assertThat("Session.open",sess.isOpen(),is(true)); + assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); + assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); // Have server send initial message srvSock.write(new TextFrame().setPayload("Hello World")); @@ -180,9 +193,9 @@ public class WebSocketClientTest // Verify connect future.get(30,TimeUnit.SECONDS); wsocket.assertWasOpened(); - wsocket.awaitMessage(1,TimeUnit.SECONDS,2); - wsocket.assertMessage("Hello World"); + String received = wsocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Message", received, containsString("Hello World")); } @Test @@ -203,15 +216,15 @@ public class WebSocketClientTest InetSocketAddress local = wsocket.getSession().getLocalAddress(); InetSocketAddress remote = wsocket.getSession().getRemoteAddress(); - Assert.assertThat("Local Socket Address",local,notNullValue()); - Assert.assertThat("Remote Socket Address",remote,notNullValue()); + assertThat("Local Socket Address",local,notNullValue()); + assertThat("Remote Socket Address",remote,notNullValue()); // Hard to validate (in a portable unit test) the local address that was used/bound in the low level Jetty Endpoint - Assert.assertThat("Local Socket Address / Host",local.getAddress().getHostAddress(),notNullValue()); - Assert.assertThat("Local Socket Address / Port",local.getPort(),greaterThan(0)); + assertThat("Local Socket Address / Host",local.getAddress().getHostAddress(),notNullValue()); + assertThat("Local Socket Address / Port",local.getPort(),greaterThan(0)); - Assert.assertThat("Remote Socket Address / Host",remote.getAddress().getHostAddress(),is(wsUri.getHost())); - Assert.assertThat("Remote Socket Address / Port",remote.getPort(),greaterThan(0)); + assertThat("Remote Socket Address / Host",remote.getAddress().getHostAddress(),is(wsUri.getHost())); + assertThat("Remote Socket Address / Port",remote.getPort(),greaterThan(0)); } @Test @@ -265,8 +278,8 @@ public class WebSocketClientTest wsocket.awaitConnect(1,TimeUnit.SECONDS); Session sess = future.get(30,TimeUnit.SECONDS); - Assert.assertThat("Session",sess,notNullValue()); - Assert.assertThat("Session.open",sess.isOpen(),is(true)); + assertThat("Session",sess,notNullValue()); + assertThat("Session.open",sess.isOpen(),is(true)); // Create string that is larger than default size of 64k // but smaller than maxMessageSize of 100k @@ -275,13 +288,23 @@ public class WebSocketClientTest String msg = StringUtil.toUTF8String(buf,0,buf.length); wsocket.getSession().getRemote().sendStringByFuture(msg); - ssocket.echoMessage(1,2,TimeUnit.SECONDS); - // wait for response from server - wsocket.waitForMessage(1,TimeUnit.SECONDS); + try + { + ssocket.enableIncomingEcho(true); + ssocket.startReadThread(); - wsocket.assertMessage(msg); + // wait for response from server + wsocket.waitForMessage(1, TimeUnit.SECONDS); - Assert.assertTrue(wsocket.dataLatch.await(2,TimeUnit.SECONDS)); + wsocket.assertMessage(msg); + + Assert.assertTrue(wsocket.dataLatch.await(2, TimeUnit.SECONDS)); + } + finally + { + ssocket.close(); + ssocket.disconnect(); + } } @Test @@ -301,15 +324,15 @@ public class WebSocketClientTest Session session = wsocket.getSession(); UpgradeRequest req = session.getUpgradeRequest(); - Assert.assertThat("Upgrade Request",req,notNullValue()); + assertThat("Upgrade Request",req,notNullValue()); Map> parameterMap = req.getParameterMap(); - Assert.assertThat("Parameter Map",parameterMap,notNullValue()); + assertThat("Parameter Map",parameterMap,notNullValue()); - Assert.assertThat("Parameter[snack]",parameterMap.get("snack"),is(Arrays.asList(new String[] { "cashews" }))); - Assert.assertThat("Parameter[amount]",parameterMap.get("amount"),is(Arrays.asList(new String[] { "handful" }))); - Assert.assertThat("Parameter[brand]",parameterMap.get("brand"),is(Arrays.asList(new String[] { "off" }))); + assertThat("Parameter[snack]",parameterMap.get("snack"),is(Arrays.asList(new String[] { "cashews" }))); + assertThat("Parameter[amount]",parameterMap.get("amount"),is(Arrays.asList(new String[] { "handful" }))); + assertThat("Parameter[brand]",parameterMap.get("brand"),is(Arrays.asList(new String[] { "off" }))); - Assert.assertThat("Parameter[cost]",parameterMap.get("cost"),nullValue()); + assertThat("Parameter[cost]",parameterMap.get("cost"),nullValue()); } } 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 880f5fcf070..35d2326510d 100644 --- a/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties @@ -10,6 +10,7 @@ org.eclipse.jetty.LEVEL=WARN # org.eclipse.jetty.websocket.client.ClientCloseTest.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.io.IOState.LEVEL=DEBUG +# org.eclipse.jetty.websocket.common.test.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.Generator.LEVEL=DEBUG # org.eclipse.jetty.websocket.common.Parser.LEVEL=DEBUG diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java index 85bb4543898..8a140fafd8f 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java @@ -22,15 +22,19 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; +import java.util.concurrent.LinkedBlockingQueue; import java.util.regex.Pattern; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.junit.Assert; +/** + * @deprecated should refactor away. + */ @SuppressWarnings("serial") -public class EventCapture extends EventQueue +@Deprecated +public class EventCapture extends LinkedBlockingQueue { private static final Logger LOG = Log.getLogger(EventCapture.class); @@ -74,6 +78,7 @@ public class EventCapture extends EventQueue public Assertable pop() { + // TODO: poll should have timeout. return new Assertable(super.poll()); } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingInputStreamSocket.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingInputStreamSocket.java index 97f75704824..9730a0f0b9c 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingInputStreamSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingInputStreamSocket.java @@ -23,9 +23,9 @@ import static org.hamcrest.Matchers.is; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -43,8 +43,8 @@ public class TrackingInputStreamSocket public int closeCode = -1; public StringBuilder closeMessage = new StringBuilder(); public CountDownLatch closeLatch = new CountDownLatch(1); - public EventQueue messageQueue = new EventQueue<>(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); public TrackingInputStreamSocket() { diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingSocket.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingSocket.java index 40a2db3ba36..bd52cf5e01e 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/TrackingSocket.java @@ -22,10 +22,9 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; @@ -45,8 +44,8 @@ public class TrackingSocket extends WebSocketAdapter public CountDownLatch openLatch = new CountDownLatch(1); public CountDownLatch closeLatch = new CountDownLatch(1); public CountDownLatch dataLatch = new CountDownLatch(1); - public EventQueue messageQueue = new EventQueue<>(); - public EventQueue errorQueue = new EventQueue<>(); + public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errorQueue = new LinkedBlockingQueue<>(); public TrackingSocket() { @@ -102,11 +101,6 @@ public class TrackingSocket extends WebSocketAdapter Assert.assertThat("Was Opened",openLatch.await(30,TimeUnit.SECONDS),is(true)); } - public void awaitMessage(int expectedMessageCount, TimeUnit timeoutUnit, int timeoutDuration) throws TimeoutException, InterruptedException - { - messageQueue.awaitEventCount(expectedMessageCount,timeoutDuration,timeoutUnit); - } - public void clear() { messageQueue.clear(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java index 889379c9da1..e7bca7d02af 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java @@ -41,13 +41,13 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.net.ssl.HttpsURLConnection; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.StringUtil; @@ -96,8 +96,8 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, public long totalReadOps = 0; public long totalParseOps = 0; - public EventQueue frames = new EventQueue<>(); - public EventQueue errors = new EventQueue<>(); + public LinkedBlockingQueue frames = new LinkedBlockingQueue<>(); + public LinkedBlockingQueue errors = new LinkedBlockingQueue<>(); @Override public void run() @@ -630,9 +630,8 @@ public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, } @Override - public EventQueue readFrames(int expectedFrameCount, int timeoutDuration, TimeUnit timeoutUnit) throws Exception + public LinkedBlockingQueue getFrameQueue() { - frameReader.frames.awaitEventCount(expectedFrameCount,timeoutDuration,timeoutUnit); return frameReader.frames; } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java index 026df3cdf10..6ab10df9091 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java @@ -18,7 +18,8 @@ package org.eclipse.jetty.websocket.common.test; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import java.io.BufferedReader; import java.io.IOException; @@ -32,8 +33,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; @@ -50,9 +51,9 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.WriteCallback; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.eclipse.jetty.websocket.api.extensions.Frame; +import org.eclipse.jetty.websocket.api.extensions.Frame.Type; import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; -import org.eclipse.jetty.websocket.api.extensions.Frame.Type; import org.eclipse.jetty.websocket.common.AcceptHash; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.Generator; @@ -73,13 +74,15 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames private final Socket socket; private final ByteBufferPool bufferPool; private final WebSocketPolicy policy; - private final IncomingFramesCapture incomingFrames; + private final LinkedBlockingQueue incomingFrames = new LinkedBlockingQueue<>(); + private final LinkedBlockingQueue incomingErrors = new LinkedBlockingQueue<>(); private final Parser parser; private final Generator generator; private final AtomicInteger parseCount; private final WebSocketExtensionFactory extensionRegistry; private final AtomicBoolean echoing = new AtomicBoolean(false); - private Thread echoThread; + private final AtomicBoolean reading = new AtomicBoolean(false); + private Thread readThread; /** Set to true to disable timeouts (for debugging reasons) */ private boolean debug = false; @@ -92,7 +95,6 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames public BlockheadServerConnection(Socket socket) { this.socket = socket; - this.incomingFrames = new IncomingFramesCapture(); this.policy = WebSocketPolicy.newServerPolicy(); this.policy.setMaxBinaryMessageSize(100000); this.policy.setMaxTextMessageSize(100000); @@ -140,6 +142,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames public void disconnect() { LOG.debug("disconnect"); + reading.set(false); IO.close(in); IO.close(out); if (socket != null) @@ -154,19 +157,6 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames } } } - - @Override - public void echoMessage(int expectedFrames, int timeoutDuration, TimeUnit timeoutUnit) throws IOException, TimeoutException - { - LOG.debug("Echo Frames [expecting {}]",expectedFrames); - IncomingFramesCapture cap = readFrames(expectedFrames,timeoutDuration,timeoutUnit); - // now echo them back. - for (Frame frame : cap.getFrames()) - { - write(WebSocketFrame.copy(frame).setMasked(false)); - } - } - @Override public void flush() throws IOException { @@ -179,12 +169,6 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames return bufferPool; } - @Override - public IncomingFramesCapture getIncomingFrames() - { - return incomingFrames; - } - public InputStream getInputStream() throws IOException { if (in == null) @@ -217,19 +201,19 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames @Override public void incomingError(Throwable e) { - incomingFrames.incomingError(e); + incomingErrors.offer(e); } @Override public void incomingFrame(Frame frame) { - LOG.debug("incoming({})",frame); + LOG.debug("incomingFrame({})",frame); int count = parseCount.incrementAndGet(); if ((count % 10) == 0) { LOG.info("Server parsed {} frames",count); } - incomingFrames.incomingFrame(WebSocketFrame.copy(frame)); + incomingFrames.offer(WebSocketFrame.copy(frame)); if (frame.getOpCode() == OpCode.CLOSE) { @@ -238,6 +222,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames } Type type = frame.getType(); + if (echoing.get() && (type.isData() || type.isContinuation())) { try @@ -329,52 +314,8 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames } @Override - public IncomingFramesCapture readFrames(int expectedCount, int timeoutDuration, TimeUnit timeoutUnit) throws IOException, TimeoutException + public LinkedBlockingQueue getFrameQueue() { - LOG.debug("Read: waiting for {} frame(s) from client",expectedCount); - int startCount = incomingFrames.size(); - - ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE,false); - BufferUtil.clearToFill(buf); - try - { - long msDur = TimeUnit.MILLISECONDS.convert(timeoutDuration,timeoutUnit); - long now = System.currentTimeMillis(); - long expireOn = now + msDur; - LOG.debug("Now: {} - expireOn: {} ({} ms)",now,expireOn,msDur); - - int len = 0; - while (incomingFrames.size() < (startCount + expectedCount)) - { - BufferUtil.clearToFill(buf); - len = read(buf); - if (len > 0) - { - LOG.debug("Read {} bytes",len); - BufferUtil.flipToFlush(buf,0); - parser.parse(buf); - } - try - { - TimeUnit.MILLISECONDS.sleep(20); - } - catch (InterruptedException gnore) - { - /* ignore */ - } - if (!debug && (System.currentTimeMillis() > expireOn)) - { - incomingFrames.dump(); - throw new TimeoutException(String.format("Timeout reading all %d expected frames. (managed to only read %d frame(s))",expectedCount, - incomingFrames.size())); - } - } - } - finally - { - bufferPool.release(buf); - } - return incomingFrames; } @@ -457,20 +398,19 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames { LOG.debug("Entering echo thread"); - ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE,false); - BufferUtil.clearToFill(buf); - long readBytes = 0; - try + long totalReadBytes = 0; + ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE, false); + while(reading.get()) { - while (echoing.get()) + try { BufferUtil.clearToFill(buf); long len = read(buf); if (len > 0) { - readBytes += len; - LOG.debug("Read {} bytes",len); - BufferUtil.flipToFlush(buf,0); + totalReadBytes += len; + LOG.debug("Read {} bytes", len); + BufferUtil.flipToFlush(buf, 0); parser.parse(buf); } @@ -483,16 +423,18 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames /* ignore */ } } + catch (IOException e) + { + LOG.debug("Exception during echo loop", e); + } + catch (Throwable t) + { + LOG.warn("Exception during echo loop", t); + } } - catch (IOException e) - { - LOG.debug("Exception during echo loop",e); - } - finally - { - LOG.debug("Read {} bytes",readBytes); - bufferPool.release(buf); - } + + LOG.debug("Read {} total bytes (exiting)",totalReadBytes); + bufferPool.release(buf); } @Override @@ -502,21 +444,22 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames } @Override - public void startEcho() + public void startReadThread() { - if (echoThread != null) + if (readThread != null) { - throw new IllegalStateException("Echo thread already declared!"); + throw new IllegalStateException("Read thread already declared/started!"); } - echoThread = new Thread(this,"BlockheadServer/Echo"); - echoing.set(true); - echoThread.start(); + readThread = new Thread(this,"BlockheadServer/Read"); + LOG.debug("Starting Read Thread: {}", readThread); + reading.set(true); + readThread.start(); } @Override - public void stopEcho() + public void enableIncomingEcho(boolean enabled) { - echoing.set(false); + echoing.set(enabled); } @Override diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java index af932f72ce2..87c74d437e4 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java @@ -27,9 +27,9 @@ import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -146,19 +146,27 @@ public class Fuzzer implements AutoCloseable expect(expect,10,TimeUnit.SECONDS); } + /** + * Read the response frames and validate them against the expected frame list + * + * @param expect the list of expected frames + * @param duration the timeout duration to wait for each read frame + * @param unit the timeout unit to wait for each read frame + * @throws Exception if unable to validate expectations + */ public void expect(List expect, int duration, TimeUnit unit) throws Exception { int expectedCount = expect.size(); LOG.debug("expect() {} frame(s)",expect.size()); // Read frames - EventQueue frames = client.readFrames(expect.size(),duration,unit); + LinkedBlockingQueue frames = client.getFrameQueue(); String prefix = ""; for (int i = 0; i < expectedCount; i++) { WebSocketFrame expected = expect.get(i); - WebSocketFrame actual = frames.poll(); + WebSocketFrame actual = frames.poll(duration,unit); prefix = "Frame[" + i + "]"; diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadClient.java index a2321ba6429..743e718fda1 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadClient.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadClient.java @@ -21,9 +21,9 @@ package org.eclipse.jetty.websocket.common.test; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.common.WebSocketFrame; /** @@ -56,7 +56,7 @@ public interface IBlockheadClient extends AutoCloseable public InetSocketAddress getRemoteSocketAddress(); - public EventQueue readFrames(int expectedFrameCount, int timeoutDuration, TimeUnit timeoutUnit) throws Exception; + public LinkedBlockingQueue getFrameQueue(); public HttpResponse readResponseHeader() throws IOException; diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java index 9c799171db6..d5dceebd266 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java @@ -22,47 +22,46 @@ import java.io.IOException; import java.net.SocketException; import java.nio.ByteBuffer; import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.Parser; +import org.eclipse.jetty.websocket.common.WebSocketFrame; public interface IBlockheadServerConnection { public void close() throws IOException; - public void close(int statusCode) throws IOException; - - public void write(Frame frame) throws IOException; - - public List upgrade() throws IOException; - public void disconnect(); - public IncomingFramesCapture readFrames(int expectedCount, int timeoutDuration, TimeUnit timeoutUnit) throws IOException, TimeoutException; + public void write(Frame frame) throws IOException; public void write(ByteBuffer buf) throws IOException; + public void write(int b) throws IOException; + public void flush() throws IOException; + + public LinkedBlockingQueue getFrameQueue(); + + public void enableIncomingEcho(boolean enabled); + public void startReadThread(); + + public String readRequest() throws IOException; public List readRequestLines() throws IOException; public String parseWebSocketKey(List requestLines); - public void respond(String rawstr) throws IOException; - public String readRequest() throws IOException; - public List regexFind(List lines, String pattern); - public void echoMessage(int expectedFrames, int timeoutDuration, TimeUnit timeoutUnit) throws IOException, TimeoutException; - public void setSoTimeout(int ms) throws SocketException; - public ByteBufferPool getBufferPool(); - public int read(ByteBuffer buf) throws IOException; - public Parser getParser(); - public IncomingFramesCapture getIncomingFrames(); - public void flush() throws IOException; - public void write(int b) throws IOException; - public void startEcho(); - public void stopEcho(); - /** * Add an extra header for the upgrade response (from the server). No extra work is done to ensure the key and value are sane for http. * @param rawkey the raw key * @param rawvalue the raw value */ public void addResponseHeader(String rawkey, String rawvalue); + public List upgrade() throws IOException; + public void setSoTimeout(int ms) throws SocketException; + + public void respond(String rawstr) throws IOException; + public List regexFind(List lines, String pattern); + public ByteBufferPool getBufferPool(); + public Parser getParser(); + + @Deprecated + public int read(ByteBuffer buf) throws IOException; } \ No newline at end of file diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IncomingFramesCapture.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IncomingFramesCapture.java index ed01e8597ff..e9835591cce 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IncomingFramesCapture.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IncomingFramesCapture.java @@ -22,8 +22,8 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -37,8 +37,8 @@ import org.junit.Assert; public class IncomingFramesCapture implements IncomingFrames { private static final Logger LOG = Log.getLogger(IncomingFramesCapture.class); - private EventQueue frames = new EventQueue<>(); - private EventQueue errors = new EventQueue<>(); + private LinkedBlockingQueue frames = new LinkedBlockingQueue<>(); + private LinkedBlockingQueue errors = new LinkedBlockingQueue<>(); public void assertErrorCount(int expectedCount) { diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java new file mode 100644 index 00000000000..fa3321e2f18 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.common.test; + +import java.util.concurrent.TimeUnit; + +public class Timeouts +{ + public static long POLL_EVENT = 2; + public static TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS; +} diff --git a/jetty-websocket/websocket-common/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-common/src/test/resources/jetty-logging.properties index 683b76a631f..525226380f0 100644 --- a/jetty-websocket/websocket-common/src/test/resources/jetty-logging.properties +++ b/jetty-websocket/websocket-common/src/test/resources/jetty-logging.properties @@ -1,6 +1,7 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog org.eclipse.jetty.LEVEL=WARN # org.eclipse.jetty.websocket.LEVEL=DEBUG +# org.eclipse.jetty.websocket.common.test.LEVEL=DEBUG # org.eclipse.jetty.websocket.protocol.Parser.LEVEL=DEBUG # org.eclipse.jetty.websocket.protocol.LEVEL=DEBUG # org.eclipse.jetty.websocket.io.payload.LEVEL=DEBUG diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java index 240d10755b9..f24fa3465db 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java @@ -24,11 +24,10 @@ import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; import java.util.Arrays; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; @@ -38,6 +37,7 @@ import org.eclipse.jetty.websocket.common.Parser; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.echo.BigEchoSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; @@ -105,8 +105,8 @@ public class AnnotatedMaxMessageSizeTest client.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } finally @@ -133,8 +133,8 @@ public class AnnotatedMaxMessageSizeTest client.write(new TextFrame().setPayload(ByteBuffer.wrap(buf))); // Read frame (hopefully close frame saying its too large) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame is close", tf.getOpCode(), is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(tf); Assert.assertThat("Close Code", close.getStatusCode(), is(StatusCode.MESSAGE_TOO_LARGE)); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java index f16a5bd3b5d..aa3437c9255 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java @@ -21,13 +21,13 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -73,8 +73,8 @@ public class ChromeTest client.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } finally diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java index 4dbcd08a4cf..8dbf77587a3 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java @@ -24,18 +24,19 @@ import static org.junit.Assert.assertThat; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.servlet.ServletContext; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.Decorator; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; @@ -167,8 +168,8 @@ public class DecoratorsLegacyTest client.write(new TextFrame().setPayload("info")); - EventQueue frames = client.readFrames(1,1,TimeUnit.SECONDS); - WebSocketFrame resp = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String textMsg = resp.getPayloadAsUTF8(); assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory")); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java index 8734a3d9ef6..3753d360e56 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java @@ -24,18 +24,19 @@ import static org.junit.Assert.assertThat; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import javax.servlet.ServletContext; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.DecoratedObjectFactory; import org.eclipse.jetty.util.Decorator; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; @@ -165,8 +166,8 @@ public class DecoratorsTest client.write(new TextFrame().setPayload("info")); - EventQueue frames = client.readFrames(1,1,TimeUnit.SECONDS); - WebSocketFrame resp = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String textMsg = resp.getPayloadAsUTF8(); assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory")); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java index 2a0950a9a95..bebbf78aa14 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java @@ -18,11 +18,10 @@ package org.eclipse.jetty.websocket.server; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.is; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; @@ -66,7 +65,7 @@ public class FirefoxTest client.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(1, 30, TimeUnit.SECONDS); + LinkedBlockingQueue frames = client.getFrameQueue(); WebSocketFrame tf = frames.poll(); Assert.assertThat("Text Frame.status code", tf.getPayloadAsUTF8(), is(msg)); } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java index 45d12c59f8b..de089f26845 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java @@ -21,13 +21,14 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -89,10 +90,10 @@ public class FragmentExtensionTest client.write(new TextFrame().setPayload(msg)); String parts[] = split(msg,fragSize); - EventQueue frames = client.readFrames(parts.length,1000,TimeUnit.MILLISECONDS); + LinkedBlockingQueue frames = client.getFrameQueue(); for (int i = 0; i < parts.length; i++) { - WebSocketFrame frame = frames.poll(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i])); } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java index 62e15d6746a..49c4b268553 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java @@ -21,13 +21,14 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -72,8 +73,8 @@ public class IdentityExtensionTest client.write(new TextFrame().setPayload("Hello")); - EventQueue frames = client.readFrames(1,1000,TimeUnit.MILLISECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello")); } finally diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java index a6c95950171..9174d1e8ab0 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java @@ -21,15 +21,16 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; @@ -94,8 +95,8 @@ public class IdleTimeoutTest client.write(new TextFrame().setPayload("Hello")); // Expect server to have closed due to its own timeout - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("frame opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); Assert.assertThat("close code",close.getStatusCode(),is(StatusCode.SHUTDOWN)); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java index bf33a79746e..0e819ec7d68 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java @@ -25,10 +25,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StacklessLogging; @@ -43,6 +43,7 @@ import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -272,21 +273,21 @@ public class ManyConnectionsCleanupTest client.write(new TextFrame().setPayload("calls")); client.write(new TextFrame().setPayload("openSessions")); - EventQueue frames = client.readFrames(3,6,TimeUnit.SECONDS); + LinkedBlockingQueue frames = client.getFrameQueue(); WebSocketFrame frame; String resp; - frame = frames.poll(); + frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.TEXT)); resp = frame.getPayloadAsUTF8(); assertThat("Should only have 1 open session",resp,containsString("calls=" + ((iterationCount * 2) + 1))); - frame = frames.poll(); + frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[1].opcode",frame.getOpCode(),is(OpCode.TEXT)); resp = frame.getPayloadAsUTF8(); assertThat("Should only have 1 open session",resp,containsString("openSessions.size=1\n")); - frame = frames.poll(); + frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[2].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); @@ -310,8 +311,9 @@ public class ManyConnectionsCleanupTest client.connect(); client.sendStandardRequest(); client.expectUpgradeResponse(); - - client.readFrames(1,1,TimeUnit.SECONDS); + + LinkedBlockingQueue frames = client.getFrameQueue(); + frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java index 5f908648e54..ee689e47ea1 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.common.util.Sha1Sum; import org.eclipse.jetty.websocket.server.helper.CaptureSocket; import org.eclipse.jetty.websocket.server.helper.EchoServlet; @@ -166,8 +167,7 @@ public class PerMessageDeflateExtensionTest // Client sends first message session.getRemote().sendBytes(ByteBuffer.wrap(msg)); - clientSocket.messages.awaitEventCount(1,5,TimeUnit.SECONDS); - String echoMsg = clientSocket.messages.poll(); + String echoMsg = clientSocket.messages.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Echo'd Message",echoMsg,is("binary[sha1="+sha1+"]")); } finally diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java index 36b141047dc..3beb3869427 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java @@ -21,9 +21,9 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; @@ -31,6 +31,7 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; @@ -129,8 +130,8 @@ public class SubProtocolTest client.expectUpgradeResponse(); client.write(new TextFrame().setPayload("showme")); - EventQueue frames = client.readFrames(1, 30, TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(ProtocolEchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("acceptedSubprotocol=" + acceptedSubProtocols)); } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java index 1fe8fa3716b..09f2cd2c5a3 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java @@ -21,9 +21,9 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.SuspendToken; import org.eclipse.jetty.websocket.api.WriteCallback; @@ -33,6 +33,7 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; @@ -128,10 +129,10 @@ public class SuspendResumeTest client.write(new TextFrame().setPayload("echo1")); client.write(new TextFrame().setPayload("echo2")); - EventQueue frames = client.readFrames(2, 30, TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(EchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("echo1")); - tf = frames.poll(); + tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(EchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("echo2")); } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java index 01e453799fa..bf2de13101e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java @@ -23,17 +23,17 @@ import static org.hamcrest.Matchers.is; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.jetty.io.LeakTrackingByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.common.Generator; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -108,10 +108,10 @@ public class TooFastClientTest client.expectUpgradeResponse(); // Read frames (hopefully text frames) - EventQueue frames = client.readFrames(2,1,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(msg1)); - tf = frames.poll(); + tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg2",tf.getPayloadAsUTF8(),is(msg2)); } finally @@ -167,9 +167,9 @@ public class TooFastClientTest client.expectUpgradeResponse(); // Read frames (hopefully text frames) - EventQueue frames = client.readFrames(1,1,TimeUnit.SECONDS); + LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame tf = frames.poll(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(bigMsg)); } finally diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java index 95f47383b9c..5ead761e174 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java @@ -26,9 +26,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StacklessLogging; @@ -42,6 +42,7 @@ import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -231,8 +232,8 @@ public class WebSocketCloseTest client.expectUpgradeResponse(); // Verify that client got close frame - EventQueue frames = client.readFrames(1,5,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); @@ -265,8 +266,8 @@ public class WebSocketCloseTest client.sendStandardRequest(); client.expectUpgradeResponse(); - EventQueue frames = client.readFrames(1,5,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); @@ -306,14 +307,14 @@ public class WebSocketCloseTest text.setPayload("openSessions"); client.write(text); - EventQueue frames = client.readFrames(2,1,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.TEXT)); String resp = frame.getPayloadAsUTF8(); assertThat("Should only have 1 open session",resp,containsString("openSessions.size=1\n")); - frame = frames.poll(); + frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[1].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); @@ -338,8 +339,9 @@ public class WebSocketCloseTest client.connect(); client.sendStandardRequest(); client.expectUpgradeResponse(); - - client.readFrames(1,1,TimeUnit.SECONDS); + + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); @@ -365,8 +367,9 @@ public class WebSocketCloseTest client.connect(); client.sendStandardRequest(); client.expectUpgradeResponse(); - - client.readFrames(1,1,TimeUnit.SECONDS); + + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); client.write(close.asFrame()); // respond with close diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java index e8ef9b3cb60..623a14f78b0 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java @@ -22,16 +22,17 @@ import static org.hamcrest.Matchers.is; import java.net.URI; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.CaptureSocket; import org.eclipse.jetty.websocket.server.helper.SessionServlet; import org.junit.AfterClass; @@ -94,9 +95,8 @@ public class WebSocketOverSSLTest remote.flush(); // Read frame (hopefully text frame) - clientSocket.messages.awaitEventCount(1,30,TimeUnit.SECONDS); - EventQueue captured = clientSocket.messages; - Assert.assertThat("Text Message",captured.poll(),is(msg)); + LinkedBlockingQueue captured = clientSocket.messages; + Assert.assertThat("Text Message",captured.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT),is(msg)); // Shutdown the socket clientSocket.close(); @@ -136,9 +136,8 @@ public class WebSocketOverSSLTest remote.flush(); // Read frame (hopefully text frame) - clientSocket.messages.awaitEventCount(1,30,TimeUnit.SECONDS); - EventQueue captured = clientSocket.messages; - Assert.assertThat("Server.session.isSecure",captured.poll(),is("session.isSecure=true")); + LinkedBlockingQueue captured = clientSocket.messages; + Assert.assertThat("Server.session.isSecure",captured.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT),is("session.isSecure=true")); // Shutdown the socket clientSocket.close(); @@ -178,10 +177,9 @@ public class WebSocketOverSSLTest remote.flush(); // Read frame (hopefully text frame) - clientSocket.messages.awaitEventCount(1,30,TimeUnit.SECONDS); - EventQueue captured = clientSocket.messages; + LinkedBlockingQueue captured = clientSocket.messages; String expected = String.format("session.upgradeRequest.requestURI=%s",requestUri.toASCIIString()); - Assert.assertThat("session.upgradeRequest.requestURI",captured.poll(),is(expected)); + Assert.assertThat("session.upgradeRequest.requestURI",captured.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT),is(expected)); // Shutdown the socket clientSocket.close(); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java index c278ed6b83a..ad5c2144fb5 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java @@ -21,14 +21,15 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import java.net.URI; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.SessionServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -90,14 +91,14 @@ public class WebSocketServerSessionTest client.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(4,5,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Parameter Map[snack]", tf.getPayloadAsUTF8(), is("[cashews]")); - tf = frames.poll(); + tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Parameter Map[amount]", tf.getPayloadAsUTF8(), is("[handful]")); - tf = frames.poll(); + tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Parameter Map[brand]", tf.getPayloadAsUTF8(), is("[off]")); - tf = frames.poll(); + tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Parameter Map[cost]", tf.getPayloadAsUTF8(), is("")); } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java index b3f6eb29044..994128476a2 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java @@ -22,10 +22,9 @@ import static org.hamcrest.Matchers.is; import java.nio.ByteBuffer; import java.util.Arrays; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception; import org.eclipse.jetty.util.Utf8StringBuilder; import org.eclipse.jetty.util.log.StacklessLogging; @@ -42,6 +41,7 @@ import org.eclipse.jetty.websocket.common.frames.BinaryFrame; import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.common.test.UnitGenerator; import org.eclipse.jetty.websocket.common.util.Hex; import org.eclipse.jetty.websocket.server.helper.RFCServlet; @@ -124,8 +124,8 @@ public class WebSocketServletRFCTest client.write(bin); // write buf3 (fin=true) // Read frame echo'd back (hopefully a single binary frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - Frame binmsg = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + Frame binmsg = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); int expectedSize = buf1.length + buf2.length + buf3.length; Assert.assertThat("BinaryFrame.payloadLength",binmsg.getPayloadLength(),is(expectedSize)); @@ -191,8 +191,8 @@ public class WebSocketServletRFCTest client.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } finally @@ -222,8 +222,8 @@ public class WebSocketServletRFCTest client.write(new TextFrame().setPayload("CRASH")); // Read frame (hopefully close frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - Frame cf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + Frame cf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); CloseInfo close = new CloseInfo(cf); Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); } @@ -263,8 +263,8 @@ public class WebSocketServletRFCTest client.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } finally @@ -293,8 +293,8 @@ public class WebSocketServletRFCTest client.writeRaw(bbHeader); client.writeRaw(txt.getPayload()); - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); Assert.assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.BAD_PAYLOAD)); @@ -334,8 +334,8 @@ public class WebSocketServletRFCTest client.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - EventQueue frames = client.readFrames(1,30,TimeUnit.SECONDS); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } finally diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java index 1fd592843fb..784aa8609ae 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java @@ -27,7 +27,7 @@ import java.net.URI; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.DispatcherType; @@ -36,12 +36,12 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; import org.junit.Ignore; import org.junit.Test; @@ -314,8 +314,9 @@ public class WebSocketUpgradeFilterTest client.write(new TextFrame().setPayload("hello")); - EventQueue frames = client.readFrames(1, 1000, TimeUnit.MILLISECONDS); - String payload = frames.poll().getPayloadAsUTF8(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + String payload = received.getPayloadAsUTF8(); // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too @@ -336,9 +337,11 @@ public class WebSocketUpgradeFilterTest client.write(new TextFrame().setPayload("hello 1")); - EventQueue frames = client.readFrames(1, 1000, TimeUnit.MILLISECONDS); - String payload = frames.poll().getPayloadAsUTF8(); - + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + String payload = received.getPayloadAsUTF8(); + + // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); @@ -355,9 +358,11 @@ public class WebSocketUpgradeFilterTest client.write(new TextFrame().setPayload("hello 2")); - EventQueue frames = client.readFrames(1, 1000, TimeUnit.MILLISECONDS); - String payload = frames.poll().getPayloadAsUTF8(); - + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + String payload = received.getPayloadAsUTF8(); + + // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/CaptureSocket.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/CaptureSocket.java index 554000e0a92..7715f9ed539 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/CaptureSocket.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/helper/CaptureSocket.java @@ -20,9 +20,9 @@ package org.eclipse.jetty.websocket.server.helper; import java.security.NoSuchAlgorithmException; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.util.Sha1Sum; @@ -30,12 +30,7 @@ import org.eclipse.jetty.websocket.common.util.Sha1Sum; public class CaptureSocket extends WebSocketAdapter { private final CountDownLatch latch = new CountDownLatch(1); - public EventQueue messages; - - public CaptureSocket() - { - messages = new EventQueue(); - } + public LinkedBlockingQueue messages = new LinkedBlockingQueue<>(); public boolean awaitConnected(long timeout) throws InterruptedException { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java index 57da5b71e77..bc5db0c678c 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java @@ -21,9 +21,10 @@ package org.eclipse.jetty.websocket.server.misbehaving; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; + +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.EventQueue; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -32,15 +33,12 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.test.BlockheadClient; import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.SimpleServletServer; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - /** * Testing badly behaving Socket class implementations to get the best * error messages and state out of the websocket implementation. @@ -80,8 +78,8 @@ public class MisbehavingClassTest client.sendStandardRequest(); client.expectUpgradeResponse(); - EventQueue frames = client.readFrames(1,1,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); @@ -115,8 +113,8 @@ public class MisbehavingClassTest client.sendStandardRequest(); client.expectUpgradeResponse(); - EventQueue frames = client.readFrames(1,1,TimeUnit.SECONDS); - WebSocketFrame frame = frames.poll(); + LinkedBlockingQueue frames = client.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); From 020ebde77cb0a9cf4d943933c7fc2e213069c3ab Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 6 Mar 2018 14:28:11 +1100 Subject: [PATCH 04/87] found additional ReferenceEquality warnings which have been resolved Signed-off-by: Lachlan Roberts --- .../org/eclipse/jetty/client/HttpContent.java | 17 +++++++++++++++-- .../org/eclipse/jetty/client/HttpRequest.java | 5 ++++- .../jetty/client/http/HttpSenderOverHTTP.java | 4 ++-- .../client/HttpClientAuthenticationTest.java | 1 + .../jetty/deploy/DeploymentManager.java | 5 ++++- .../org/eclipse/jetty/deploy/graph/Edge.java | 18 +++++++++++++++++- .../org/eclipse/jetty/deploy/graph/Graph.java | 10 ++++++---- .../deploy/jmx/DeploymentManagerMBean.java | 2 +- .../client/http/HttpConnectionOverFCGI.java | 4 +++- .../eclipse/jetty/http/GZIPContentDecoder.java | 4 ++-- .../org/eclipse/jetty/http/HttpParserTest.java | 1 + .../jetty/http2/hpack/HpackContextTest.java | 1 + .../jetty/io/ArrayByteBufferPoolTest.java | 2 ++ .../jetty/rewrite/handler/ValidUrlRule.java | 2 +- .../eclipse/jetty/server/ResponseWriter.java | 5 ----- .../org/eclipse/jetty/servlets/DoSFilter.java | 6 +++--- .../org/eclipse/jetty/servlets/QoSFilter.java | 4 ++-- .../java/org/eclipse/jetty/start/Modules.java | 6 +++--- .../org/eclipse/jetty/util/BufferUtil.java | 11 +++++++++++ .../java/org/eclipse/jetty/util/Fields.java | 5 ++--- .../jetty/util/resource/FileResource.java | 5 ++--- .../org/eclipse/jetty/util/BufferUtilTest.java | 1 + .../org/eclipse/jetty/util/DateCacheTest.java | 1 + .../org/eclipse/jetty/util/StringUtilTest.java | 6 +++++- .../jetty/util/TopologicalSortTest.java | 1 + .../common/message/MessageInputStream.java | 9 ++++++++- ...actSessionInvalidateCreateScavengeTest.java | 1 + 27 files changed, 100 insertions(+), 37 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java index 544bbadc23f..66b24cc677d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java @@ -81,6 +81,18 @@ public class HttpContent implements Callback, Closeable this.iterator = provider == null ? Collections.emptyIterator() : provider.iterator(); } + /** + * + * @param buffer + * @return whether the input buffer has been closed + */ + private static boolean isBufferClosed(ByteBuffer buffer) + { + @SuppressWarnings("ReferenceEquality") + boolean bufferClosed = (buffer == CLOSE); + return bufferClosed; + } + /** * @return whether there is any content at all */ @@ -177,6 +189,7 @@ public class HttpContent implements Callback, Closeable /** * @return whether the cursor has been advanced past the {@link #isLast() last} position. */ + @SuppressWarnings("ReferenceEquality") public boolean isConsumed() { return buffer == AFTER; @@ -187,7 +200,7 @@ public class HttpContent implements Callback, Closeable { if (isConsumed()) return; - if (buffer == CLOSE) + if (isBufferClosed(buffer)) return; if (iterator instanceof Callback) ((Callback)iterator).succeeded(); @@ -198,7 +211,7 @@ public class HttpContent implements Callback, Closeable { if (isConsumed()) return; - if (buffer == CLOSE) + if (isBufferClosed(buffer)) return; if (iterator instanceof Callback) ((Callback)iterator).failed(x); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java index be229cda4c9..7ae3fbb56d2 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java @@ -204,7 +204,10 @@ public class HttpRequest implements Request { if (uri == null) uri = buildURI(true); - return uri == NULL_URI ? null : uri; + + @SuppressWarnings("ReferenceEquality") + boolean isNullURI = (uri == NULL_URI); + return isNullURI ? null : uri; } @Override diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java index e80163c81b8..003d685f9c6 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpSenderOverHTTP.java @@ -321,10 +321,10 @@ public class HttpSenderOverHTTP extends HttpSender private void release() { ByteBufferPool bufferPool = httpClient.getByteBufferPool(); - if (headerBuffer != BufferUtil.EMPTY_BUFFER) + if (!BufferUtil.isTheEmptyBuffer(headerBuffer)) bufferPool.release(headerBuffer); headerBuffer = null; - if (chunkBuffer != BufferUtil.EMPTY_BUFFER) + if (!BufferUtil.isTheEmptyBuffer(chunkBuffer)) bufferPool.release(chunkBuffer); chunkBuffer = null; contentBuffer = null; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java index 96fd6cc27ec..3dd0d4a1c99 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java @@ -589,6 +589,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest public ByteBuffer current; @Override + @SuppressWarnings("ReferenceEquality") public boolean hasNext() { if (current == null) diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java index 5ace6c65ef6..48648c606c0 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -311,10 +312,12 @@ public class DeploymentManager extends ContainerLifeCycle */ public Collection getApps(Node node) { + Objects.requireNonNull(node); + List ret = new ArrayList<>(); for (AppEntry entry : _apps) { - if (entry.lifecyleNode == node) + if (node.equals(entry.lifecyleNode)) { ret.add(entry.app); } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java index 024e25c5a26..af792eedd66 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java @@ -28,7 +28,9 @@ public final class Edge public Edge(Node from, Node to) { - if (from==null || to==null || from==to) + @SuppressWarnings("ReferenceEquality") + boolean sameObject = (from==to); + if (from==null || to==null || sameObject) throw new IllegalArgumentException("from "+from+" to "+to); _from = from; _to = to; @@ -71,12 +73,26 @@ public final class Edge { return _from; } + + public boolean isFromNode(Node node) + { + @SuppressWarnings("ReferenceEquality") + boolean isFromNode_ = (_from == node); + return isFromNode_; + } public Node getTo() { return _to; } + public boolean isToNode(Node node) + { + @SuppressWarnings("ReferenceEquality") + boolean isToNode_ = (_to == node); + return isToNode_; + } + @Override public String toString() { diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java index c0aba65f542..b05064f7add 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java @@ -40,7 +40,7 @@ public class Graph addNode(toNode=edge.getTo()); // replace edge with normalized edge - if (edge.getFrom()!=fromNode || edge.getTo()!=toNode) + if (!edge.isFromNode(fromNode) || !edge.isToNode(toNode)) edge=new Edge(fromNode,toNode); this._edges.add(edge); @@ -129,7 +129,7 @@ public class Graph for (Edge edge : this._edges) { - if ((edge.getFrom() == node) || (edge.getTo() == node)) + if (edge.isFromNode(node) || edge.isToNode(node)) { fromedges.add(edge); } @@ -151,7 +151,7 @@ public class Graph for (Edge edge : this._edges) { - if (edge.getFrom() == from) + if (edge.isFromNode(from)) { fromedges.add(edge); } @@ -192,7 +192,9 @@ public class Graph */ public Path getPath(Node from, Node to) { - if (from == to) + @SuppressWarnings("ReferenceEquality") + boolean sameObject = (from==to); + if (sameObject) { return new Path(); } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java index 3c0ea08de81..165d10a122a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java @@ -74,7 +74,7 @@ public class DeploymentManagerMBean extends ObjectMBean List ret = new ArrayList<>(); for (DeploymentManager.AppEntry entry : _manager.getAppEntries()) { - if (entry.getLifecyleNode() == node) + if (node.equals(entry.getLifecyleNode())) { ret.add(toRef(entry.getApp())); } diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java index 1ff27d3583d..d72762f2d63 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java @@ -127,7 +127,9 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec private void releaseBuffer(ByteBuffer buffer) { - assert this.buffer == buffer; + @SuppressWarnings("ReferenceEquality") + boolean isCurrentBuffer = (this.buffer == buffer); + assert(isCurrentBuffer); HttpClient client = destination.getHttpClient(); ByteBufferPool bufferPool = client.getByteBufferPool(); bufferPool.release(buffer); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java index c4ce22f2013..e3e0401fbee 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java @@ -418,8 +418,8 @@ public class GZIPContentDecoder implements Destroyable public void release(ByteBuffer buffer) { @SuppressWarnings("ReferenceEquality") - boolean isTheEmptyBuffer = (buffer!=BufferUtil.EMPTY_BUFFER); - if (_pool!=null && isTheEmptyBuffer) + boolean isTheEmptyBuffer = (buffer==BufferUtil.EMPTY_BUFFER); + if (_pool!=null && !isTheEmptyBuffer) _pool.release(buffer); } } diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index 174ac6da23e..98e1f9a9044 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -2025,6 +2025,7 @@ public class HttpParserTest Assert.assertEquals(null, _bad); } @Test + @SuppressWarnings("ReferenceEquality") public void testCachedField() throws Exception { ByteBuffer buffer = BufferUtil.toBuffer( diff --git a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java index 0afca53f3cc..8af7b0e11e5 100644 --- a/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java +++ b/jetty-http2/http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java @@ -131,6 +131,7 @@ public class HpackContextTest assertNull(ctx.get("name")); } @Test + @SuppressWarnings("ReferenceEquality") public void testGetAddStatic() { HpackContext ctx = new HpackContext(4096); 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 index 7b2dd9f2cfd..fef7a562023 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java @@ -29,6 +29,7 @@ import java.util.Arrays; import org.eclipse.jetty.io.ByteBufferPool.Bucket; import org.junit.Test; +@SuppressWarnings("ReferenceEquality") public class ArrayByteBufferPoolTest { @Test @@ -113,6 +114,7 @@ public class ArrayByteBufferPoolTest } @Test + @SuppressWarnings("ReferenceEquality") public void testAcquireReleaseAcquire() throws Exception { ArrayByteBufferPool bufferPool = new ArrayByteBufferPool(10,100,1000); diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java index 45d6ba438ce..4cb856b9457 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ValidUrlRule.java @@ -115,7 +115,7 @@ public class ValidUrlRule extends Rule LOG.debug("{} {} {} {}", Character.charCount(codepoint), codepoint, block, Character.isISOControl(codepoint)); - return (!Character.isISOControl(codepoint)) && block != null && block != Character.UnicodeBlock.SPECIALS; + return (!Character.isISOControl(codepoint)) && block != null && !Character.UnicodeBlock.SPECIALS.equals(block); } public String toString() diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java index 22a499abc4e..47103e6257c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResponseWriter.java @@ -470,11 +470,6 @@ public class ResponseWriter extends PrintWriter { _formatter = new Formatter(this, locale); } - else if(_formatter.locale()==null) - { - if(locale != null) - _formatter = new Formatter(this, locale); - } else if (!_formatter.locale().equals(locale)) { _formatter = new Formatter(this, locale); diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java index 684b9677ce5..70e2bbe1653 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java @@ -381,7 +381,7 @@ public class DoSFilter implements Filter // or if we were woken up we insist or we fail. Boolean throttled = (Boolean)request.getAttribute(__THROTTLED); long throttleMs = getThrottleMs(); - if (throttled != Boolean.TRUE && throttleMs > 0) + if (Boolean.FALSE.equals(throttled) && throttleMs > 0) { int priority = getPriority(request, tracker); request.setAttribute(__THROTTLED, Boolean.TRUE); @@ -399,7 +399,7 @@ public class DoSFilter implements Filter } Boolean resumed = (Boolean)request.getAttribute(_resumed); - if (resumed == Boolean.TRUE) + if (Boolean.TRUE.equals(resumed)) { // We were resumed, we wait for the next pass. _passes.acquire(); @@ -444,7 +444,7 @@ public class DoSFilter implements Filter { ServletRequest candidate = asyncContext.getRequest(); Boolean suspended = (Boolean)candidate.getAttribute(_suspended); - if (suspended == Boolean.TRUE) + if (Boolean.TRUE.equals(suspended)) { if (LOG.isDebugEnabled()) LOG.debug("Resuming {}", request); diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java index bf6a80f749c..cf46bf686ac 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java @@ -171,7 +171,7 @@ public class QoSFilter implements Filter { request.setAttribute(_suspended, Boolean.FALSE); Boolean resumed = (Boolean)request.getAttribute(_resumed); - if (resumed == Boolean.TRUE) + if (Boolean.TRUE.equals(resumed)) { _passes.acquire(); accepted = true; @@ -222,7 +222,7 @@ public class QoSFilter implements Filter { ServletRequest candidate = asyncContext.getRequest(); Boolean suspended = (Boolean)candidate.getAttribute(_suspended); - if (suspended == Boolean.TRUE) + if (Boolean.TRUE.equals(suspended)) { candidate.setAttribute(_resumed, Boolean.TRUE); asyncContext.dispatch(); diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java index 0879311d473..69bcad311d9 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java @@ -305,7 +305,7 @@ public class Modules implements Iterable { for (Module p:providers) { - if (p!=module && p.isEnabled()) + if (!p.equals(module) && p.isEnabled()) { // If the already enabled module is transitive and this enable is not if (p.isTransitive() && !transitive) @@ -364,8 +364,8 @@ public class Modules implements Iterable } // If a provider is already enabled, then add a transitive enable - if (providers.stream().filter(Module::isEnabled).count()!=0) - providers.stream().filter(m->m.isEnabled()&&m!=module).forEach(m->enable(newlyEnabled,m,"transitive provider of "+dependsOn+" for "+module.getName(),true)); + if (providers.stream().filter(Module::isEnabled).count()>0) + providers.stream().filter(m->m.isEnabled()&&!m.equals(module)).forEach(m->enable(newlyEnabled,m,"transitive provider of "+dependsOn+" for "+module.getName(),true)); else { // Is there an obvious default? diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java index cba8dac91bc..a35cbb43881 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java @@ -238,6 +238,17 @@ public class BufferUtil } } + /** + * @param buf the buffer to check + * @return true if buf is equal to EMPTY_BUFFER + */ + public static boolean isTheEmptyBuffer(ByteBuffer buf) + { + @SuppressWarnings("ReferenceEquality") + boolean isTheEmptyBuffer_ = (buf == EMPTY_BUFFER); + return isTheEmptyBuffer_; + } + /* ------------------------------------------------------------ */ /** Check for an empty or null buffer. * @param buf the buffer to check diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index fd3f3212868..23b8e0713d3 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -251,11 +251,10 @@ public class Fields implements Iterable this.values = Collections.unmodifiableList(list); } + @SuppressWarnings("ReferenceEquality") public boolean equals(Field that, boolean caseSensitive) { - @SuppressWarnings("ReferenceEquality") - boolean isThisInstance = (this == that); - if (isThisInstance) + if (this == that) return true; if (that == null) return false; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java index 296dd6a8dfe..33d73c73657 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java @@ -407,6 +407,7 @@ public class FileResource extends Resource * @return true of the object o is a {@link FileResource} pointing to the same file as this resource. */ @Override + @SuppressWarnings("ReferenceEquality") public boolean equals( Object o) { if (this == o) @@ -416,9 +417,7 @@ public class FileResource extends Resource return false; FileResource f=(FileResource)o; - @SuppressWarnings("ReferenceEquality") - boolean sameFile = f._file==_file; - return sameFile || (null != _file && _file.equals(f._file)); + return f._file==_file || (null != _file && _file.equals(f._file)); } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/BufferUtilTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/BufferUtilTest.java index ab3ead51d61..5d7492dff93 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/BufferUtilTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/BufferUtilTest.java @@ -297,6 +297,7 @@ public class BufferUtilTest @Test + @SuppressWarnings("ReferenceEquality") public void testEnsureCapacity() throws Exception { ByteBuffer b = BufferUtil.toBuffer("Goodbye Cruel World"); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java index d95acb63ef3..80e06435aab 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java @@ -40,6 +40,7 @@ public class DateCacheTest /* ------------------------------------------------------------ */ @Test @Slow + @SuppressWarnings("ReferenceEquality") public void testDateCache() throws Exception { //@WAS: Test t = new Test("org.eclipse.jetty.util.DateCache"); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java index dfce5f4b588..273fd429aaa 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java @@ -36,6 +36,7 @@ import static org.junit.Assert.assertTrue; public class StringUtilTest { @Test + @SuppressWarnings("ReferenceEquality") public void testAsciiToLowerCase() { String lc="\u0690bc def 1\u06903"; @@ -88,6 +89,7 @@ public class StringUtilTest } @Test + @SuppressWarnings("ReferenceEquality") public void testReplace() { String s="\u0690bc \u0690bc \u0690bc"; @@ -100,6 +102,7 @@ public class StringUtilTest } @Test + @SuppressWarnings("ReferenceEquality") public void testUnquote() { String uq =" not quoted "; @@ -112,9 +115,10 @@ public class StringUtilTest @Test + @SuppressWarnings("ReferenceEquality") public void testNonNull() { - String nn=""; + String nn="non empty string"; assertTrue(nn==StringUtil.nonNull(nn)); assertEquals("",StringUtil.nonNull(null)); } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/TopologicalSortTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/TopologicalSortTest.java index 05eac6ef68d..3b74d30260c 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/TopologicalSortTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/TopologicalSortTest.java @@ -193,6 +193,7 @@ public class TopologicalSortTest } } + @SuppressWarnings("ReferenceEquality") private int indexOf(String[] list,String s) { for (int i=0;i Date: Tue, 6 Mar 2018 17:21:15 +1100 Subject: [PATCH 05/87] changes after second review from gregw Signed-off-by: Lachlan Roberts --- .../java/org/eclipse/jetty/client/HttpContent.java | 13 ++++++------- .../java/org/eclipse/jetty/deploy/graph/Edge.java | 14 -------------- .../java/org/eclipse/jetty/deploy/graph/Graph.java | 6 +++--- .../java/org/eclipse/jetty/servlets/DoSFilter.java | 2 +- .../common/message/MessageInputStream.java | 8 ++++---- 5 files changed, 14 insertions(+), 29 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java index 66b24cc677d..0f02a6d970d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpContent.java @@ -82,15 +82,14 @@ public class HttpContent implements Callback, Closeable } /** - * * @param buffer - * @return whether the input buffer has been closed + * @return true if the buffer is the sentinel instance {@link CLOSE} */ - private static boolean isBufferClosed(ByteBuffer buffer) + private static boolean isTheCloseBuffer(ByteBuffer buffer) { @SuppressWarnings("ReferenceEquality") - boolean bufferClosed = (buffer == CLOSE); - return bufferClosed; + boolean isTheCloseBuffer = (buffer == CLOSE); + return isTheCloseBuffer; } /** @@ -200,7 +199,7 @@ public class HttpContent implements Callback, Closeable { if (isConsumed()) return; - if (isBufferClosed(buffer)) + if (isTheCloseBuffer(buffer)) return; if (iterator instanceof Callback) ((Callback)iterator).succeeded(); @@ -211,7 +210,7 @@ public class HttpContent implements Callback, Closeable { if (isConsumed()) return; - if (isBufferClosed(buffer)) + if (isTheCloseBuffer(buffer)) return; if (iterator instanceof Callback) ((Callback)iterator).failed(x); diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java index af792eedd66..83fec32fcc4 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java @@ -74,25 +74,11 @@ public final class Edge return _from; } - public boolean isFromNode(Node node) - { - @SuppressWarnings("ReferenceEquality") - boolean isFromNode_ = (_from == node); - return isFromNode_; - } - public Node getTo() { return _to; } - public boolean isToNode(Node node) - { - @SuppressWarnings("ReferenceEquality") - boolean isToNode_ = (_to == node); - return isToNode_; - } - @Override public String toString() { diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java index b05064f7add..a0fe24a7c95 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java @@ -40,7 +40,7 @@ public class Graph addNode(toNode=edge.getTo()); // replace edge with normalized edge - if (!edge.isFromNode(fromNode) || !edge.isToNode(toNode)) + if (!edge.getFrom().equals(fromNode) || !edge.getTo().equals(toNode)) edge=new Edge(fromNode,toNode); this._edges.add(edge); @@ -129,7 +129,7 @@ public class Graph for (Edge edge : this._edges) { - if (edge.isFromNode(node) || edge.isToNode(node)) + if (edge.getFrom().equals(node) || edge.getTo().equals(node)) { fromedges.add(edge); } @@ -151,7 +151,7 @@ public class Graph for (Edge edge : this._edges) { - if (edge.isFromNode(from)) + if (edge.getFrom().equals(from)) { fromedges.add(edge); } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java index 70e2bbe1653..8b37652497c 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java @@ -381,7 +381,7 @@ public class DoSFilter implements Filter // or if we were woken up we insist or we fail. Boolean throttled = (Boolean)request.getAttribute(__THROTTLED); long throttleMs = getThrottleMs(); - if (Boolean.FALSE.equals(throttled) && throttleMs > 0) + if (!Boolean.TRUE.equals(throttled) && throttleMs > 0) { int priority = getPriority(request, tracker); request.setAttribute(__THROTTLED, Boolean.TRUE); diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java index a2d87759548..7765127e5bf 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/message/MessageInputStream.java @@ -45,11 +45,11 @@ public class MessageInputStream extends InputStream implements MessageAppender private final long timeoutMs; private ByteBuffer activeBuffer = null; - private static boolean isBufferEOF(ByteBuffer buf) + private static boolean isTheEofBuffer(ByteBuffer buf) { @SuppressWarnings("ReferenceEquality") - boolean isBufferEOF_ = (buf==EOF); - return isBufferEOF_; + boolean isTheEofBuffer = (buf==EOF); + return isTheEofBuffer; } public MessageInputStream() @@ -173,7 +173,7 @@ public class MessageInputStream extends InputStream implements MessageAppender } } - if (isBufferEOF(activeBuffer)) + if (isTheEofBuffer(activeBuffer)) { if (LOG.isDebugEnabled()) LOG.debug("Reached EOF"); From e4ad88aaf1e16f5a5d2408bc7eafcadc779495de Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 6 Mar 2018 09:18:18 -0600 Subject: [PATCH 06/87] Issue #2282 - simplifying EventCapture --- .../examples/AdapterConnectCloseSocket.java | 4 +- .../examples/AnnotatedBinaryArraySocket.java | 6 +- .../examples/AnnotatedBinaryStreamSocket.java | 6 +- .../java/examples/AnnotatedFramesSocket.java | 6 +- .../examples/AnnotatedStreamingSocket.java | 4 +- .../java/examples/AnnotatedTextSocket.java | 8 +-- .../examples/AnnotatedTextStreamSocket.java | 6 +- .../java/examples/ListenerBasicSocket.java | 10 +-- .../java/examples/ListenerFrameSocket.java | 8 +-- .../java/examples/ListenerPartialSocket.java | 10 +-- .../java/examples/ListenerPingPongSocket.java | 10 +-- .../websocket/common/events/EventCapture.java | 59 ++------------- .../common/events/EventDriverTest.java | 72 +++++++++---------- .../websocket/common/test/MoreMatchers.java | 39 ++++++++++ 14 files changed, 118 insertions(+), 130 deletions(-) create mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/MoreMatchers.java diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AdapterConnectCloseSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AdapterConnectCloseSocket.java index 7c7d2a4c022..744dfb2784b 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AdapterConnectCloseSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AdapterConnectCloseSocket.java @@ -29,12 +29,12 @@ public class AdapterConnectCloseSocket extends WebSocketAdapter @Override public void onWebSocketClose(int statusCode, String reason) { - capture.add("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); } @Override public void onWebSocketConnect(Session sess) { - capture.add("onWebSocketConnect(%s)",sess); + capture.offer("onWebSocketConnect(%s)",sess); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryArraySocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryArraySocket.java index 860cd5860b1..9fcb4575c56 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryArraySocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryArraySocket.java @@ -33,19 +33,19 @@ public class AnnotatedBinaryArraySocket @OnWebSocketMessage public void onBinary(byte payload[], int offset, int length) { - capture.add("onBinary([%d],%d,%d)",payload.length,offset,length); + capture.offer("onBinary([%d],%d,%d)",payload.length,offset,length); } @OnWebSocketClose public void onClose(int statusCode, String reason) { - capture.add("onClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onClose(%d, %s)",statusCode,capture.q(reason)); } @OnWebSocketConnect public void onConnect(Session sess) { - capture.add("onConnect(%s)",sess); + capture.offer("onConnect(%s)",sess); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryStreamSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryStreamSocket.java index 89d874a2ac3..9910f78db96 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryStreamSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedBinaryStreamSocket.java @@ -39,18 +39,18 @@ public class AnnotatedBinaryStreamSocket { new RuntimeException("Stream cannot be null").printStackTrace(System.err); } - capture.add("onBinary(%s)",stream); + capture.offer("onBinary(%s)",stream); } @OnWebSocketClose public void onClose(int statusCode, String reason) { - capture.add("onClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onClose(%d, %s)",statusCode,capture.q(reason)); } @OnWebSocketConnect public void onConnect(Session sess) { - capture.add("onConnect(%s)",sess); + capture.offer("onConnect(%s)",sess); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedFramesSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedFramesSocket.java index 85339f4a990..ccc9b738bba 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedFramesSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedFramesSocket.java @@ -34,18 +34,18 @@ public class AnnotatedFramesSocket @OnWebSocketClose public void onClose(int statusCode, String reason) { - capture.add("onClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onClose(%d, %s)",statusCode,capture.q(reason)); } @OnWebSocketConnect public void onConnect(Session sess) { - capture.add("onConnect(%s)",sess); + capture.offer("onConnect(%s)",sess); } @OnWebSocketFrame public void onFrame(Frame frame) { - capture.add("onFrame(%s)",frame); + capture.offer("onFrame(%s)",frame); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedStreamingSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedStreamingSocket.java index dee874d58a6..58b02d7ae35 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedStreamingSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedStreamingSocket.java @@ -38,13 +38,13 @@ public class AnnotatedStreamingSocket @OnWebSocketClose public void onClose(int statusCode, String reason) { - capture.add("onClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onClose(%d, %s)",statusCode,capture.q(reason)); } @OnWebSocketConnect public void onConnect(Session sess) { - capture.add("onConnect(%s)",sess); + capture.offer("onConnect(%s)",sess); } @OnWebSocketFrame diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextSocket.java index e6569680195..02a11d77482 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextSocket.java @@ -34,24 +34,24 @@ public class AnnotatedTextSocket @OnWebSocketClose public void onClose(int statusCode, String reason) { - capture.add("onClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onClose(%d, %s)",statusCode,capture.q(reason)); } @OnWebSocketConnect public void onConnect(Session sess) { - capture.add("onConnect(%s)",sess); + capture.offer("onConnect(%s)",sess); } @OnWebSocketError public void onError(Throwable cause) { - capture.add("onError(%s: %s)",cause.getClass().getSimpleName(),cause.getMessage()); + capture.offer("onError(%s: %s)",cause.getClass().getSimpleName(),cause.getMessage()); } @OnWebSocketMessage public void onText(String message) { - capture.add("onText(%s)",capture.q(message)); + capture.offer("onText(%s)",capture.q(message)); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextStreamSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextStreamSocket.java index 037b8d9d38a..cf6576df8ab 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextStreamSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/AnnotatedTextStreamSocket.java @@ -35,18 +35,18 @@ public class AnnotatedTextStreamSocket @OnWebSocketClose public void onClose(int statusCode, String reason) { - capture.add("onClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onClose(%d, %s)",statusCode,capture.q(reason)); } @OnWebSocketConnect public void onConnect(Session sess) { - capture.add("onConnect(%s)",sess); + capture.offer("onConnect(%s)",sess); } @OnWebSocketMessage public void onText(Reader reader) { - capture.add("onText(%s)",reader); + capture.offer("onText(%s)",reader); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/ListenerBasicSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/ListenerBasicSocket.java index 4dcb4132694..10d36f35206 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/ListenerBasicSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/ListenerBasicSocket.java @@ -29,30 +29,30 @@ public class ListenerBasicSocket implements WebSocketListener @Override public void onWebSocketBinary(byte[] payload, int offset, int len) { - capture.add("onWebSocketBinary([%d], %d, %d)",payload.length,offset,len); + capture.offer("onWebSocketBinary([%d], %d, %d)",payload.length,offset,len); } @Override public void onWebSocketClose(int statusCode, String reason) { - capture.add("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); } @Override public void onWebSocketConnect(Session session) { - capture.add("onWebSocketConnect(%s)",session); + capture.offer("onWebSocketConnect(%s)",session); } @Override public void onWebSocketError(Throwable cause) { - capture.add("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); + capture.offer("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); } @Override public void onWebSocketText(String message) { - capture.add("onWebSocketText(%s)",capture.q(message)); + capture.offer("onWebSocketText(%s)",capture.q(message)); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/ListenerFrameSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/ListenerFrameSocket.java index a3b6eb6f7c6..f42f2552440 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/ListenerFrameSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/ListenerFrameSocket.java @@ -30,24 +30,24 @@ public class ListenerFrameSocket implements WebSocketFrameListener @Override public void onWebSocketClose(int statusCode, String reason) { - capture.add("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); } @Override public void onWebSocketConnect(Session session) { - capture.add("onWebSocketConnect(%s)",session); + capture.offer("onWebSocketConnect(%s)",session); } @Override public void onWebSocketError(Throwable cause) { - capture.add("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); + capture.offer("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); } @Override public void onWebSocketFrame(Frame frame) { - capture.add("onWebSocketFrame(%s, %d, %b)", frame.getType(), frame.getPayload().remaining(), frame.isFin()); + capture.offer("onWebSocketFrame(%s, %d, %b)", frame.getType(), frame.getPayload().remaining(), frame.isFin()); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/ListenerPartialSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/ListenerPartialSocket.java index 5f29b8d5ca7..2e7b89e1f49 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/ListenerPartialSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/ListenerPartialSocket.java @@ -31,30 +31,30 @@ public class ListenerPartialSocket implements WebSocketPartialListener @Override public void onWebSocketClose(int statusCode, String reason) { - capture.add("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); } @Override public void onWebSocketConnect(Session session) { - capture.add("onWebSocketConnect(%s)",session); + capture.offer("onWebSocketConnect(%s)",session); } @Override public void onWebSocketError(Throwable cause) { - capture.add("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); + capture.offer("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); } @Override public void onWebSocketPartialText(String payload, boolean fin) { - capture.add("onWebSocketPartialText('%s', %b)",payload,fin); + capture.offer("onWebSocketPartialText('%s', %b)",payload,fin); } @Override public void onWebSocketPartialBinary(ByteBuffer payload, boolean fin) { - capture.add("onWebSocketPartialBinary(%s [%d], %b)",payload,payload.remaining(),fin); + capture.offer("onWebSocketPartialBinary(%s [%d], %b)",payload,payload.remaining(),fin); } } diff --git a/jetty-websocket/websocket-common/src/test/java/examples/ListenerPingPongSocket.java b/jetty-websocket/websocket-common/src/test/java/examples/ListenerPingPongSocket.java index a7152bc214d..9f3692dafb8 100644 --- a/jetty-websocket/websocket-common/src/test/java/examples/ListenerPingPongSocket.java +++ b/jetty-websocket/websocket-common/src/test/java/examples/ListenerPingPongSocket.java @@ -31,30 +31,30 @@ public class ListenerPingPongSocket implements WebSocketPingPongListener @Override public void onWebSocketClose(int statusCode, String reason) { - capture.add("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); + capture.offer("onWebSocketClose(%d, %s)",statusCode,capture.q(reason)); } @Override public void onWebSocketConnect(Session session) { - capture.add("onWebSocketConnect(%s)",session); + capture.offer("onWebSocketConnect(%s)",session); } @Override public void onWebSocketError(Throwable cause) { - capture.add("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); + capture.offer("onWebSocketError((%s) %s)",cause.getClass().getSimpleName(),cause.getMessage()); } @Override public void onWebSocketPing(ByteBuffer payload) { - capture.add("onWebSocketPing(%d)",payload.remaining()); + capture.offer("onWebSocketPing(%d)",payload.remaining()); } @Override public void onWebSocketPong(ByteBuffer payload) { - capture.add("onWebSocketPong(%d)",payload.remaining()); + capture.offer("onWebSocketPong(%d)",payload.remaining()); } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java index 8a140fafd8f..b05265841f9 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventCapture.java @@ -18,57 +18,18 @@ package org.eclipse.jetty.websocket.common.events; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.startsWith; - import java.util.concurrent.LinkedBlockingQueue; -import java.util.regex.Pattern; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.junit.Assert; +import org.eclipse.jetty.websocket.common.test.Timeouts; -/** - * @deprecated should refactor away. - */ @SuppressWarnings("serial") -@Deprecated public class EventCapture extends LinkedBlockingQueue { private static final Logger LOG = Log.getLogger(EventCapture.class); - public static class Assertable - { - private final String event; - - public Assertable(String event) - { - this.event = event; - } - - public void assertEventContains(String expected) - { - Assert.assertThat("Event",event,containsString(expected)); - } - - public void assertEventRegex(String regex) - { - Assert.assertTrue("Event: regex:[" + regex + "] in [" + event + "]",Pattern.matches(regex,event)); - } - - public void assertEventStartsWith(String expected) - { - Assert.assertThat("Event",event,startsWith(expected)); - } - - public void assertEvent(String expected) - { - Assert.assertThat("Event",event,is(expected)); - } - } - - public void add(String format, Object... args) + public void offer(String format, Object... args) { String msg = String.format(format,args); if (LOG.isDebugEnabled()) @@ -76,17 +37,6 @@ public class EventCapture extends LinkedBlockingQueue super.offer(msg); } - public Assertable pop() - { - // TODO: poll should have timeout. - return new Assertable(super.poll()); - } - - public void assertEventCount(int expectedCount) - { - Assert.assertThat("Event Count",size(),is(expectedCount)); - } - public String q(String str) { if (str == null) @@ -95,4 +45,9 @@ public class EventCapture extends LinkedBlockingQueue } return '"' + str + '"'; } + + public String safePoll() throws InterruptedException + { + return poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java index 75cd41a9d63..67e78647843 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/events/EventDriverTest.java @@ -18,8 +18,10 @@ package org.eclipse.jetty.websocket.common.events; -import java.io.IOException; -import java.util.concurrent.TimeoutException; +import static org.eclipse.jetty.websocket.common.test.MoreMatchers.regex; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertThat; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; @@ -80,9 +82,8 @@ public class EventDriverTest conn.open(); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(2); - socket.capture.pop().assertEventStartsWith("onWebSocketConnect"); - socket.capture.pop().assertEventStartsWith("onWebSocketClose"); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketConnect")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketClose")); } } @@ -98,10 +99,9 @@ public class EventDriverTest driver.incomingFrame(makeBinaryFrame("Hello World",true)); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(3); - socket.capture.pop().assertEventStartsWith("onConnect"); - socket.capture.pop().assertEvent("onBinary([11],0,11)"); - socket.capture.pop().assertEventStartsWith("onClose(1000,"); + assertThat(socket.capture.safePoll(), startsWith("onConnect")); + assertThat(socket.capture.safePoll(), containsString("onBinary([11],0,11)")); + assertThat(socket.capture.safePoll(), startsWith("onClose(1000,")); } } @@ -117,10 +117,9 @@ public class EventDriverTest driver.incomingError(new WebSocketException("oof")); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(3); - socket.capture.pop().assertEventStartsWith("onConnect"); - socket.capture.pop().assertEventStartsWith("onError(WebSocketException: oof)"); - socket.capture.pop().assertEventStartsWith("onClose(1000,"); + assertThat(socket.capture.safePoll(), startsWith("onConnect")); + assertThat(socket.capture.safePoll(), startsWith("onError(WebSocketException: oof)")); + assertThat(socket.capture.safePoll(), startsWith("onClose(1000,")); } } @@ -138,18 +137,17 @@ public class EventDriverTest driver.incomingFrame(new BinaryFrame().setPayload("Hello Bin")); driver.incomingFrame(new CloseInfo(StatusCode.SHUTDOWN,"testcase").asFrame()); - socket.capture.assertEventCount(6); - socket.capture.pop().assertEventStartsWith("onConnect("); - socket.capture.pop().assertEventStartsWith("onFrame(PING["); - socket.capture.pop().assertEventStartsWith("onFrame(TEXT["); - socket.capture.pop().assertEventStartsWith("onFrame(BINARY["); - socket.capture.pop().assertEventStartsWith("onFrame(CLOSE["); - socket.capture.pop().assertEventStartsWith("onClose(1001,"); + assertThat(socket.capture.safePoll(), startsWith("onConnect(")); + assertThat(socket.capture.safePoll(), startsWith("onFrame(PING[")); + assertThat(socket.capture.safePoll(), startsWith("onFrame(TEXT[")); + assertThat(socket.capture.safePoll(), startsWith("onFrame(BINARY[")); + assertThat(socket.capture.safePoll(), startsWith("onFrame(CLOSE[")); + assertThat(socket.capture.safePoll(), startsWith("onClose(1001,")); } } @Test - public void testAnnotated_InputStream() throws IOException, TimeoutException, InterruptedException + public void testAnnotated_InputStream() throws InterruptedException { AnnotatedBinaryStreamSocket socket = new AnnotatedBinaryStreamSocket(); EventDriver driver = wrap(socket); @@ -160,10 +158,9 @@ public class EventDriverTest driver.incomingFrame(makeBinaryFrame("Hello World",true)); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(3); - socket.capture.pop().assertEventStartsWith("onConnect"); - socket.capture.pop().assertEventRegex("^onBinary\\(.*InputStream.*"); - socket.capture.pop().assertEventStartsWith("onClose(1000,"); + assertThat(socket.capture.safePoll(), startsWith("onConnect")); + assertThat(socket.capture.safePoll(), regex("^onBinary\\(.*InputStream.*")); + assertThat(socket.capture.safePoll(), startsWith("onClose(1000,")); } } @@ -180,10 +177,9 @@ public class EventDriverTest driver.incomingFrame(new TextFrame().setPayload("Hello World")); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(3); - socket.capture.pop().assertEventStartsWith("onWebSocketConnect"); - socket.capture.pop().assertEventStartsWith("onWebSocketText(\"Hello World\")"); - socket.capture.pop().assertEventStartsWith("onWebSocketClose(1000,"); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketConnect")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketText(\"Hello World\")")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketClose(1000,")); } } @@ -201,11 +197,10 @@ public class EventDriverTest driver.incomingFrame(new PongFrame().setPayload("PONG")); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(4); - socket.capture.pop().assertEventStartsWith("onWebSocketConnect"); - socket.capture.pop().assertEventStartsWith("onWebSocketPing("); - socket.capture.pop().assertEventStartsWith("onWebSocketPong("); - socket.capture.pop().assertEventStartsWith("onWebSocketClose(1000,"); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketConnect")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketPing(")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketPong(")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketClose(1000,")); } } @@ -223,11 +218,10 @@ public class EventDriverTest driver.incomingFrame(new PongFrame()); driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame()); - socket.capture.assertEventCount(4); - socket.capture.pop().assertEventStartsWith("onWebSocketConnect"); - socket.capture.pop().assertEventStartsWith("onWebSocketPing("); - socket.capture.pop().assertEventStartsWith("onWebSocketPong("); - socket.capture.pop().assertEventStartsWith("onWebSocketClose(1000,"); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketConnect")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketPing(")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketPong(")); + assertThat(socket.capture.safePoll(), startsWith("onWebSocketClose(1000,")); } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/MoreMatchers.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/MoreMatchers.java new file mode 100644 index 00000000000..a185e872ee2 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/MoreMatchers.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.common.test; + +import org.eclipse.jetty.toolchain.test.matchers.RegexMatcher; + +public class MoreMatchers +{ + /** + * Create a matcher for {@link String} that matches against a regex pattern. + * + *

+ * Returns success based on {@code java.util.regex.Pattern.matcher(input).matches();} + *

+ * + * @param pattern the {@link java.util.regex.Pattern} syntax pattern to match against. + * @return the Regex Matcher + */ + public static org.hamcrest.Matcher regex(String pattern) + { + return new RegexMatcher(pattern); + } +} From 3c393da3f91ab10d2f6614dce2d2b72542d9336b Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 5 Mar 2018 15:02:00 -0600 Subject: [PATCH 07/87] Issue #2278 - making distribution pom not require tests - Speculative fix to ensure that the users of the jetty-distribution do not require the test artifacts to utilize the tarball / zip files - Also disabled the snapshot repository as it causes false success - Adding now unreferenced dependency Signed-off-by: Joakim Erdfelt --- jetty-distribution/pom.xml | 9 +++++++++ pom.xml | 4 ++++ tests/test-integration/pom.xml | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 8c92a955625..32a051f13e7 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -398,29 +398,37 @@ + org.eclipse.jetty jetty-home ${project.version} pom + true org.eclipse.jetty test-jetty-webapp war ${project.version} + true org.eclipse.jetty test-proxy-webapp war ${project.version} + true org.eclipse.jetty.example-async-rest example-async-rest-webapp ${project.version} war + true org.eclipse.jetty @@ -428,6 +436,7 @@ ${project.version} html zip + true diff --git a/pom.xml b/pom.xml index 5907756de04..0ea022736b3 100644 --- a/pom.xml +++ b/pom.xml @@ -1766,6 +1766,9 @@ https://webtide.com + diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index edb785ca3cb..6e5cc58e119 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -118,6 +118,11 @@ apache-jsp ${project.version} + + org.eclipse.jetty.http2 + http2-server + ${project.version} + org.eclipse.jetty.tests test-webapp-rfc2616 From 5dea9b673e968a98bbeb54355fb23cb1ff458973 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 7 Mar 2018 00:45:23 +0100 Subject: [PATCH 08/87] Fixes #2291 - Expose HTTP/2 close reason in dumps. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/http2/HTTP2Session.java | 17 ++++++++++------- .../eclipse/jetty/http2/frames/GoAwayFrame.java | 13 +++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java index 4dd88c5f35e..2ebcb2dc6c1 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java @@ -89,6 +89,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio private int initialSessionRecvWindow; private boolean pushEnabled; private long idleTime; + private GoAwayFrame closeFrame; public HTTP2Session(Scheduler scheduler, EndPoint endPoint, Generator generator, Session.Listener listener, FlowControlStrategy flowControl, int initialStreamId) { @@ -430,6 +431,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio { // We received a GO_AWAY, so try to write // what's in the queue and then disconnect. + closeFrame = frame; notifyClose(this, frame, new DisconnectCallback()); return; } @@ -597,8 +599,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio { if (closed.compareAndSet(current, CloseState.LOCALLY_CLOSED)) { - GoAwayFrame frame = newGoAwayFrame(error, reason); - control(null, callback, frame); + closeFrame = newGoAwayFrame(CloseState.LOCALLY_CLOSED, error, reason); + control(null, callback, closeFrame); return true; } break; @@ -614,7 +616,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio } } - private GoAwayFrame newGoAwayFrame(int error, String reason) + private GoAwayFrame newGoAwayFrame(CloseState closeState, int error, String reason) { byte[] payload = null; if (reason != null) @@ -623,7 +625,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio reason = reason.substring(0, Math.min(reason.length(), 32)); payload = reason.getBytes(StandardCharsets.UTF_8); } - return new GoAwayFrame(lastStreamId.get(), error, payload); + return new GoAwayFrame(closeState, lastStreamId.get(), error, payload); } @Override @@ -1125,7 +1127,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio @Override public String toString() { - return String.format("%s@%x{l:%s <-> r:%s,sendWindow=%s,recvWindow=%s,streams=%d,%s}", + return String.format("%s@%x{l:%s <-> r:%s,sendWindow=%s,recvWindow=%s,streams=%d,%s,%s}", getClass().getSimpleName(), hashCode(), getEndPoint().getLocalAddress(), @@ -1133,7 +1135,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio sendWindow, recvWindow, streams.size(), - closed); + closed, + closeFrame); } private class ControlEntry extends HTTP2Flusher.Entry @@ -1453,7 +1456,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio private void complete() { - frames(null, Callback.NOOP, newGoAwayFrame(ErrorCode.NO_ERROR.code, null), new DisconnectFrame()); + frames(null, Callback.NOOP, newGoAwayFrame(CloseState.CLOSED, ErrorCode.NO_ERROR.code, null), new DisconnectFrame()); } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java index 7fcf3cb81cb..e603771dee9 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java @@ -20,17 +20,25 @@ package org.eclipse.jetty.http2.frames; import java.nio.charset.StandardCharsets; +import org.eclipse.jetty.http2.CloseState; import org.eclipse.jetty.http2.ErrorCode; public class GoAwayFrame extends Frame { + private final CloseState closeState; private final int lastStreamId; private final int error; private final byte[] payload; public GoAwayFrame(int lastStreamId, int error, byte[] payload) + { + this(CloseState.REMOTELY_CLOSED, lastStreamId, error, payload); + } + + public GoAwayFrame(CloseState closeState, int lastStreamId, int error, byte[] payload) { super(FrameType.GO_AWAY); + this.closeState = closeState; this.lastStreamId = lastStreamId; this.error = error; this.payload = payload; @@ -69,10 +77,11 @@ public class GoAwayFrame extends Frame public String toString() { ErrorCode errorCode = ErrorCode.from(error); - return String.format("%s,%d/%s/%s", + return String.format("%s,%d/%s/%s/%s", super.toString(), lastStreamId, errorCode != null ? errorCode.toString() : String.valueOf(error), - tryConvertPayload()); + tryConvertPayload(), + closeState); } } From dd57cf0bf602692edbdc87a6ff85506b636e239c Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 6 Mar 2018 21:01:39 -0600 Subject: [PATCH 09/87] Issue #2282 - Simplifying BlockheadClient to drastically reduce CPU load during testing --- .../jsr356/DecoderReaderManySmallTest.java | 5 - .../websocket/jsr356/DecoderReaderTest.java | 5 - .../jetty/websocket/jsr356/EncoderTest.java | 4 - .../jsr356/server/ConfiguratorTest.java | 204 +++-- .../websocket/jsr356/server/EchoTest.java | 1 - ...tedEndpointScanner_GoodSignaturesTest.java | 1 - .../websocket/client/BadNetworkTest.java | 5 - .../websocket/client/ClientCloseTest.java | 5 - .../websocket/client/ClientConnectTest.java | 5 - .../client/ConnectionManagerTest.java | 5 - .../websocket/client/SlowClientTest.java | 9 +- .../websocket/client/SlowServerTest.java | 10 - .../client/WebSocketClientBadUriTest.java | 5 - .../websocket/client/WebSocketClientTest.java | 3 - jetty-websocket/websocket-common/pom.xml | 6 + .../websocket/common/ab/TestABCase3.java | 5 - .../io/http/HttpResponseHeaderParserTest.java | 5 - .../message/MessageOutputStreamTest.java | 4 - .../common/message/MessageWriterTest.java | 4 - .../common/test/BlockheadClient.java | 832 +----------------- .../test/BlockheadClientConnection.java | 48 + .../test/BlockheadClientConstructionTest.java | 72 -- .../common/test/BlockheadClientRequest.java | 252 ++++++ .../common/test/BlockheadConnection.java | 373 ++++++++ .../test/BlockheadServerConnection.java | 4 +- .../jetty/websocket/common/test/Fuzzer.java | 109 +-- .../test/IBlockheadServerConnection.java | 1 + .../jetty/websocket/common/test/Timeouts.java | 7 +- .../common/test/WriteCallbackDelegate.java | 46 + .../server/AnnotatedMaxMessageSizeTest.java | 75 +- .../jetty/websocket/server/ChromeTest.java | 54 +- .../server/DecoratorsLegacyTest.java | 55 +- .../websocket/server/DecoratorsTest.java | 39 +- .../jetty/websocket/server/FirefoxTest.java | 36 +- .../server/FragmentExtensionTest.java | 57 +- .../server/IdentityExtensionTest.java | 53 +- .../websocket/server/IdleTimeoutTest.java | 51 +- .../server/ManyConnectionsCleanupTest.java | 159 ++-- .../websocket/server/RequestHeadersTest.java | 57 +- .../websocket/server/SubProtocolTest.java | 40 +- .../websocket/server/SuspendResumeTest.java | 36 +- .../websocket/server/TooFastClientTest.java | 157 ++-- .../websocket/server/WebSocketCloseTest.java | 187 ++-- .../server/WebSocketInvalidVersionTest.java | 59 +- .../server/WebSocketOverSSLTest.java | 5 - .../server/WebSocketServerSessionTest.java | 59 +- .../server/WebSocketServletRFCTest.java | 197 ++--- .../server/WebSocketUpgradeFilterTest.java | 76 +- .../websocket/server/ab/TestABCase2.java | 3 - .../websocket/server/ab/TestABCase4.java | 3 - .../websocket/server/ab/TestABCase5.java | 7 +- .../websocket/server/ab/TestABCase6.java | 8 - .../websocket/server/ab/TestABCase7.java | 5 - .../websocket/server/ab/TestABCase9.java | 40 - .../server/examples/MyEchoSocket.java | 3 - .../misbehaving/MisbehavingClassTest.java | 72 +- 56 files changed, 1783 insertions(+), 1845 deletions(-) create mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java delete mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java create mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java create mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java create mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java index 3402fb5b582..1500064c44b 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java @@ -37,7 +37,6 @@ import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -49,7 +48,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; @Ignore("Not working atm") @@ -165,9 +163,6 @@ public class DecoderReaderManySmallTest private static final Logger LOG = Log.getLogger(DecoderReaderManySmallTest.class); - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java index c3ffc6909ca..56792c47554 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java @@ -42,7 +42,6 @@ import javax.websocket.OnMessage; import javax.websocket.WebSocketContainer; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; @@ -57,7 +56,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; public class DecoderReaderTest @@ -229,9 +227,6 @@ public class DecoderReaderTest private static final Logger LOG = Log.getLogger(DecoderReaderTest.class); - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java index d8ac993af07..807ca8444e2 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java @@ -41,7 +41,6 @@ import javax.websocket.Session; import javax.websocket.WebSocketContainer; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -51,7 +50,6 @@ import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; public class EncoderTest @@ -186,8 +184,6 @@ public class EncoderTest private static final Logger LOG = Log.getLogger(EncoderTest.class); - @Rule - public TestTracker tt = new TestTracker(); private BlockheadServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java index 9042d4f4a4b..93ac72667c0 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java @@ -35,7 +35,9 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -51,6 +53,9 @@ import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -60,8 +65,8 @@ import org.eclipse.jetty.websocket.api.util.QuoteUtil; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.junit.AfterClass; @@ -356,7 +361,8 @@ public class ConfiguratorTest return dateFormat; } } - + + private static BlockheadClient client; private static Server server; private static URI baseServerUri; @@ -408,18 +414,35 @@ public class ConfiguratorTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testEmptyConfigurator() throws Exception { URI uri = baseServerUri.resolve("/empty"); - try (IBlockheadClient client = new BlockheadClient(uri)) + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.addExtensions("identity"); - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.readResponseHeader(); - Assert.assertThat("response.extensions", response.getExtensionsHeader(), is("identity")); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + Assert.assertThat("response.extensions", extensionHeader.getValue(), is("identity")); } } @@ -428,16 +451,19 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/no-extensions"); - try (IBlockheadClient client = new BlockheadClient(uri)) + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.addExtensions("identity"); - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.expectUpgradeResponse(); - assertThat("response.extensions", response.getExtensionsHeader(), nullValue()); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + assertThat("response.extensions", extensionHeader, is(nullValue())); - client.write(new TextFrame().setPayload("NegoExts")); - LinkedBlockingQueue frames = client.getFrameQueue(); + clientConn.write(new TextFrame().setPayload("NegoExts")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("Frame Response", frame.getPayloadAsUTF8(), is("negotiatedExtensions=[]")); } @@ -448,15 +474,15 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/capture-request-headers"); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("X-Dummy: Bogus\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header("X-Dummy", "Bogus"); - client.write(new TextFrame().setPayload("X-Dummy")); - LinkedBlockingQueue frames = client.getFrameQueue(); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("X-Dummy")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Request Header [X-Dummy]: \"Bogus\"")); } @@ -468,33 +494,32 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/unique-user-props"); // First request - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("apple")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("apple")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = \"fruit from tree\"")); } // Second request - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - client.write(new TextFrame().setPayload("apple")); - client.write(new TextFrame().setPayload("blueberry")); - LinkedBlockingQueue frames = client.getFrameQueue(); + request = client.newWsRequest(uri); + connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("apple")); + clientConn.write(new TextFrame().setPayload("blueberry")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); // should have no value Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = ")); - frame = frames.poll(); + frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [blueberry] = \"fruit from bush\"")); } } @@ -504,18 +529,16 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/addr"); - // First request - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - InetSocketAddress expectedLocal = client.getLocalSocketAddress(); - InetSocketAddress expectedRemote = client.getRemoteSocketAddress(); + BlockheadClientRequest request = client.newWsRequest(uri); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("addr")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + InetSocketAddress expectedLocal = clientConn.getLocalSocketAddress(); + InetSocketAddress expectedRemote = clientConn.getRemoteSocketAddress(); + + clientConn.write(new TextFrame().setPayload("addr")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); StringWriter expected = new StringWriter(); @@ -540,15 +563,14 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-WebSocket-Protocol: echo\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\"]")); } @@ -564,15 +586,14 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-WebSocket-Protocol: echo, chat, status\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo, chat, status"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } @@ -588,15 +609,14 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("sec-websocket-protocol: echo, chat, status\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header("sec-websocket-protocol", "echo, chat, status"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } @@ -612,15 +632,15 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-Websocket-Protocol: echo, chat, status\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + // We see "Websocket" (no capital "S" often) + request.header("Sec-Websocket-Protocol", "echo, chat, status"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } @@ -634,15 +654,15 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/timedecoder"); - try (BlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-Websocket-Protocol: gmt\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + // We see "Websocket" (no capital "S" often) + request.header("SeC-WeBsOcKeT-PrOtOcOl", "gmt"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("2016-06-20T14:27:44")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("2016-06-20T14:27:44")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("cal=2016.06.20 AD at 14:27:44 +0000")); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java index b4b95d9c803..b836c4dcb8a 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java @@ -249,7 +249,6 @@ public class EchoTest public EchoTest(EchoCase testcase) { this.testcase = testcase; - System.err.println(testcase); } @Test(timeout=2000) diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java index 0c168b60381..80a1a51bf72 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java @@ -179,7 +179,6 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest public ServerAnnotatedEndpointScanner_GoodSignaturesTest(Case testcase) { this.testcase = testcase; - System.err.printf("Testing signature of %s%n",testcase.pojo.getName()); } @Test 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 index 94cd12c0b6e..85a26b59156 100644 --- 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 @@ -24,14 +24,12 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; /** @@ -39,9 +37,6 @@ import org.junit.Test; */ public class BadNetworkTest { - @Rule - public TestTracker tt = new TestTracker(); - public ByteBufferPool bufferPool = new MappedByteBufferPool(); private BlockheadServer server; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java index 2b7ffe5e1e8..62da4dd5f7e 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java @@ -51,7 +51,6 @@ import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SocketChannelEndPoint; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -76,7 +75,6 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; public class ClientCloseTest @@ -178,9 +176,6 @@ public class ClientCloseTest } } - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketClient client; 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 index e1c842df49f..5b570fb4053 100644 --- 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 @@ -39,7 +39,6 @@ import java.util.concurrent.TimeoutException; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.common.AcceptHash; @@ -49,7 +48,6 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; /** @@ -58,9 +56,6 @@ import org.junit.Test; @SuppressWarnings("Duplicates") public class ClientConnectTest { - @Rule - public TestTracker tt = new TestTracker(); - public ByteBufferPool bufferPool = new MappedByteBufferPool(); private final int timeout = 500; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java index 205c221855d..77511c95d31 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java @@ -24,17 +24,12 @@ import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.client.io.ConnectionManager; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; public class ConnectionManagerTest { - @Rule - public TestTracker tt = new TestTracker(); - private void assertToSocketAddress(String uriStr, String expectedHost, int expectedPort) throws URISyntaxException { URI uri = new URI(uriStr); 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 index 7dde15b797f..d727c44b176 100644 --- 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 @@ -18,14 +18,12 @@ package org.eclipse.jetty.websocket.client; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.is; import java.net.URI; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.test.BlockheadServer; @@ -33,14 +31,10 @@ import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; public class SlowClientTest { - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketClient client; @@ -72,7 +66,6 @@ public class SlowClientTest } @Test - @Slow public void testClientSlowToSend() throws Exception { JettyTrackingSocket tsocket = new JettyTrackingSocket(); 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 index 101d0eae04d..09050221515 100644 --- 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 @@ -24,8 +24,6 @@ import java.net.URI; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.client.masks.ZeroMasker; @@ -34,16 +32,10 @@ import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; -@Ignore("TODO: Flappy Test") public class SlowServerTest { - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketClient client; @@ -75,7 +67,6 @@ public class SlowServerTest } @Test - @Slow public void testServerSlowToRead() throws Exception { JettyTrackingSocket tsocket = new JettyTrackingSocket(); @@ -122,7 +113,6 @@ public class SlowServerTest } @Test - @Slow public void testServerSlowToSend() throws Exception { JettyTrackingSocket clientSocket = new JettyTrackingSocket(); diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java index 028083949a5..02e7c31317e 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java @@ -23,11 +23,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -56,9 +54,6 @@ public class WebSocketClientBadUriTest return data; } - @Rule - public TestTracker tt = new TestTracker(); - private WebSocketClient client; private final String uriStr; private final URI uri; 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 90fe11e4da5..b22e3646d93 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 @@ -34,7 +34,6 @@ import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; @@ -50,9 +49,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -@RunWith(AdvancedRunner.class) public class WebSocketClientTest { private BlockheadServer server; diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index a3bac53190d..2e7e2393291 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -30,6 +30,12 @@ jetty-io ${project.version} + + org.eclipse.jetty + jetty-client + ${project.version} + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java index c8c2d6ee9cc..ab4dec13fe5 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java @@ -22,14 +22,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.ProtocolException; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.PongFrame; import org.eclipse.jetty.websocket.common.test.UnitGenerator; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -74,9 +72,6 @@ public class TestABCase3 return data; } - @Rule - public TestTracker tt = new TestTracker(); - private WebSocketFrame invalidFrame; public TestABCase3(WebSocketFrame invalidFrame) diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java index 96453c9b022..e9a4d36814e 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java @@ -28,18 +28,13 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; public class HttpResponseHeaderParserTest { - @Rule - public TestTracker tt = new TestTracker(); - private void appendUtf8(ByteBuffer buf, String line) { buf.put(ByteBuffer.wrap(StringUtil.getUtf8Bytes(line))); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java index 0060f58c4b3..6e3aa82a3b3 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java @@ -26,7 +26,6 @@ import java.util.Arrays; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -48,9 +47,6 @@ public class MessageOutputStreamTest { private static final Logger LOG = Log.getLogger(MessageOutputStreamTest.class); - @Rule - public TestTracker testtracker = new TestTracker(); - @Rule public TestName testname = new TestName(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java index ec77b8d176a..e4c6c99bced 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java @@ -24,7 +24,6 @@ import java.util.Arrays; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -46,9 +45,6 @@ public class MessageWriterTest { private static final Logger LOG = Log.getLogger(MessageWriterTest.class); - @Rule - public TestTracker testtracker = new TestTracker(); - @Rule public TestName testname = new TestName(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java index e7bca7d02af..3dba1c72bb0 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java @@ -18,833 +18,67 @@ package org.eclipse.jetty.websocket.common.test; -import static org.hamcrest.Matchers.anyOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketTimeoutException; import java.net.URI; -import java.net.URISyntaxException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.HttpsURLConnection; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.BatchMode; +import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.api.WebSocketPolicy; -import org.eclipse.jetty.websocket.api.WriteCallback; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.api.extensions.Frame; -import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; -import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; -import org.eclipse.jetty.websocket.api.util.WSURI; -import org.eclipse.jetty.websocket.common.AcceptHash; -import org.eclipse.jetty.websocket.common.CloseInfo; -import org.eclipse.jetty.websocket.common.ConnectionState; -import org.eclipse.jetty.websocket.common.Generator; -import org.eclipse.jetty.websocket.common.OpCode; -import org.eclipse.jetty.websocket.common.Parser; -import org.eclipse.jetty.websocket.common.WebSocketFrame; -import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; +import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; +import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; -import org.eclipse.jetty.websocket.common.io.IOState; -import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener; -import org.eclipse.jetty.websocket.common.io.http.HttpResponseHeaderParser; -import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; -import org.junit.Assert; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; -/** - * A simple websocket client for performing unit tests with. - *

- * This client will use {@link HttpURLConnection} and {@link HttpsURLConnection} with standard blocking calls to perform websocket requests. - *

- * This client is NOT intended to be performant or follow the websocket spec religiously. In fact, being able to deviate from the websocket spec at will - * is desired for this client to operate properly for the unit testing within this module. - *

- * The BlockheadClient should never validate frames or bytes being sent for validity, against any sort of spec, or even sanity. It should, however be honest - * with regards to basic IO behavior, a write should work as expected, a read should work as expected, but what byte it sends or reads is not within its - * scope. - */ -public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, AutoCloseable, IBlockheadClient +public class BlockheadClient extends HttpClient implements WebSocketContainerScope { - private class FrameReadingThread extends Thread implements Runnable, IncomingFrames + private WebSocketPolicy policy; + private ByteBufferPool bufferPool; + private ExtensionFactory extensionFactory; + private DecoratedObjectFactory objectFactory; + + public BlockheadClient() { - public long totalBytes = 0; - public long totalReadOps = 0; - public long totalParseOps = 0; - - public LinkedBlockingQueue frames = new LinkedBlockingQueue<>(); - public LinkedBlockingQueue errors = new LinkedBlockingQueue<>(); - - @Override - public void run() - { - LOG.debug("Reading frames from server"); - - byte buf[] = new byte[BUFFER_SIZE]; - try - { - if ((remainingBuffer != null) && (remainingBuffer.remaining() > 0)) - { - LOG.debug("Reading bytes received during response header parse: {}",BufferUtil.toDetailString(remainingBuffer)); - totalBytes += remainingBuffer.remaining(); - totalReadOps++; - parser.parse(remainingBuffer); - } - - int len = 0; - int available = 0; - while (!eof) - { - available = in.available(); - len = in.read(buf,0,Math.min(available,buf.length)); - totalReadOps++; - if (len < 0) - { - eof = true; - break; - } - else if (len > 0) - { - totalBytes += len; - ByteBuffer bbuf = ByteBuffer.wrap(buf,0,len); - if (LOG.isDebugEnabled()) - { - LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(bbuf)); - } - totalParseOps++; - parser.parse(bbuf); - } - } - } - catch (IOException e) - { - LOG.debug(e); - } - } - - @Override - public String toString() - { - StringBuilder str = new StringBuilder(); - str.append("FrameReadingThread["); - str.append(",frames=" + frames.size()); - str.append(",errors=" + errors.size()); - str.append(String.format(",totalBytes=%,d",totalBytes)); - str.append(String.format(",totalReadOps=%,d",totalReadOps)); - str.append(String.format(",totalParseOps=%,d",totalParseOps)); - str.append("]"); - return str.toString(); - } - - @Override - public synchronized void incomingError(Throwable t) - { - this.errors.add(t); - } - - @Override - public synchronized void incomingFrame(Frame frame) - { - this.frames.add(WebSocketFrame.copy(frame)); - } - - public synchronized void clear() - { - this.frames.clear(); - this.errors.clear(); - } + super(null); + setName("Blockhead-CLIENT"); + this.policy = new WebSocketPolicy(WebSocketBehavior.CLIENT); + this.bufferPool = new MappedByteBufferPool(); + this.extensionFactory = new WebSocketExtensionFactory(this); + this.objectFactory = new DecoratedObjectFactory(); } - private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ=="; - private static final int BUFFER_SIZE = 64 * 1024; - private static final Logger LOG = Log.getLogger(BlockheadClient.class); - private final URI destHttpURI; - private final URI destWebsocketURI; - private final ByteBufferPool bufferPool; - private final Generator generator; - private final Parser parser; - - private final WebSocketExtensionFactory extensionFactory; - private FrameReadingThread frameReader; - - private ExecutorService executor; - private Socket socket; - private OutputStream out; - private InputStream in; - private int version = 13; // default to RFC-6455 - private String protocols; - private List extensions = new ArrayList<>(); - private List headers = new ArrayList<>(); - private byte[] clientmask = new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }; - private int timeout = 1000; - private OutgoingFrames outgoing = this; - private boolean eof = false; - private ExtensionStack extensionStack; - private IOState ioState; - private CountDownLatch disconnectedLatch = new CountDownLatch(1); - private ByteBuffer remainingBuffer; - - private String connectionValue = "Upgrade"; - - public BlockheadClient(URI destWebsocketURI) throws URISyntaxException + public ByteBufferPool getBufferPool() { - this(WebSocketPolicy.newClientPolicy(),destWebsocketURI); - } - - public BlockheadClient(WebSocketPolicy policy, URI destWebsocketURI) throws URISyntaxException - { - Assert.assertThat("Websocket URI scheme",destWebsocketURI.getScheme(),anyOf(is("ws"),is("wss"))); - this.destWebsocketURI = destWebsocketURI; - if (destWebsocketURI.getScheme().equals("wss")) - { - throw new RuntimeException("Sorry, BlockheadClient does not support SSL"); - } - this.destHttpURI = WSURI.toHttp(destWebsocketURI); - - LOG.debug("WebSocket URI: {}",destWebsocketURI); - LOG.debug(" HTTP URI: {}",destHttpURI); - - // This is a blockhead client, no point tracking leaks on this object. - this.bufferPool = new MappedByteBufferPool(8192); - this.generator = new Generator(policy,bufferPool); - this.parser = new Parser(policy,bufferPool); - - this.extensionFactory = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool)); - this.ioState = new IOState(); - this.ioState.addListener(this); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#addExtensions(java.lang.String) - */ - @Override - public void addExtensions(String xtension) - { - this.extensions.add(xtension); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#addHeader(java.lang.String) - */ - @Override - public void addHeader(String header) - { - this.headers.add(header); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#awaitDisconnect(long, java.util.concurrent.TimeUnit) - */ - @Override - public boolean awaitDisconnect(long timeout, TimeUnit unit) throws InterruptedException - { - return disconnectedLatch.await(timeout,unit); - } - - public void clearCaptured() - { - frameReader.clear(); - } - - public void clearExtensions() - { - extensions.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#close() - */ - @Override - public void close() - { - LOG.debug("close()"); - close(-1,null); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#close(int, java.lang.String) - */ - @Override - public void close(int statusCode, String message) - { - LOG.debug("close({},{})",statusCode,message); - CloseInfo close = new CloseInfo(statusCode,message); - - if (!ioState.isClosed()) - { - ioState.onCloseLocal(close); - } - else - { - LOG.debug("Not issuing close. ioState = {}",ioState); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#connect() - */ - @Override - public void connect() throws IOException - { - InetAddress destAddr = InetAddress.getByName(destHttpURI.getHost()); - int port = destHttpURI.getPort(); - - SocketAddress endpoint = new InetSocketAddress(destAddr,port); - - socket = new Socket(); - socket.setSoTimeout(timeout); - socket.connect(endpoint); - - out = socket.getOutputStream(); - in = socket.getInputStream(); + return bufferPool; } @Override - public void disconnect() + public DecoratedObjectFactory getObjectFactory() { - LOG.debug("disconnect"); - IO.close(in); - IO.close(out); - disconnectedLatch.countDown(); - if (frameReader != null) - { - frameReader.interrupt(); - } - if (socket != null) - { - try - { - socket.close(); - } - catch (IOException ignore) - { - /* ignore */ - } - } + return objectFactory; } - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#expectServerDisconnect() - */ - @Override - public void expectServerDisconnect() + public ExtensionFactory getExtensionFactory() { - if (eof) - { - return; - } - - try - { - int len = in.read(); - if (len == (-1)) - { - // we are disconnected - eof = true; - return; - } - - Assert.assertThat("Expecting no data and proper socket disconnect (issued from server)",len,is(-1)); - } - catch (SocketTimeoutException e) - { - LOG.warn(e); - Assert.fail("Expected a server initiated disconnect, instead the read timed out"); - } - catch (IOException e) - { - // acceptable path - } + return extensionFactory; } - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#expectUpgradeResponse() - */ - @Override - public HttpResponse expectUpgradeResponse() throws IOException + public WebSocketPolicy getPolicy() { - HttpResponse response = readResponseHeader(); - - if (LOG.isDebugEnabled()) - { - LOG.debug("Response Header: {}{}",'\n',response); - } - - Assert.assertThat("Response Status Code",response.getStatusCode(),is(101)); - Assert.assertThat("Response Status Reason",response.getStatusReason(),is("Switching Protocols")); - Assert.assertThat("Response Header[Upgrade]",response.getHeader("Upgrade"),is("WebSocket")); - Assert.assertThat("Response Header[Connection]",response.getHeader("Connection"),is("Upgrade")); - - // Validate the Sec-WebSocket-Accept - String acceptKey = response.getHeader("Sec-WebSocket-Accept"); - Assert.assertThat("Response Header[Sec-WebSocket-Accept Exists]",acceptKey,notNullValue()); - - String reqKey = REQUEST_HASH_KEY; - String expectedHash = AcceptHash.hashKey(reqKey); - - Assert.assertThat("Valid Sec-WebSocket-Accept Hash?",acceptKey,is(expectedHash)); - - // collect extensions configured in response header - List configs = getExtensionConfigs(response); - extensionStack = new ExtensionStack(this.extensionFactory); - extensionStack.negotiate(configs); - - // Setup Frame Reader - this.frameReader = new FrameReadingThread(); - this.frameReader.start(); - - // Start with default routing - extensionStack.setNextIncoming(frameReader); // the websocket layer - extensionStack.setNextOutgoing(outgoing); // the network layer - - // Configure Parser / Generator - extensionStack.configure(parser); - extensionStack.configure(generator); - - // Start Stack - try - { - extensionStack.start(); - } - catch (Exception e) - { - throw new IOException("Unable to start Extension Stack"); - } - - // configure parser - parser.setIncomingFramesHandler(extensionStack); - ioState.onOpened(); - - LOG.debug("outgoing = {}",outgoing); - LOG.debug("incoming = {}",extensionStack); - - return response; + return policy; } - public void flush() throws IOException + public BlockheadClientRequest newWsRequest(URI destURI) { - out.flush(); - } - - public String getConnectionValue() - { - return connectionValue; - } - - public ExecutorService getExecutor() - { - if (executor == null) - { - executor = Executors.newCachedThreadPool(); - } - return executor; - } - - private List getExtensionConfigs(HttpResponse response) - { - List configs = new ArrayList<>(); - - String econf = response.getHeader("Sec-WebSocket-Extensions"); - if (econf != null) - { - LOG.debug("Found Extension Response: {}",econf); - ExtensionConfig config = ExtensionConfig.parse(econf); - configs.add(config); - } - return configs; - } - - public List getExtensions() - { - return extensions; - } - - public URI getHttpURI() - { - return destHttpURI; + return new BlockheadClientRequest(this, destURI); } @Override - public InetSocketAddress getLocalSocketAddress() - { - return (InetSocketAddress)socket.getLocalSocketAddress(); - } - - public IOState getIOState() - { - return ioState; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#getProtocols() - */ - @Override - public String getProtocols() - { - return protocols; - } - + public void onSessionOpened(WebSocketSession session) + { /* ignored */ } @Override - public InetSocketAddress getRemoteSocketAddress() - { - return (InetSocketAddress)socket.getRemoteSocketAddress(); - } - - public String getRequestHost() - { - if (destHttpURI.getPort() > 0) - { - return String.format("%s:%d",destHttpURI.getHost(),destHttpURI.getPort()); - } - else - { - return destHttpURI.getHost(); - } - } - - public String getRequestPath() - { - StringBuilder path = new StringBuilder(); - path.append(destHttpURI.getPath()); - if (StringUtil.isNotBlank(destHttpURI.getQuery())) - { - path.append('?').append(destHttpURI.getRawQuery()); - } - return path.toString(); - } - - public String getRequestWebSocketKey() - { - return REQUEST_HASH_KEY; - } - - public String getRequestWebSocketOrigin() - { - return destWebsocketURI.toASCIIString(); - } - - public int getVersion() - { - return version; - } - - public URI getWebsocketURI() - { - return destWebsocketURI; - } - - public boolean isConnected() - { - return (socket != null) && (socket.isConnected()); - } - - @Override - public void onConnectionStateChange(ConnectionState state) - { - LOG.debug("CLIENT onConnectionStateChange() - {}",state); - switch (state) - { - case CLOSED: - // Per Spec, client should not initiate disconnect on its own - // this.disconnect(); - break; - case CLOSING: - CloseInfo close = ioState.getCloseInfo(); - - WebSocketFrame frame = close.asFrame(); - LOG.debug("Issuing: {}",frame); - try - { - write(frame); - } - catch (IOException e) - { - LOG.debug(e); - } - break; - default: - /* do nothing */ - break; - } - } - - @Override - public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode) - { - ByteBuffer headerBuf = generator.generateHeaderBytes(frame); - if (LOG.isDebugEnabled()) - { - LOG.debug("writing out: {}",BufferUtil.toDetailString(headerBuf)); - } - try - { - BufferUtil.writeTo(headerBuf,out); - BufferUtil.writeTo(frame.getPayload(),out); - out.flush(); - if (callback != null) - { - callback.writeSuccess(); - } - } - catch (IOException e) - { - if (callback != null) - { - callback.writeFailed(e); - } - } - finally - { - bufferPool.release(headerBuf); - } - - if (frame.getOpCode() == OpCode.CLOSE) - { - disconnect(); - } - } - - @Override - public LinkedBlockingQueue getFrameQueue() - { - return frameReader.frames; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#readResponseHeader() - */ - @Override - public HttpResponse readResponseHeader() throws IOException - { - HttpResponse response = new HttpResponse(); - HttpResponseHeaderParser respParser = new HttpResponseHeaderParser(response); - - byte buf[] = new byte[512]; - - while (!eof) - { - int available = in.available(); - int len = in.read(buf,0,Math.min(available,buf.length)); - if (len < 0) - { - eof = true; - break; - } - else if (len > 0) - { - ByteBuffer bbuf = ByteBuffer.wrap(buf,0,len); - if (LOG.isDebugEnabled()) - { - LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(bbuf)); - } - if (respParser.parse(bbuf) != null) - { - break; - } - } - } - - remainingBuffer = response.getRemainingBuffer(); - - return response; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#sendStandardRequest() - */ - @Override - public void sendStandardRequest() throws IOException - { - StringBuilder req = generateUpgradeRequest(); - writeRaw(req.toString()); - } - - public StringBuilder generateUpgradeRequest() - { - StringBuilder req = new StringBuilder(); - req.append("GET ").append(getRequestPath()).append(" HTTP/1.1\r\n"); - req.append("Host: ").append(getRequestHost()).append("\r\n"); - req.append("Upgrade: websocket\r\n"); - req.append("User-Agent: BlockheadClient/JettyTests\r\n"); - req.append("Connection: ").append(connectionValue).append("\r\n"); - for (String header : headers) - { - req.append(header); - } - req.append("Sec-WebSocket-Key: ").append(getRequestWebSocketKey()).append("\r\n"); - req.append("Sec-WebSocket-Origin: ").append(getRequestWebSocketOrigin()).append("\r\n"); - if (StringUtil.isNotBlank(protocols)) - { - req.append("Sec-WebSocket-Protocol: ").append(protocols).append("\r\n"); - } - - for (String xtension : extensions) - { - req.append("Sec-WebSocket-Extensions: ").append(xtension).append("\r\n"); - } - req.append("Sec-WebSocket-Version: ").append(version).append("\r\n"); - req.append("\r\n"); - return req; - } - - @Override - public void setConnectionValue(String connectionValue) - { - this.connectionValue = connectionValue; - } - - public void setExecutor(ExecutorService executor) - { - this.executor = executor; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#setProtocols(java.lang.String) - */ - @Override - public void setProtocols(String protocols) - { - this.protocols = protocols; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#setTimeout(int, java.util.concurrent.TimeUnit) - */ - @Override - public void setTimeout(int duration, TimeUnit unit) - { - this.timeout = (int)TimeUnit.MILLISECONDS.convert(duration,unit); - } - - public void setVersion(int version) - { - this.version = version; - } - - public void skipTo(String string) throws IOException - { - int state = 0; - - while (true) - { - int b = in.read(); - if (b < 0) - { - throw new EOFException(); - } - - if (b == string.charAt(state)) - { - state++; - if (state == string.length()) - { - break; - } - } - else - { - state = 0; - } - } - } - - public void sleep(TimeUnit unit, int duration) throws InterruptedException - { - LOG.info("Sleeping for {} {}",duration,unit); - unit.sleep(duration); - LOG.info("Waking up from sleep"); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#write(org.eclipse.jetty.websocket.common.WebSocketFrame) - */ - @Override - public void write(WebSocketFrame frame) throws IOException - { - if (!ioState.isOpen()) - { - LOG.debug("IO Not Open / Not Writing: {}",frame); - return; - } - LOG.debug("write(Frame->{}) to {}",frame,outgoing); - if (LOG.isDebugEnabled()) - { - frame.setMask(new byte[] { 0x00, 0x00, 0x00, 0x00 }); - } - else - { - frame.setMask(clientmask); - } - extensionStack.outgoingFrame(frame,null,BatchMode.OFF); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRaw(java.nio.ByteBuffer) - */ - @Override - public void writeRaw(ByteBuffer buf) throws IOException - { - LOG.debug("write(ByteBuffer) {}",BufferUtil.toDetailString(buf)); - BufferUtil.writeTo(buf,out); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRaw(java.nio.ByteBuffer, int) - */ - @Override - public void writeRaw(ByteBuffer buf, int numBytes) throws IOException - { - int len = Math.min(numBytes,buf.remaining()); - byte arr[] = new byte[len]; - buf.get(arr,0,len); - out.write(arr); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRaw(java.lang.String) - */ - @Override - public void writeRaw(String str) throws IOException - { - LOG.debug("write((String)[{}]){}{})",str.length(),'\n',str); - out.write(str.getBytes(StandardCharsets.ISO_8859_1)); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRawSlowly(java.nio.ByteBuffer, int) - */ - @Override - public void writeRawSlowly(ByteBuffer buf, int segmentSize) throws IOException - { - while (buf.remaining() > 0) - { - writeRaw(buf,segmentSize); - flush(); - } - } + public void onSessionClosed(WebSocketSession session) + { /* ignored */ } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java new file mode 100644 index 00000000000..72d7ff2c859 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.common.test; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadLocalRandom; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; + +public class BlockheadClientConnection extends BlockheadConnection +{ + public BlockheadClientConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + { + super(policy, bufferPool, extensionStack, endp, executor); + } + + @Override + public void write(WebSocketFrame frame) + { + if (frame.getMask() == null) + { + byte mask[] = new byte[4]; + ThreadLocalRandom.current().nextBytes(mask); + frame.setMask(mask); + } + super.write(frame); + } +} \ No newline at end of file diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java deleted file mode 100644 index 87ebe51ba0f..00000000000 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.common.test; - -import static org.hamcrest.Matchers.is; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * Gotta test some basic constructors of the BlockheadClient. - */ -@RunWith(value = Parameterized.class) -public class BlockheadClientConstructionTest -{ - @Parameters - public static Collection data() - { - List data = new ArrayList<>(); - // @formatter:off - data.add(new Object[] { "ws://localhost/", "http://localhost/" }); - data.add(new Object[] { "ws://localhost:8080/", "http://localhost:8080/" }); - data.add(new Object[] { "ws://webtide.com/", "http://webtide.com/" }); - data.add(new Object[] { "ws://www.webtide.com/sockets/chat", "http://www.webtide.com/sockets/chat" }); - // @formatter:on - return data; - } - - private URI expectedWsUri; - private URI expectedHttpUri; - - public BlockheadClientConstructionTest(String wsuri, String httpuri) - { - this.expectedWsUri = URI.create(wsuri); - this.expectedHttpUri = URI.create(httpuri); - } - - @Test - public void testURIs() throws URISyntaxException - { - @SuppressWarnings("resource") - BlockheadClient client = new BlockheadClient(expectedWsUri); - Assert.assertThat("Websocket URI",client.getWebsocketURI(),is(expectedWsUri)); - Assert.assertThat("Websocket URI",client.getHttpURI(),is(expectedHttpUri)); - } - -} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java new file mode 100644 index 00000000000..8dd9b2801f9 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java @@ -0,0 +1,252 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.common.test; + +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.client.HttpConversation; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; +import org.eclipse.jetty.client.http.HttpConnectionUpgrader; +import org.eclipse.jetty.client.util.ByteBufferContentProvider; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.B64Code; +import org.eclipse.jetty.util.QuotedStringTokenizer; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.UpgradeException; +import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; +import org.eclipse.jetty.websocket.common.AcceptHash; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; + +public class BlockheadClientRequest extends HttpRequest implements Response.CompleteListener, HttpConnectionUpgrader +{ + private static final Logger LOG = Log.getLogger(BlockheadClientRequest.class); + private final BlockheadClient client; + private final CompletableFuture fut; + + protected BlockheadClientRequest(BlockheadClient client, URI uri) + { + super(client, new HttpConversation(), uri); + this.client = client; + this.fut = new CompletableFuture<>(); + } + + public void setInitialBytes(ByteBuffer initialBytes) + { + content(new RawBytesProvider(initialBytes)); + } + + private final String genRandomKey() + { + byte[] bytes = new byte[16]; + ThreadLocalRandom.current().nextBytes(bytes); + return new String(B64Code.encode(bytes)); + } + + private void initWebSocketHeaders() + { + method(HttpMethod.GET); + version(HttpVersion.HTTP_1_1); + + HttpFields fields = getHeaders(); + + // The Upgrade Headers + if (!fields.contains(HttpHeader.UPGRADE)) + header(HttpHeader.UPGRADE, "websocket"); + if (!fields.contains(HttpHeader.CONNECTION)) + header(HttpHeader.CONNECTION, "Upgrade"); + + // The WebSocket Headers + if (!fields.contains(HttpHeader.SEC_WEBSOCKET_KEY)) + header(HttpHeader.SEC_WEBSOCKET_KEY, genRandomKey()); + if (!fields.contains(HttpHeader.SEC_WEBSOCKET_VERSION)) + header(HttpHeader.SEC_WEBSOCKET_VERSION, "13"); + + // (Per the hybi list): Add no-cache headers to avoid compatibility issue. + // There are some proxies that rewrite "Connection: upgrade" + // to "Connection: close" in the response if a request doesn't contain + // these headers. + if (!fields.contains(HttpHeader.PRAGMA)) + header(HttpHeader.PRAGMA, "no-cache"); + if (!fields.contains(HttpHeader.CACHE_CONTROL)) + header(HttpHeader.CACHE_CONTROL, "no-cache"); + } + + @Override + public ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException + { + throw new RuntimeException("Working with raw ContentResponse is invalid for WebSocket"); + } + + @Override + public void send(final Response.CompleteListener listener) + { + initWebSocketHeaders(); + super.send(listener); + } + + public CompletableFuture sendAsync() + { + send(this); + return fut; + } + + @Override + public void onComplete(Result result) + { + if (LOG.isDebugEnabled()) + { + LOG.debug("onComplete() - {}", result); + } + + URI requestURI = result.getRequest().getURI(); + Response response = result.getResponse(); + int responseStatusCode = response.getStatus(); + String responseLine = responseStatusCode + " " + response.getReason(); + + if (result.isFailed()) + { + if (LOG.isDebugEnabled()) + { + if (result.getFailure() != null) + LOG.debug("General Failure", result.getFailure()); + if (result.getRequestFailure() != null) + LOG.debug("Request Failure", result.getRequestFailure()); + if (result.getResponseFailure() != null) + LOG.debug("Response Failure", result.getResponseFailure()); + } + + Throwable failure = result.getFailure(); + if ((failure instanceof java.net.ConnectException) || (failure instanceof UpgradeException)) + { + // handle as-is + handleException(failure); + } + else + { + // wrap in UpgradeException + handleException(new UpgradeException(requestURI, responseStatusCode, responseLine, failure)); + } + } + + if (responseStatusCode != HttpStatus.SWITCHING_PROTOCOLS_101) + { + // Failed to upgrade (other reason) + handleException(new UpgradeException(requestURI, responseStatusCode, responseLine)); + } + } + + private void handleException(Throwable failure) + { + fut.completeExceptionally(failure); + } + + @Override + public void upgrade(HttpResponse response, HttpConnectionOverHTTP oldConn) + { + if (!this.getHeaders().get(HttpHeader.UPGRADE).equalsIgnoreCase("websocket")) + { + // Not my upgrade + throw new HttpResponseException("Not WebSocket Upgrade", response); + } + + // Check the Accept hash + String reqKey = this.getHeaders().get(HttpHeader.SEC_WEBSOCKET_KEY); + String expectedHash = AcceptHash.hashKey(reqKey); + String respHash = response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_ACCEPT); + + if (expectedHash.equalsIgnoreCase(respHash) == false) + { + throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash", response); + } + + // We can upgrade + EndPoint endp = oldConn.getEndPoint(); + + ExtensionStack extensionStack = new ExtensionStack(client.getExtensionFactory()); + List extensions = new ArrayList<>(); + HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + if (extField != null) + { + String[] extValues = extField.getValues(); + if (extValues != null) + { + for (String extVal : extValues) + { + QuotedStringTokenizer tok = new QuotedStringTokenizer(extVal, ","); + while (tok.hasMoreTokens()) + { + extensions.add(ExtensionConfig.parse(tok.nextToken())); + } + } + } + } + extensionStack.negotiate(extensions); + + BlockheadClientConnection connection = new BlockheadClientConnection( + client.getPolicy(), + client.getBufferPool(), + extensionStack, + endp, + client.getExecutor()); + + connection.setUpgradeResponseHeaders(response.getHeaders()); + + // Now swap out the connection + endp.upgrade(connection); + + fut.complete(connection); + } + + /** + * Raw Bytes Content Provider (intentionally without a Content-Type) + */ + public static class RawBytesProvider extends ByteBufferContentProvider + { + public RawBytesProvider(ByteBuffer buf) + { + super(buf); + } + + @Override + public String getContentType() + { + return null; + } + } +} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java new file mode 100644 index 00000000000..2269e7f3f14 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java @@ -0,0 +1,373 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.common.test; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; + +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.io.AbstractConnection; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.BufferUtil; +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.BatchMode; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.api.WriteCallback; +import org.eclipse.jetty.websocket.api.extensions.Frame; +import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; +import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; +import org.eclipse.jetty.websocket.common.Generator; +import org.eclipse.jetty.websocket.common.Parser; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; + +public class BlockheadConnection extends AbstractConnection implements Connection.UpgradeTo +{ + private final static int BUFFER_SIZE = 4096; + public static final String STATIC_REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ=="; + private final Logger LOG; + private final WebSocketPolicy policy; + private final ByteBufferPool bufferPool; + private final Parser parser; + private final Generator generator; + private final ExtensionStack extensionStack; + private final OutgoingNetwork networkOutgoing; + private final IncomingCapture incomingCapture; + private ByteBuffer networkBuffer; + private HttpFields upgradeResponseHeaders; + + public BlockheadConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + { + super(endp, executor); + this.LOG = Log.getLogger(this.getClass()); + this.policy = policy; + this.bufferPool = bufferPool; + this.parser = new Parser(policy, bufferPool); + this.generator = new Generator(policy, bufferPool, false); + this.extensionStack = extensionStack; + + this.extensionStack.configure(this.parser); + this.extensionStack.configure(this.generator); + + // Wire up incoming frames (network -> extensionStack -> connection) + this.parser.setIncomingFramesHandler(extensionStack); + this.incomingCapture = new IncomingCapture(); + this.extensionStack.setNextIncoming(incomingCapture); + + // Wire up outgoing frames (connection -> extensionStack -> network) + this.networkOutgoing = new OutgoingNetwork(); + extensionStack.setNextOutgoing(networkOutgoing); + + try + { + extensionStack.start(); + } + catch (Exception e) + { + throw new RuntimeException("Unable to start ExtensionStack", e); + } + } + + public void abort() + { + EndPoint endPoint = getEndPoint(); + // We need to gently close first, to allow + // SSL close alerts to be sent by Jetty + endPoint.shutdownOutput(); + endPoint.close(); + } + + @Override + public void fillInterested() + { + // Handle situation where initial/prefill buffer (from upgrade) has created network buffer, + // but there is no actual read interest (yet) + if (BufferUtil.hasContent(networkBuffer)) + { + fillAndParse(); + } + else + { + super.fillInterested(); + } + } + + public LinkedBlockingQueue getFrameQueue() + { + return incomingCapture.incomingFrames; + } + + public Generator getGenerator() + { + return generator; + } + + public InetSocketAddress getLocalSocketAddress() + { + return getEndPoint().getLocalAddress(); + } + + public Parser getParser() + { + return parser; + } + + public InetSocketAddress getRemoteSocketAddress() + { + return getEndPoint().getRemoteAddress(); + } + + public HttpFields getUpgradeResponseHeaders() + { + return upgradeResponseHeaders; + } + + public boolean isOpen() + { + return getEndPoint().isOpen(); + } + + @Override + public void onFillable() + { + getNetworkBuffer(); + fillAndParse(); + } + + @Override + public void onUpgradeTo(ByteBuffer prefilled) + { + setInitialBuffer(prefilled); + } + + @Override + public void onOpen() + { + super.onOpen(); + fillInterested(); + } + + public void processConnectionError(Throwable cause) + { + LOG.warn("Connection Error", cause); + } + + public void setUpgradeResponseHeaders(HttpFields upgradeResponseHeaders) + { + this.upgradeResponseHeaders = upgradeResponseHeaders; + } + + public void write(WebSocketFrame frame) + { + networkOutgoing.outgoingFrame(frame, null, BatchMode.OFF); + } + + public void writeRaw(ByteBuffer buf) throws IOException + { + getEndPoint().flush(buf); + } + + public void writeRaw(ByteBuffer buf, int numBytes) throws IOException + { + int len = Math.min(numBytes, buf.remaining()); + ByteBuffer slice = buf.slice(); + buf.position(len); + try + { + getEndPoint().flush(slice); + } + catch (IOException e) + { + throw e; + } + finally + { + buf.position(buf.position() + len); + } + } + + public void writeRawSlowly(ByteBuffer buf, int segmentSize) throws IOException + { + while (buf.remaining() > 0) + { + writeRaw(buf, segmentSize); + } + } + + /** + * Extra bytes from the initial HTTP upgrade that need to + * be processed by the websocket parser before starting + * to read bytes from the connection + * + * @param prefilled the bytes of prefilled content encountered during upgrade + */ + protected void setInitialBuffer(ByteBuffer prefilled) + { + if (LOG.isDebugEnabled()) + { + LOG.debug("set Initial Buffer - {}", BufferUtil.toDetailString(prefilled)); + } + + if ((prefilled != null) && (prefilled.hasRemaining())) + { + networkBuffer = bufferPool.acquire(prefilled.remaining(), true); + BufferUtil.clearToFill(networkBuffer); + BufferUtil.put(prefilled, networkBuffer); + BufferUtil.flipToFlush(networkBuffer, 0); + } + } + + private void fillAndParse() + { + boolean interested = false; + + try + { + while (getEndPoint().isOpen()) + { + ByteBuffer nBuffer = getNetworkBuffer(); + + parser.parse(nBuffer); + + // Shouldn't reach this point if buffer has un-parsed bytes + assert (!nBuffer.hasRemaining()); + + int filled = getEndPoint().fill(nBuffer); + + if (LOG.isDebugEnabled()) + LOG.debug("endpointFill() filled={}: {}", filled, BufferUtil.toDetailString(nBuffer)); + + if (filled < 0) + { + releaseNetworkBuffer(nBuffer); + return; + } + + if (filled == 0) + { + releaseNetworkBuffer(nBuffer); + interested = true; + return; + } + } + } + catch (Throwable t) + { + processConnectionError(t); + } + finally + { + if (interested) + fillInterested(); + } + } + + private ByteBuffer getNetworkBuffer() + { + synchronized (this) + { + if (networkBuffer == null) + { + networkBuffer = bufferPool.acquire(BUFFER_SIZE, true); + } + return networkBuffer; + } + } + + private void releaseNetworkBuffer(ByteBuffer buffer) + { + synchronized (this) + { + assert (!buffer.hasRemaining()); + bufferPool.release(buffer); + networkBuffer = null; + } + } + + public class IncomingCapture implements IncomingFrames + { + public final LinkedBlockingQueue incomingFrames = new LinkedBlockingQueue<>(); + public final LinkedBlockingQueue incomingErrors = new LinkedBlockingQueue<>(); + + @Override + public void incomingError(Throwable cause) + { + incomingErrors.offer(cause); + } + + @Override + public void incomingFrame(Frame frame) + { + incomingFrames.offer(WebSocketFrame.copy(frame)); + } + } + + public class OutgoingNetwork implements OutgoingFrames + { + /** + * Last step for networkOutgoing frames before the network buffer. + *

+ * if ExtensionStack is in play, this should be wired up to the output from + * the ExtensionStack. + *

+ * + * @param frame the frame to eventually write to the network layer. + * @param callback the callback to notify when the frame is written. + * @param batchMode ignored by BlockheadConnections + */ + @Override + public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode) + { + ByteBuffer header = generator.generateHeaderBytes(frame); + ByteBuffer payload = frame.getPayload(); + if (payload == null) + payload = BufferUtil.EMPTY_BUFFER; + + Callback jettyCallback = asJettyCallback(callback); + try + { + getEndPoint().flush(header, payload); + jettyCallback.succeeded(); + } + catch (IOException e) + { + jettyCallback.failed(e); + } + } + + private Callback asJettyCallback(final WriteCallback writeCallback) + { + if (writeCallback instanceof org.eclipse.jetty.util.Callback) + { + return (org.eclipse.jetty.util.Callback) writeCallback; + } + else + { + return new WriteCallbackDelegate(writeCallback); + } + } + } +} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java index 6ab10df9091..b1a9d910198 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java @@ -396,7 +396,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames @Override public void run() { - LOG.debug("Entering echo thread"); + LOG.debug("Entering read thread"); long totalReadBytes = 0; ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE, false); @@ -450,7 +450,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames { throw new IllegalStateException("Read thread already declared/started!"); } - readThread = new Thread(this,"BlockheadServer/Read"); + readThread = new Thread(this,"Blockhead-Server-Read"); LOG.debug("Starting Read Thread: {}", readThread); reading.set(true); readThread.start(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java index 87c74d437e4..26910fcf0e4 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java @@ -27,19 +27,20 @@ import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; 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.api.extensions.Frame; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.Generator; import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; -import org.eclipse.jetty.websocket.common.io.IOState; import org.junit.Assert; /** @@ -47,28 +48,13 @@ import org.junit.Assert; */ public class Fuzzer implements AutoCloseable { - public static enum CloseState - { - OPEN, - REMOTE_INITIATED, - LOCAL_INITIATED - } - - public static enum SendMode + public enum SendMode { BULK, PER_FRAME, SLOW } - public static enum DisconnectMode - { - /** Disconnect occurred after a proper close handshake */ - CLEAN, - /** Disconnect occurred in a harsh manner, without a close handshake */ - UNCLEAN - } - private static final int KBYTE = 1024; private static final int MBYTE = KBYTE * KBYTE; @@ -78,24 +64,26 @@ public class Fuzzer implements AutoCloseable protected static final byte[] MASK = { 0x11, 0x22, 0x33, 0x44 }; + private final Fuzzed testcase; private final BlockheadClient client; private final Generator generator; private final String testname; + private BlockheadConnection clientConnection; private SendMode sendMode = SendMode.BULK; private int slowSendSegmentSize = 5; public Fuzzer(Fuzzed testcase) throws Exception { - WebSocketPolicy policy = WebSocketPolicy.newClientPolicy(); - + this.testcase = testcase; + this.client = new BlockheadClient(); int bigMessageSize = 20 * MBYTE; - policy.setMaxTextMessageSize(bigMessageSize); - policy.setMaxBinaryMessageSize(bigMessageSize); - policy.setIdleTimeout(5000); + client.getPolicy().setMaxTextMessageSize(bigMessageSize); + client.getPolicy().setMaxBinaryMessageSize(bigMessageSize); + client.getPolicy().setIdleTimeout(5000); + + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); - this.client = new BlockheadClient(policy,testcase.getServerURI()); - this.client.setTimeout(2,TimeUnit.SECONDS); this.generator = testcase.getLaxGenerator(); this.testname = testcase.getTestMethodName(); } @@ -120,30 +108,43 @@ public class Fuzzer implements AutoCloseable } @Override - public void close() throws Exception + public void close() { - this.client.disconnect(); + this.clientConnection.close(); } public void disconnect() { - this.client.disconnect(); + this.clientConnection.abort(); } public void connect() throws IOException { - if (!client.isConnected()) + BlockheadClientRequest request = this.client.newWsRequest(testcase.getServerURI()); + request.header("X-TestCase", testname); + Future connFut = request.sendAsync(); + + try { - client.connect(); - client.addHeader("X-TestCase: " + testname + "\r\n"); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + this.clientConnection = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + } + catch (InterruptedException e) + { + throw new IOException("Connect interrupted", e); + } + catch (ExecutionException e) + { + throw new IOException("Connect execution failed", e); + } + catch (TimeoutException e) + { + throw new IOException("Connect timed out", e); } } public void expect(List expect) throws Exception { - expect(expect,10,TimeUnit.SECONDS); + expect(expect, Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); } /** @@ -154,13 +155,13 @@ public class Fuzzer implements AutoCloseable * @param unit the timeout unit to wait for each read frame * @throws Exception if unable to validate expectations */ - public void expect(List expect, int duration, TimeUnit unit) throws Exception + public void expect(List expect, long duration, TimeUnit unit) throws Exception { int expectedCount = expect.size(); LOG.debug("expect() {} frame(s)",expect.size()); // Read frames - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConnection.getFrameQueue(); String prefix = ""; for (int i = 0; i < expectedCount; i++) @@ -198,24 +199,6 @@ public class Fuzzer implements AutoCloseable // TODO Should test for no more frames. success if connection closed. } - public CloseState getCloseState() - { - IOState ios = client.getIOState(); - - if (ios.wasLocalCloseInitiated()) - { - return CloseState.LOCAL_INITIATED; - } - else if (ios.wasRemoteCloseInitiated()) - { - return CloseState.REMOTE_INITIATED; - } - else - { - return CloseState.OPEN; - } - } - public SendMode getSendMode() { return sendMode; @@ -228,27 +211,26 @@ public class Fuzzer implements AutoCloseable public void send(ByteBuffer buf) throws IOException { - Assert.assertThat("Client connected",client.isConnected(),is(true)); + Assert.assertThat("Client connected",clientConnection.isOpen(),is(true)); LOG.debug("Sending bytes {}",BufferUtil.toDetailString(buf)); if (sendMode == SendMode.SLOW) { - client.writeRawSlowly(buf,slowSendSegmentSize); + clientConnection.writeRawSlowly(buf,slowSendSegmentSize); } else { - client.writeRaw(buf); + clientConnection.writeRaw(buf); } } public void send(ByteBuffer buf, int numBytes) throws IOException { - client.writeRaw(buf,numBytes); - client.flush(); + clientConnection.writeRaw(buf, numBytes); } public void send(List send) throws IOException { - Assert.assertThat("Client connected",client.isConnected(),is(true)); + Assert.assertThat("Client connected",clientConnection.isOpen(),is(true)); LOG.debug("[{}] Sending {} frames (mode {})",testname,send.size(),sendMode); if ((sendMode == SendMode.BULK) || (sendMode == SendMode.SLOW)) { @@ -275,10 +257,10 @@ public class Fuzzer implements AutoCloseable switch (sendMode) { case BULK: - client.writeRaw(buf); + clientConnection.writeRaw(buf); break; case SLOW: - client.writeRawSlowly(buf,slowSendSegmentSize); + clientConnection.writeRawSlowly(buf,slowSendSegmentSize); break; default: throw new RuntimeException("Whoops, unsupported sendMode: " + sendMode); @@ -294,8 +276,7 @@ public class Fuzzer implements AutoCloseable BufferUtil.clearToFill(fullframe); generator.generateWholeFrame(f,fullframe); BufferUtil.flipToFlush(fullframe,0); - client.writeRaw(fullframe); - client.flush(); + clientConnection.writeRaw(fullframe); } } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java index d5dceebd266..a44ec00e6dd 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.Parser; import org.eclipse.jetty.websocket.common.WebSocketFrame; +@Deprecated public interface IBlockheadServerConnection { public void close() throws IOException; diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java index fa3321e2f18..b9092fbc6a5 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java @@ -22,6 +22,9 @@ import java.util.concurrent.TimeUnit; public class Timeouts { - public static long POLL_EVENT = 2; - public static TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS; + public static final long CONNECT = 2; + public static final TimeUnit CONNECT_UNIT = TimeUnit.SECONDS; + + public static final long POLL_EVENT = 2; + public static final TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS; } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java new file mode 100644 index 00000000000..0d906c294d1 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.common.test; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.api.WriteCallback; + +public class WriteCallbackDelegate implements Callback +{ + private final WriteCallback delegate; + + public WriteCallbackDelegate(WriteCallback delegate) + { + this.delegate = delegate; + } + + @Override + public void succeeded() + { + if (this.delegate != null) + this.delegate.writeSuccess(); + } + + @Override + public void failed(Throwable x) + { + if (this.delegate != null) + this.delegate.writeFailed(x); + } +} diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java index f24fa3465db..eef290e3ab9 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java @@ -20,15 +20,16 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; -import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -37,20 +38,19 @@ import org.eclipse.jetty.websocket.common.Parser; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.echo.BigEchoSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; public class AnnotatedMaxMessageSizeTest { - @Rule - public TestTracker tracker = new TestTracker(); - + private static BlockheadClient client; private static Server server; private static ServerConnector connector; private static URI serverUri; @@ -89,59 +89,64 @@ public class AnnotatedMaxMessageSizeTest server.stop(); } - @Test - public void testEchoGood() throws IOException, Exception + @BeforeClass + public static void startClient() throws Exception { - BlockheadClient client = new BlockheadClient(serverUri); - try - { - client.setProtocols("echo"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + + @Test + public void testEchoGood() throws Exception + { + BlockheadClientRequest request = client.newWsRequest(serverUri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } @Test(timeout=8000) - public void testEchoTooBig() throws IOException, Exception + public void testEchoTooBig() throws Exception { - BlockheadClient client = new BlockheadClient(serverUri); - try(StacklessLogging logging = new StacklessLogging(Parser.class)) - { - client.setProtocols("echo"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(serverUri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo"); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(Parser.class)) + { // Generate text frame int size = 120 * 1024; byte buf[] = new byte[size]; // buffer bigger than maxMessageSize Arrays.fill(buf,(byte)'x'); - client.write(new TextFrame().setPayload(ByteBuffer.wrap(buf))); + clientConn.write(new TextFrame().setPayload(ByteBuffer.wrap(buf))); // Read frame (hopefully close frame saying its too large) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame is close", tf.getOpCode(), is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(tf); Assert.assertThat("Close Code", close.getStatusCode(), is(StatusCode.MESSAGE_TOO_LARGE)); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java index aa3437c9255..cb67178343e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java @@ -21,12 +21,18 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; @@ -37,6 +43,7 @@ import org.junit.Test; public class ChromeTest { + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -52,34 +59,49 @@ public class ChromeTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testUpgradeWithWebkitDeflateExtension() throws Exception { Assume.assumeTrue("Server has x-webkit-deflate-frame registered", server.getWebSocketServletFactory().getExtensionFactory().isAvailable("x-webkit-deflate-frame")); - - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + + Assume.assumeTrue("Client has x-webkit-deflate-frame registered", + client.getExtensionFactory().isAvailable("x-webkit-deflate-frame")); + + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "x-webkit-deflate-frame"); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "chat"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.addExtensions("x-webkit-deflate-frame"); - client.setProtocols("chat"); - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.expectUpgradeResponse(); - Assert.assertThat("Response",response.getExtensionsHeader(),containsString("x-webkit-deflate-frame")); + HttpFields responseFields = clientConn.getUpgradeResponseHeaders(); + HttpField extensionField = responseFields.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + Assert.assertThat("Response", extensionField.getValue(),containsString("x-webkit-deflate-frame")); // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java index 8dbf77587a3..45b37b1685d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -36,6 +37,8 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -50,29 +53,30 @@ import org.junit.Test; @Ignore("Unstable - see Issue #1815") public class DecoratorsLegacyTest { + private static class DecoratorsSocket extends WebSocketAdapter { private final DecoratedObjectFactory objFactory; - + public DecoratorsSocket(DecoratedObjectFactory objFactory) { this.objFactory = objFactory; } - + @Override public void onWebSocketText(String message) { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); - + if (objFactory != null) { out.printf("Object is a DecoratedObjectFactory%n"); List decorators = objFactory.getDecorators(); - out.printf("Decorators.size = [%d]%n",decorators.size()); + out.printf("Decorators.size = [%d]%n", decorators.size()); for (Decorator decorator : decorators) { - out.printf(" decorator[] = %s%n",decorator.getClass().getName()); + out.printf(" decorator[] = %s%n", decorator.getClass().getName()); } } else @@ -90,7 +94,7 @@ public class DecoratorsLegacyTest public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { ServletContext servletContext = req.getHttpServletRequest().getServletContext(); - DecoratedObjectFactory objFactory = (DecoratedObjectFactory)servletContext.getAttribute(DecoratedObjectFactory.ATTR); + DecoratedObjectFactory objFactory = (DecoratedObjectFactory) servletContext.getAttribute(DecoratedObjectFactory.ATTR); return new DecoratorsSocket(objFactory); } } @@ -111,7 +115,7 @@ public class DecoratorsLegacyTest factory.setCreator(this.creator); } } - + @SuppressWarnings("deprecation") private static class DummyLegacyDecorator implements org.eclipse.jetty.servlet.ServletContextHandler.Decorator { @@ -127,6 +131,7 @@ public class DecoratorsLegacyTest } } + private static BlockheadClient client; private static SimpleServletServer server; private static DecoratorsCreator decoratorsCreator; @@ -154,31 +159,39 @@ public class DecoratorsLegacyTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testAccessRequestCookies() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setTimeout(1,TimeUnit.SECONDS); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.idleTimeout(1, TimeUnit.SECONDS); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("info")); + clientConn.write(new TextFrame().setPayload("info")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String textMsg = resp.getPayloadAsUTF8(); - + assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory")); assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]")); assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyLegacyDecorator.class.getName())); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java index 3753d360e56..1428aea3029 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -36,6 +37,8 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -44,10 +47,8 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; -@Ignore public class DecoratorsTest { private static class DecoratorsSocket extends WebSocketAdapter @@ -126,6 +127,7 @@ public class DecoratorsTest } } + private static BlockheadClient client; private static SimpleServletServer server; private static DecoratorsCreator decoratorsCreator; @@ -152,21 +154,32 @@ public class DecoratorsTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testAccessRequestCookies() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setTimeout(1,TimeUnit.SECONDS); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("info")); + clientConn.write(new TextFrame().setPayload("info")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String textMsg = resp.getPayloadAsUTF8(); @@ -174,9 +187,5 @@ public class DecoratorsTest assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]")); assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyUtilDecorator.class.getName())); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java index bebbf78aa14..e8b6661425d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java @@ -20,12 +20,16 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -34,39 +38,45 @@ import org.junit.Test; public class FirefoxTest { + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass - public static void startServer() throws Exception + public static void startContainers() throws Exception { server = new SimpleServletServer(new MyEchoServlet()); server.start(); + + client = new BlockheadClient(); + client.start(); } @AfterClass - public static void stopServer() + public static void stopContainers() throws Exception { + client.stop(); server.stop(); } @Test public void testConnectionKeepAlive() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) - { - // Odd Connection Header value seen in Firefox - client.setConnectionValue("keep-alive, Upgrade"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + // Odd Connection Header value seen in older Firefox versions + request.header(HttpHeader.CONNECTION, "keep-alive, Upgrade"); + + Future connFut = request.sendAsync(); + + try(BlockheadConnection conn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + conn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = conn.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code", tf.getPayloadAsUTF8(), is(msg)); } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java index de089f26845..4bd4e9af557 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java @@ -21,23 +21,30 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; public class FragmentExtensionTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -52,6 +59,20 @@ public class FragmentExtensionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + private String[] split(String str, int partSize) { int strLength = str.length(); @@ -69,37 +90,39 @@ public class FragmentExtensionTest @Test public void testFragmentExtension() throws Exception { + Assume.assumeTrue("Server has fragment registered", + server.getWebSocketServletFactory().getExtensionFactory().isAvailable("fragment")); + + Assume.assumeTrue("Client has fragment registered", + client.getExtensionFactory().isAvailable("fragment")); + int fragSize = 4; - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.clearExtensions(); - client.addExtensions("fragment;maxLength=" + fragSize); - client.setProtocols("onConnect"); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "fragment;maxLength=" + fragSize); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect"); + request.idleTimeout(1, TimeUnit.SECONDS); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // Make sure the read times out if there are problems with the implementation - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - HttpResponse resp = client.expectUpgradeResponse(); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); - Assert.assertThat("Response",resp.getExtensionsHeader(),containsString("fragment")); + Assert.assertThat("Response",extensionHeader.getValue(),containsString("fragment")); String msg = "Sent as a long message that should be split"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); String parts[] = split(msg,fragSize); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); for (int i = 0; i < parts.length; i++) { WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i])); } } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java index 49c4b268553..9ea5577186e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java @@ -21,13 +21,18 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; @@ -38,6 +43,7 @@ import org.junit.Test; public class IdentityExtensionTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -52,34 +58,43 @@ public class IdentityExtensionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testIdentityExtension() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.clearExtensions(); - client.addExtensions("identity;param=0"); - client.addExtensions("identity;param=1, identity ; param = '2' ; other = ' some = value '"); - client.setProtocols("onConnect"); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity;param=0"); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity;param=1, identity ; param = '2' ; other = ' some = value '"); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect"); + request.idleTimeout(1, TimeUnit.SECONDS); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - // Make sure the read times out if there are problems with the implementation - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - HttpResponse resp = client.expectUpgradeResponse(); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); - Assert.assertThat("Response",resp.getExtensionsHeader(),containsString("identity")); + Assert.assertThat("Response", extensionHeader.getValue(), containsString("identity")); - client.write(new TextFrame().setPayload("Hello")); + clientConn.write(new TextFrame().setPayload("Hello")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello")); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java index 9174d1e8ab0..704527f1b1f 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java @@ -21,15 +21,19 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; @@ -41,17 +45,23 @@ import org.junit.Test; public class IdleTimeoutTest { + + public static final int IDLE_TIMEOUT_MS_WEBSOCKET_SERVER = 500; + public static final int IDLE_TIMEOUT_ON_SERVER = 1000; + public static final int IDLE_TIMEOUT_MS_WEBSOCKET_CLIENT = 2500; + @SuppressWarnings("serial") public static class TimeoutServlet extends WebSocketServlet { @Override public void configure(WebSocketServletFactory factory) { - factory.getPolicy().setIdleTimeout(500); + factory.getPolicy().setIdleTimeout(IDLE_TIMEOUT_MS_WEBSOCKET_SERVER); factory.register(RFCSocket.class); } } + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -67,6 +77,20 @@ public class IdleTimeoutTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test IdleTimeout on server. * @throws Exception on test failure @@ -74,37 +98,32 @@ public class IdleTimeoutTest @Test public void testIdleTimeout() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setProtocols("onConnect"); - client.setTimeout(2500,TimeUnit.MILLISECONDS); - try - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect"); + request.idleTimeout(IDLE_TIMEOUT_MS_WEBSOCKET_CLIENT, TimeUnit.MILLISECONDS); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // This wait should be shorter than client timeout above, but // longer than server timeout configured in TimeoutServlet - client.sleep(TimeUnit.MILLISECONDS,1000); + TimeUnit.MILLISECONDS.sleep(IDLE_TIMEOUT_ON_SERVER); // Write to server // This action is possible, but does nothing. // Server could be in a half-closed state at this point. // Where the server read is closed (due to timeout), but the server write is still open. // The server could not read this frame, if it is in this half closed state - client.write(new TextFrame().setPayload("Hello")); + clientConn.write(new TextFrame().setPayload("Hello")); // Expect server to have closed due to its own timeout - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("frame opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); Assert.assertThat("close code",close.getStatusCode(),is(StatusCode.SHUTDOWN)); Assert.assertThat("close reason",close.getReason(),containsString("Timeout")); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java index 0e819ec7d68..6b2b03231fd 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java @@ -18,21 +18,23 @@ package org.eclipse.jetty.websocket.server; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketAdapter; @@ -42,7 +44,8 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; @@ -52,13 +55,11 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** * Tests various close scenarios that should result in Open Session cleanup */ -@Ignore public class ManyConnectionsCleanupTest { static class AbstractCloseSocket extends WebSocketAdapter @@ -220,6 +221,7 @@ public class ManyConnectionsCleanupTest private static final Logger LOG = Log.getLogger(ManyConnectionsCleanupTest.class); + private static BlockheadClient client; private static SimpleServletServer server; private static AbstractCloseSocket closeSocket; @@ -236,6 +238,20 @@ public class ManyConnectionsCleanupTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test session open session cleanup (bug #474936) * @@ -245,35 +261,31 @@ public class ManyConnectionsCleanupTest @Test public void testOpenSessionCleanup() throws Exception { - int iterationCount = 100; - - StdErrLog.getLogger(FastFailSocket.class).setLevel(StdErrLog.LEVEL_OFF); - - StdErrLog sessLog = StdErrLog.getLogger(WebSocketSession.class); - int oldLevel = sessLog.getLevel(); - sessLog.setLevel(StdErrLog.LEVEL_OFF); - - for (int requests = 0; requests < iterationCount; requests++) + int iterationCount = 20; + + // TODO: consider a SilentLogging alternative class + try(StacklessLogging ignore = new StacklessLogging(FastFailSocket.class, WebSocketSession.class)) { - fastFail(); - fastClose(); - dropConnection(); + for (int requests = 0; requests < iterationCount; requests++) + { + fastFail(); + fastClose(); + dropConnection(); + } } - sessLog.setLevel(oldLevel); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1, TimeUnit.SECONDS); - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("calls")); - client.write(new TextFrame().setPayload("openSessions")); + clientConn.write(new TextFrame().setPayload("calls")); + clientConn.write(new TextFrame().setPayload("openSessions")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame; String resp; @@ -291,7 +303,7 @@ public class ManyConnectionsCleanupTest assertThat("frames[2].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); @@ -302,70 +314,63 @@ public class ManyConnectionsCleanupTest private void fastClose() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose"); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastclose"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - LinkedBlockingQueue frames = client.getFrameQueue(); - frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); + // Notify server of close handshake + clientConn.write(close.asFrame()); // respond with close - // Notify server of close handshake - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); - } + // ensure server socket got close event + assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); } } private void fastFail() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastfail"); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastfail"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - // client.readFrames(1,2,TimeUnit.SECONDS); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + clientConn.write(close.asFrame()); // respond with close - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); - assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); - } + // ensure server socket got close event + assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); + assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); } } private void dropConnection() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - client.disconnect(); - } + clientConn.abort(); } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java index d8a5c24e311..292136afa81 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java @@ -26,11 +26,16 @@ import static org.junit.Assert.assertThat; import java.net.HttpCookie; import java.net.URI; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -43,6 +48,7 @@ import org.junit.Test; public class RequestHeadersTest { + private static class EchoCreator implements WebSocketCreator { private UpgradeRequest lastRequest; @@ -86,6 +92,7 @@ public class RequestHeadersTest } } + private static BlockheadClient client; private static SimpleServletServer server; private static EchoCreator echoCreator; @@ -103,19 +110,31 @@ public class RequestHeadersTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testAccessRequestCookies() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setTimeout(1,TimeUnit.SECONDS); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.idleTimeout(1, TimeUnit.SECONDS); + request.header(HttpHeader.COOKIE, "fruit=Pear; type=Anjou"); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection ignore = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.addHeader("Cookie: fruit=Pear; type=Anjou\r\n"); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - UpgradeRequest req = echoCreator.getLastRequest(); assertThat("Last Request",req,notNullValue()); List cookies = req.getCookies(); @@ -127,25 +146,19 @@ public class RequestHeadersTest assertThat("Cookie value",cookie.getValue(),anyOf(is("Pear"),is("Anjou"))); } } - finally - { - client.close(); - } } @Test public void testRequestURI() throws Exception { URI destUri = server.getServerUri().resolve("/?abc=x%20z&breakfast=bacon%26eggs&2*2%3d5=false"); - BlockheadClient client = new BlockheadClient(destUri); - client.setTimeout(1,TimeUnit.SECONDS); - - try + BlockheadClientRequest request = client.newWsRequest(destUri); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection ignore = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - UpgradeRequest req = echoCreator.getLastRequest(); assertThat("Last Request",req,notNullValue()); assertThat("Request.host", req.getHost(), is(server.getServerUri().getHost())); @@ -154,9 +167,5 @@ public class RequestHeadersTest assertThat("Request.uri.rawQuery", req.getRequestURI().getRawQuery(), is("abc=x%20z&breakfast=bacon%26eggs&2*2%3d5=false")); assertThat("Request.uri.query", req.getRequestURI().getQuery(), is("abc=x z&breakfast=bacon&eggs&2*2=5=false")); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java index 3beb3869427..277a3460e8c 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java @@ -21,9 +21,11 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; @@ -31,6 +33,8 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -90,7 +94,8 @@ public class SubProtocolTest factory.setCreator(new ProtocolCreator()); } } - + + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -105,6 +110,20 @@ public class SubProtocolTest { server.stop(); } + + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } @Test public void testSingleProtocol() throws Exception @@ -120,17 +139,16 @@ public class SubProtocolTest private void testSubProtocol(String requestProtocols, String acceptedSubProtocols) throws Exception { - try (BlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, requestProtocols); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.setTimeout(1, TimeUnit.SECONDS); - - client.connect(); - client.addHeader("Sec-WebSocket-Protocol: "+ requestProtocols + "\r\n"); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("showme")); - LinkedBlockingQueue frames = client.getFrameQueue(); + clientConn.write(new TextFrame().setPayload("showme")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(ProtocolEchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("acceptedSubprotocol=" + acceptedSubProtocols)); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java index 09f2cd2c5a3..d8060ec7f5b 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -33,6 +34,8 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -101,6 +104,7 @@ public class SuspendResumeTest } private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -108,7 +112,21 @@ public class SuspendResumeTest server = new SimpleServletServer(new EchoServlet()); server.start(); } + + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @AfterClass public static void stopServer() { @@ -118,18 +136,16 @@ public class SuspendResumeTest @Test public void testSuspendResume() throws Exception { - try (BlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.setTimeout(1, TimeUnit.SECONDS); + clientConn.write(new TextFrame().setPayload("echo1")); + clientConn.write(new TextFrame().setPayload("echo2")); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("echo1")); - client.write(new TextFrame().setPayload("echo2")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(EchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("echo1")); tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java index bf2de13101e..6b2aa39ff4a 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java @@ -23,9 +23,10 @@ import static org.hamcrest.Matchers.is; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.LeakTrackingByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -33,12 +34,13 @@ import org.eclipse.jetty.websocket.common.Generator; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** @@ -50,6 +52,7 @@ import org.junit.Test; public class TooFastClientTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -64,119 +67,93 @@ public class TooFastClientTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + + private ByteBuffer createInitialPacket(String... msgs) + { + int len = Arrays.stream(msgs).mapToInt((str)->str.length() + Generator.MAX_HEADER_LENGTH).sum(); + ByteBuffer initialPacket = ByteBuffer.allocate(len); + + BufferUtil.clearToFill(initialPacket); + Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), + new MappedByteBufferPool()); + + for (String msg : msgs) + { + TextFrame frame = new TextFrame().setPayload(msg); + byte mask[] = new byte[]{0x11, 0x22, 0x33, 0x44}; + frame.setMask(mask); + generator.generateWholeFrame(frame, initialPacket); + } + + BufferUtil.flipToFlush(initialPacket, 0); + return initialPacket; + } + @Test - @Ignore("RELEASE") public void testUpgradeWithSmallFrames() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + String msg1 = "Echo 1"; + String msg2 = "This is also an echooooo!"; + + ByteBuffer initialPacket = createInitialPacket(msg1, msg2); + request.setInitialBytes(initialPacket); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - // Create ByteBuffer representing the initial opening network packet from the client - ByteBuffer initialPacket = ByteBuffer.allocate(4096); - BufferUtil.clearToFill(initialPacket); - - // Add upgrade request to packet - StringBuilder upgradeRequest = client.generateUpgradeRequest(); - ByteBuffer upgradeBuffer = BufferUtil.toBuffer(upgradeRequest.toString(),StandardCharsets.UTF_8); - initialPacket.put(upgradeBuffer); - - // Add text frames - Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), - new MappedByteBufferPool()); - - String msg1 = "Echo 1"; - String msg2 = "This is also an echooooo!"; - - TextFrame frame1 = new TextFrame().setPayload(msg1); - TextFrame frame2 = new TextFrame().setPayload(msg2); - - // Need to set frame mask (as these are client frames) - byte mask[] = new byte[] { 0x11, 0x22, 0x33, 0x44 }; - frame1.setMask(mask); - frame2.setMask(mask); - - generator.generateWholeFrame(frame1,initialPacket); - generator.generateWholeFrame(frame2,initialPacket); - - // Write packet to network - BufferUtil.flipToFlush(initialPacket,0); - client.writeRaw(initialPacket); - - // Expect upgrade - client.expectUpgradeResponse(); - // Read frames (hopefully text frames) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(msg1)); tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg2",tf.getPayloadAsUTF8(),is(msg2)); } - finally - { - client.close(); - } } - + /** * Test where were a client sends a HTTP Upgrade to websocket AND enough websocket frame(s) * to completely overfill the {@link org.eclipse.jetty.io.AbstractConnection#getInputBufferSize()} - * to test a situation where the WebSocket connection opens with prefill that exceeds + * to test a situation where the WebSocket connection opens with prefill that exceeds * the normal input buffer sizes. * @throws Exception on test failure */ @Test - @Ignore("RELEASE") public void testUpgradeWithLargeFrame() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + byte bigMsgBytes[] = new byte[64*1024]; + Arrays.fill(bigMsgBytes,(byte)'x'); + String bigMsg = new String(bigMsgBytes, StandardCharsets.UTF_8); + + ByteBuffer initialPacket = createInitialPacket(bigMsg); + request.setInitialBytes(initialPacket); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - // Create ByteBuffer representing the initial opening network packet from the client - ByteBuffer initialPacket = ByteBuffer.allocate(100 * 1024); - BufferUtil.clearToFill(initialPacket); - - // Add upgrade request to packet - StringBuilder upgradeRequest = client.generateUpgradeRequest(); - ByteBuffer upgradeBuffer = BufferUtil.toBuffer(upgradeRequest.toString(),StandardCharsets.UTF_8); - initialPacket.put(upgradeBuffer); - - // Add text frames - Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), - new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged())); - - byte bigMsgBytes[] = new byte[64*1024]; - Arrays.fill(bigMsgBytes,(byte)'x'); - String bigMsg = new String(bigMsgBytes, StandardCharsets.UTF_8); - - // Need to set frame mask (as these are client frames) - byte mask[] = new byte[] { 0x11, 0x22, 0x33, 0x44 }; - TextFrame frame = new TextFrame().setPayload(bigMsg); - frame.setMask(mask); - generator.generateWholeFrame(frame,initialPacket); - - // Write packet to network - BufferUtil.flipToFlush(initialPacket,0); - client.writeRaw(initialPacket); - - // Expect upgrade - client.expectUpgradeResponse(); - // Read frames (hopefully text frames) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(bigMsg)); } - finally - { - client.close(); - } } - - } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java index 5ead761e174..75dbb333d09 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java @@ -26,9 +26,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StacklessLogging; @@ -41,7 +43,8 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; @@ -51,13 +54,11 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** * Tests various close scenarios */ -@Ignore public class WebSocketCloseTest { static class AbstractCloseSocket extends WebSocketAdapter @@ -198,6 +199,7 @@ public class WebSocketCloseTest private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class); + private static BlockheadClient client; private static SimpleServletServer server; private static AbstractCloseSocket closeSocket; @@ -214,6 +216,20 @@ public class WebSocketCloseTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test fast close (bug #403817) * @@ -223,23 +239,23 @@ public class WebSocketCloseTest @Test public void testFastClose() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) - { - client.setProtocols("fastclose"); - client.setTimeout(5,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose"); + request.idleTimeout(5,TimeUnit.SECONDS); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Verify that client got close frame - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); // Notify server of close handshake - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Fast Close Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true)); @@ -256,29 +272,27 @@ public class WebSocketCloseTest @Test public void testFastFail() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastfail"); + request.idleTimeout(5,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(FastFailSocket.class, WebSocketSession.class)) { - client.setProtocols("fastfail"); - client.setTimeout(5,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(FastFailSocket.class, WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); + CloseInfo close = new CloseInfo(frame); + assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); - CloseInfo close = new CloseInfo(frame); - assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); + clientConn.write(close.asFrame()); // respond with close - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true)); - assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); - assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); - } + // ensure server socket got close event + assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true)); + assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); + assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); } } @@ -295,19 +309,19 @@ public class WebSocketCloseTest fastClose(); dropConnection(); - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) - { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1,TimeUnit.SECONDS); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { TextFrame text = new TextFrame(); text.setPayload("openSessions"); - client.write(text); + clientConn.write(text); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.TEXT)); @@ -318,7 +332,7 @@ public class WebSocketCloseTest assertThat("frames[1].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); @@ -330,72 +344,67 @@ public class WebSocketCloseTest @SuppressWarnings("Duplicates") private void fastClose() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose"); + request.idleTimeout(1,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastclose"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); + // Notify server of close handshake + clientConn.write(close.asFrame()); // respond with close - // Notify server of close handshake - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); - } + // ensure server socket got close event + assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); } } private void fastFail() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastfail"); + request.idleTimeout(1,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastfail"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + clientConn.write(close.asFrame()); // respond with close - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); - assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); - } + // ensure server socket got close event + assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); + assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); } } @SuppressWarnings("Duplicates") private void dropConnection() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - client.disconnect(); - } + clientConn.abort(); } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java index b4c1ac14b07..31a4c2e91db 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java @@ -19,18 +19,31 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.instanceOf; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class WebSocketInvalidVersionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -46,28 +59,40 @@ public class WebSocketInvalidVersionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test the requirement of responding with an http 400 when using a Sec-WebSocket-Version that is unsupported. + * * @throws Exception on test failure */ @Test public void testRequestVersion29() throws Exception { - @SuppressWarnings("resource") - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setVersion(29); // intentionally bad version - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + // intentionally bad version + request.header(HttpHeader.SEC_WEBSOCKET_VERSION, "29"); + + Future connFut = request.sendAsync(); + + expectedException.expect(ExecutionException.class); + expectedException.expectCause(instanceOf(UpgradeException.class)); + expectedException.expectMessage(containsString("400 Unsupported websocket version specification")); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.readResponseHeader(); - Assert.assertThat("Response Status Code",response.getStatusCode(),is(400)); - Assert.assertThat("Response Status Reason",response.getStatusReason(),containsString("Unsupported websocket version specification")); - Assert.assertThat("Response Versions",response.getHeader("Sec-WebSocket-Version"),is("13")); - } - finally - { - client.disconnect(); } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java index 623a14f78b0..f19736841ac 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java @@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; @@ -38,16 +37,12 @@ import org.eclipse.jetty.websocket.server.helper.SessionServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; public class WebSocketOverSSLTest { public static final int CONNECT_TIMEOUT = 15000; public static final int FUTURE_TIMEOUT_SEC = 30; - @Rule - public TestTracker tracker = new TestTracker(); - public ByteBufferPool bufferPool = new MappedByteBufferPool(); private static SimpleServletServer server; diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java index ad5c2144fb5..6857f6b36a7 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java @@ -21,29 +21,29 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import java.net.URI; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.SessionServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runner.RunWith; /** * Testing various aspects of the server side support for WebSocket {@link org.eclipse.jetty.websocket.api.Session} */ -@RunWith(AdvancedRunner.class) public class WebSocketServerSessionTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -58,19 +58,36 @@ public class WebSocketServerSessionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testDisconnect() throws Exception { URI uri = server.getServerUri().resolve("/test/disconnect"); - try (IBlockheadClient client = new BlockheadClient(uri)) + + BlockheadClientRequest request = client.newWsRequest(uri); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("harsh-disconnect")); + clientConn.write(new TextFrame().setPayload("this shouldn't be seen by server")); - client.write(new TextFrame().setPayload("harsh-disconnect")); - - client.awaitDisconnect(1, TimeUnit.SECONDS); + TimeUnit.SECONDS.sleep(10); + // clientConn.awaitDisconnect(1, TimeUnit.SECONDS); } } @@ -78,20 +95,20 @@ public class WebSocketServerSessionTest public void testUpgradeRequestResponse() throws Exception { URI uri = server.getServerUri().resolve("/test?snack=cashews&amount=handful&brand=off"); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Ask the server socket for specific parameter map info - client.write(new TextFrame().setPayload("getParameterMap|snack")); - client.write(new TextFrame().setPayload("getParameterMap|amount")); - client.write(new TextFrame().setPayload("getParameterMap|brand")); - client.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid + clientConn.write(new TextFrame().setPayload("getParameterMap|snack")); + clientConn.write(new TextFrame().setPayload("getParameterMap|amount")); + clientConn.write(new TextFrame().setPayload("getParameterMap|brand")); + clientConn.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Parameter Map[snack]", tf.getPayloadAsUTF8(), is("[cashews]")); tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java index 994128476a2..31dec999088 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java @@ -22,13 +22,15 @@ import static org.hamcrest.Matchers.is; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Locale; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception; import org.eclipse.jetty.util.Utf8StringBuilder; import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -41,6 +43,8 @@ import org.eclipse.jetty.websocket.common.frames.BinaryFrame; import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.common.test.UnitGenerator; import org.eclipse.jetty.websocket.common.util.Hex; @@ -50,16 +54,16 @@ import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runner.RunWith; /** * Test various RFC 6455 specified requirements placed on {@link WebSocketServlet} */ -@RunWith(AdvancedRunner.class) public class WebSocketServletRFCTest { + private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ=="; private static Generator generator = new UnitGenerator(); private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -74,16 +78,18 @@ public class WebSocketServletRFCTest server.stop(); } - /** - * @param clazz the class to enable - * @param enabled true to enable the stack traces (or not) - * @deprecated use {@link StacklessLogging} in a try-with-resources block instead - */ - @Deprecated - private void enableStacks(Class clazz, boolean enabled) + @BeforeClass + public static void startClient() throws Exception { - StdErrLog log = StdErrLog.getLogger(clazz); - log.setHideStacks(!enabled); + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); } /** @@ -93,13 +99,12 @@ public class WebSocketServletRFCTest @Test public void testBinaryAggregate() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate binary frames byte buf1[] = new byte[128]; byte buf2[] = new byte[128]; @@ -113,18 +118,18 @@ public class WebSocketServletRFCTest bin = new BinaryFrame().setPayload(buf1).setFin(false); - client.write(bin); // write buf1 (fin=false) + clientConn.write(bin); // write buf1 (fin=false) bin = new ContinuationFrame().setPayload(buf2).setFin(false); - client.write(bin); // write buf2 (fin=false) + clientConn.write(bin); // write buf2 (fin=false) bin = new ContinuationFrame().setPayload(buf3).setFin(true); - client.write(bin); // write buf3 (fin=true) + clientConn.write(bin); // write buf3 (fin=true) // Read frame echo'd back (hopefully a single binary frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); Frame binmsg = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); int expectedSize = buf1.length + buf2.length + buf3.length; Assert.assertThat("BinaryFrame.payloadLength",binmsg.getPayloadLength(),is(expectedSize)); @@ -156,10 +161,6 @@ public class WebSocketServletRFCTest Assert.assertThat("Echoed data count for 0xBB",bbCount,is(buf2.length)); Assert.assertThat("Echoed data count for 0xCC",ccCount,is(buf3.length)); } - finally - { - client.close(); - } } @Test(expected = NotUtf8Exception.class) @@ -179,26 +180,21 @@ public class WebSocketServletRFCTest @Test public void testEcho() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } /** @@ -209,24 +205,21 @@ public class WebSocketServletRFCTest @Test public void testInternalError() throws Exception { - try (BlockheadClient client = new BlockheadClient(server.getServerUri()); - StacklessLogging stackless=new StacklessLogging(EventDriver.class)) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(EventDriver.class)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + // Generate text frame + clientConn.write(new TextFrame().setPayload("CRASH")); - try (StacklessLogging context = new StacklessLogging(EventDriver.class)) - { - // Generate text frame - client.write(new TextFrame().setPayload("CRASH")); - - // Read frame (hopefully close frame) - LinkedBlockingQueue frames = client.getFrameQueue(); - Frame cf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - CloseInfo close = new CloseInfo(cf); - Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - } + // Read frame (hopefully close frame) + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + Frame cf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(cf); + Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); } } @@ -239,61 +232,50 @@ public class WebSocketServletRFCTest @Test public void testLowercaseUpgrade() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header("upgrade", "websocket"); + request.header("connection", "upgrade"); + request.header("sec-websocket-key", REQUEST_HASH_KEY); + request.header("sec-websocket-origin", server.getServerUri().toASCIIString()); + request.header("sec-websocket-protocol", "echo"); + request.header("sec-websocket-version", "13"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - StringBuilder req = new StringBuilder(); - req.append("GET ").append(client.getRequestPath()).append(" HTTP/1.1\r\n"); - req.append("Host: ").append(client.getRequestHost()).append("\r\n"); - req.append("Upgrade: websocket\r\n"); - req.append("connection: upgrade\r\n"); - req.append("sec-websocket-key: ").append(client.getRequestWebSocketKey()).append("\r\n"); - req.append("sec-websocket-origin: ").append(client.getRequestWebSocketOrigin()).append("\r\n"); - req.append("sec-websocket-protocol: echo\r\n"); - req.append("sec-websocket-version: 13\r\n"); - req.append("\r\n"); - client.writeRaw(req.toString()); - - client.expectUpgradeResponse(); - // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } @Test public void testTextNotUTF8() throws Exception { - try (StacklessLogging stackless=new StacklessLogging(Parser.class); - BlockheadClient client = new BlockheadClient(server.getServerUri())) - { - client.setProtocols("other"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "other"); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(Parser.class)) + { byte buf[] = new byte[] { (byte)0xC2, (byte)0xC3 }; WebSocketFrame txt = new TextFrame().setPayload(ByteBuffer.wrap(buf)); txt.setMask(Hex.asByteArray("11223344")); ByteBuffer bbHeader = generator.generateHeaderBytes(txt); - client.writeRaw(bbHeader); - client.writeRaw(txt.getPayload()); + clientConn.writeRaw(bbHeader); + clientConn.writeRaw(txt.getPayload()); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); @@ -310,37 +292,26 @@ public class WebSocketServletRFCTest @Test public void testUppercaseUpgrade() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header("UPGRADE", "WEBSOCKET"); + request.header("CONNECTION", "UPGRADE"); + request.header("SEC-WEBSOCKET-KEY", REQUEST_HASH_KEY.toUpperCase(Locale.US)); + request.header("SEC-WEBSOCKET-ORIGIN", server.getServerUri().toASCIIString()); + request.header("SEC-WEBSOCKET-PROTOCOL", "ECHO"); + request.header("SEC-WEBSOCKET-VERSION", "13"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - StringBuilder req = new StringBuilder(); - req.append("GET ").append(client.getRequestPath()).append(" HTTP/1.1\r\n"); - req.append("HOST: ").append(client.getRequestHost()).append("\r\n"); - req.append("UPGRADE: WEBSOCKET\r\n"); - req.append("CONNECTION: UPGRADE\r\n"); - req.append("SEC-WEBSOCKET-KEY: ").append(client.getRequestWebSocketKey()).append("\r\n"); - req.append("SEC-WEBSOCKET-ORIGIN: ").append(client.getRequestWebSocketOrigin()).append("\r\n"); - req.append("SEC-WEBSOCKET-PROTOCOL: ECHO\r\n"); - req.append("SEC-WEBSOCKET-VERSION: 13\r\n"); - req.append("\r\n"); - client.writeRaw(req.toString()); - - client.expectUpgradeResponse(); - // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java index 784aa8609ae..e0bb8fdae4a 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java @@ -27,7 +27,9 @@ import java.net.URI; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.DispatcherType; @@ -41,14 +43,16 @@ import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; -import org.junit.Ignore; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -@Ignore("Unstable - see Issue #1815") @RunWith(Parameterized.class) public class WebSocketUpgradeFilterTest { @@ -56,7 +60,23 @@ public class WebSocketUpgradeFilterTest { Server newServer() throws Exception; } - + + private static BlockheadClient client; + + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + private static AtomicInteger uniqTestDirId = new AtomicInteger(0); private static File getNewTestDir() @@ -305,16 +325,16 @@ public class WebSocketUpgradeFilterTest public void testNormalConfiguration() throws Exception { URI destUri = serverUri.resolve("/info/"); - - try (BlockheadClient client = new BlockheadClient(destUri)) + + BlockheadClientRequest request = client.newWsRequest(destUri); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("hello")); - client.write(new TextFrame().setPayload("hello")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String payload = received.getPayloadAsUTF8(); @@ -328,20 +348,19 @@ public class WebSocketUpgradeFilterTest public void testStopStartOfHandler() throws Exception { URI destUri = serverUri.resolve("/info/"); - - try (BlockheadClient client = new BlockheadClient(destUri)) + + BlockheadClientRequest request = client.newWsRequest(destUri); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("hello 1")); - client.write(new TextFrame().setPayload("hello 1")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String payload = received.getPayloadAsUTF8(); - // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); @@ -349,20 +368,19 @@ public class WebSocketUpgradeFilterTest server.getHandler().stop(); server.getHandler().start(); - - try (BlockheadClient client = new BlockheadClient(destUri)) + + request = client.newWsRequest(destUri); + + connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("hello 2")); - client.write(new TextFrame().setPayload("hello 2")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String payload = received.getPayloadAsUTF8(); - // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java index 5a61dfbcd41..2e75a6adb28 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; @@ -35,9 +34,7 @@ import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.PongFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; -@RunWith(AdvancedRunner.class) public class TestABCase2 extends AbstractABCase { /** diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java index bafef7a354e..e3d565f595b 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java @@ -22,7 +22,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; @@ -33,12 +32,10 @@ import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; /** * Test various bad / forbidden opcodes (per spec) */ -@RunWith(AdvancedRunner.class) public class TestABCase4 extends AbstractABCase { /** diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java index 0a7c1e74daf..780e2f90510 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java @@ -22,8 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -35,12 +33,10 @@ import org.eclipse.jetty.websocket.common.frames.PongFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; /** * Fragmentation Tests */ -@RunWith(AdvancedRunner.class) public class TestABCase5 extends AbstractABCase { /** @@ -65,7 +61,7 @@ public class TestABCase5 extends AbstractABCase fuzzer.send(send); fuzzer.expect(expect); } - } + } /** * Send continuation+fin, then text+fin (framewise) @@ -301,7 +297,6 @@ public class TestABCase5 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase5_19() throws Exception { // phase 1 diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java index 6e6084b2217..f8eef39cc37 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java @@ -23,8 +23,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -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.StringUtil; import org.eclipse.jetty.util.TypeUtil; @@ -39,12 +37,10 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.eclipse.jetty.websocket.common.util.Hex; import org.junit.Test; -import org.junit.runner.RunWith; /** * UTF-8 Tests */ -@RunWith(AdvancedRunner.class) public class TestABCase6 extends AbstractABCase { /** @@ -276,7 +272,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_1() throws Exception { byte part1[] = StringUtil.getUtf8Bytes("\u03BA\u1F79\u03C3\u03BC\u03B5"); @@ -312,7 +307,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_2() throws Exception { byte part1[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F4"); // split code point @@ -340,7 +334,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_3() throws Exception { // Disable Long Stacks from Parser (we know this test will throw an exception) @@ -393,7 +386,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_4() throws Exception { byte invalid[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F49080808080656469746564"); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java index 18a20bc6d1b..eb5474e8c2f 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; @@ -39,7 +38,6 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.eclipse.jetty.websocket.common.util.Hex; -import org.junit.Rule; import org.junit.Test; /** @@ -47,9 +45,6 @@ import org.junit.Test; */ public class TestABCase7 extends AbstractABCase { - @Rule - public TestTracker tt = new TestTracker(); - /** * Basic message then close frame, normal behavior * @throws Exception on test failure diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java index 1756f634993..210783d547d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java @@ -24,8 +24,6 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.annotation.Stress; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -37,12 +35,10 @@ import org.eclipse.jetty.websocket.common.frames.DataFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; /** * Big frame/message tests */ -@RunWith(AdvancedRunner.class) public class TestABCase9 extends AbstractABCase { private static final int KBYTE = 1024; @@ -246,7 +242,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_1_5() throws Exception { byte utf[] = new byte[8 * MBYTE]; @@ -275,7 +270,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_1_6() throws Exception { byte utf[] = new byte[16 * MBYTE]; @@ -359,7 +353,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_3() throws Exception { byte data[] = new byte[1 * MBYTE]; @@ -388,7 +381,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_4() throws Exception { byte data[] = new byte[4 * MBYTE]; @@ -417,7 +409,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_5() throws Exception { byte data[] = new byte[8 * MBYTE]; @@ -446,7 +437,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_6() throws Exception { byte data[] = new byte[16 * MBYTE]; @@ -475,7 +465,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_1() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64); @@ -486,7 +475,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_2() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256); @@ -497,7 +485,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_3() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * KBYTE); @@ -508,7 +495,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_4() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * KBYTE); @@ -519,7 +505,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_5() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,16 * KBYTE); @@ -530,7 +515,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_6() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64 * KBYTE); @@ -541,7 +525,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_7() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256 * KBYTE); @@ -552,7 +535,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_8() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * MBYTE); @@ -563,7 +545,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_9() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * MBYTE); @@ -574,7 +555,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_1() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64); @@ -585,7 +565,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_2() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256); @@ -596,7 +575,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_3() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * KBYTE); @@ -607,7 +585,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_4() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * KBYTE); @@ -618,7 +595,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_5() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,16 * KBYTE); @@ -629,7 +605,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_6() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64 * KBYTE); @@ -640,7 +615,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_7() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256 * KBYTE); @@ -651,7 +625,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_8() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * MBYTE); @@ -662,7 +635,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_9() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * MBYTE); @@ -673,7 +645,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_1() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,64); @@ -684,7 +655,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_2() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,128); @@ -695,7 +665,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_3() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,256); @@ -706,7 +675,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_4() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,512); @@ -717,7 +685,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_5() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,1024); @@ -728,7 +695,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_6() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,2048); @@ -739,7 +705,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_1() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,64); @@ -750,7 +715,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_2() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,128); @@ -761,7 +725,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_3() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,256); @@ -772,7 +735,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_4() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,512); @@ -783,7 +745,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_5() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,1024); @@ -794,7 +755,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_6() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,2048); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java index b54266ef0a0..283ee8add7e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.server.examples; import java.io.IOException; import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.WebSocketAdapter; @@ -43,8 +42,6 @@ public class MyEchoSocket extends WebSocketAdapter // echo the data back RemoteEndpoint remote = getRemote(); remote.sendString(message); - if (remote.getBatchMode() == BatchMode.ON) - remote.flush(); } catch (IOException e) { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java index bc5db0c678c..4232727160a 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java @@ -22,9 +22,11 @@ import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -32,7 +34,8 @@ import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.SimpleServletServer; import org.junit.AfterClass; @@ -47,6 +50,7 @@ public class MisbehavingClassTest { private static SimpleServletServer server; private static BadSocketsServlet badSocketsServlet; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -62,29 +66,42 @@ public class MisbehavingClassTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testListenerRuntimeOnConnect() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri()); - StacklessLogging scope = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class)) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "listener-runtime-connect"); + request.idleTimeout(1, TimeUnit.SECONDS); + + ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect; + socket.reset(); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class)) { - client.setProtocols("listener-runtime-connect"); - client.setTimeout(1,TimeUnit.SECONDS); - - ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect; - socket.reset(); - - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); @@ -100,26 +117,25 @@ public class MisbehavingClassTest @Test public void testAnnotatedRuntimeOnConnect() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri()); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "annotated-runtime-connect"); + request.idleTimeout(1, TimeUnit.SECONDS); + + AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect; + socket.reset(); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class)) { - client.setProtocols("annotated-runtime-connect"); - client.setTimeout(1,TimeUnit.SECONDS); - - AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect; - socket.reset(); - - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); From a128b87e3a3245fcf3c4f54483110bc9d68d8192 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 7 Mar 2018 16:33:28 +1100 Subject: [PATCH 10/87] Jetty 9.4.x #2279 start update params (#2285) Jetty 9.4.x #2279 start update params (#2285): * Cleanup and Unify param update logic #2279 * Cleanup system property source #2279 * Cleanup property source #2279 * Property cleanup for #2279 * Removed duplicate Prop and Property classes * properties are only updated/set if value source is not from ?= Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/start/Main.java | 36 +--- .../java/org/eclipse/jetty/start/Module.java | 6 +- .../java/org/eclipse/jetty/start/Props.java | 31 +--- .../org/eclipse/jetty/start/StartArgs.java | 161 ++++++++---------- .../org/eclipse/jetty/start/StartIni.java | 31 +++- .../jetty/start/ConfigurationAssert.java | 2 +- .../org/eclipse/jetty/start/PropsTest.java | 23 +-- .../parameterized.addToStart.assert.txt | 1 + .../parameterized.commands.assert.txt | 1 + .../usecases/parameterized.update.assert.txt | 3 +- .../usecases/parameterized.update.prepare.txt | 1 + .../parameterized/modules/parameterized.mod | 3 + 12 files changed, 126 insertions(+), 173 deletions(-) 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 1bf7c8fef2a..59c7dc72a46 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 @@ -39,7 +39,6 @@ import java.net.SocketTimeoutException; import java.nio.file.Path; import java.util.List; import java.util.Locale; -import java.util.regex.Matcher; import org.eclipse.jetty.start.Props.Prop; import org.eclipse.jetty.start.config.CommandLineConfigSource; @@ -295,18 +294,18 @@ public class Main args.parse(baseHome.getConfigSources()); Props props = baseHome.getConfigSources().getProps(); - Props.Prop home = props.getProp(BaseHome.JETTY_HOME); + Prop home = props.getProp(BaseHome.JETTY_HOME); if (!args.getProperties().containsKey(BaseHome.JETTY_HOME)) args.getProperties().setProperty(home); args.getProperties().setProperty(BaseHome.JETTY_HOME+".uri", normalizeURI(baseHome.getHomePath().toUri().toString()), - home.origin); - Props.Prop base = props.getProp(BaseHome.JETTY_BASE); + home.source); + Prop base = props.getProp(BaseHome.JETTY_BASE); if (!args.getProperties().containsKey(BaseHome.JETTY_BASE)) args.getProperties().setProperty(base); args.getProperties().setProperty(BaseHome.JETTY_BASE+".uri", normalizeURI(baseHome.getBasePath().toUri().toString()), - base.origin); + base.source); // ------------------------------------------------------------ // 3) Module Registration @@ -426,25 +425,8 @@ public class Main { for (ConfigSource config : baseHome.getConfigSources()) { - System.out.printf("ConfigSource %s%n",config.getId()); for (StartIni ini : config.getStartInis()) - { - for (String line : ini.getAllLines()) - { - Matcher m = Module.SET_PROPERTY.matcher(line); - if (m.matches() && m.groupCount()==3) - { - String name = m.group(2); - String value = m.group(3); - Prop p = args.getProperties().getProp(name); - if (p!=null && ("#".equals(m.group(1)) || !value.equals(p.value))) - { - ini.update(baseHome,args.getProperties()); - break; - } - } - } - } + ini.update(baseHome,args.getProperties()); } } @@ -512,10 +494,10 @@ public class Main private void doStop(StartArgs args) { - Props.Prop stopHostProp = args.getProperties().getProp("STOP.HOST", true); - Props.Prop stopPortProp = args.getProperties().getProp("STOP.PORT", true); - Props.Prop stopKeyProp = args.getProperties().getProp("STOP.KEY", true); - Props.Prop stopWaitProp = args.getProperties().getProp("STOP.WAIT", true); + Prop stopHostProp = args.getProperties().getProp("STOP.HOST", true); + Prop stopPortProp = args.getProperties().getProp("STOP.PORT", true); + Prop stopKeyProp = args.getProperties().getProp("STOP.KEY", true); + Prop stopWaitProp = args.getProperties().getProp("STOP.WAIT", true); String stopHost = "127.0.0.1"; int stopPort = -1; diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java index 45e1581a553..7bec2fe5b90 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java @@ -37,7 +37,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.eclipse.jetty.start.Props.Prop; -import org.eclipse.jetty.start.config.CommandLineConfigSource; /** * Represents a Module metadata, as defined in Jetty. @@ -527,9 +526,12 @@ public class Module implements Comparable if (m.matches() && m.groupCount()==3) { String name = m.group(2); + String value = m.group(3); Prop p = props.getProp(name); - if (p!=null && p.origin.startsWith(CommandLineConfigSource.ORIGIN_CMD_LINE)) + + if (p!=null && (p.source==null || !p.source.endsWith("?=")) && ("#".equals(m.group(1)) || !value.equals(p.value))) { + System.err.printf("%s == %s :: %s%n",name,value,p.source); StartLog.info("%-15s property set %s=%s",this._name,name,p.value); out.printf("%s=%s%n",name,p.value); } diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Props.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Props.java index c1dc1e13c34..73f9775ef6a 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Props.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Props.java @@ -48,20 +48,13 @@ public final class Props implements Iterable { public String key; public String value; - public String origin; - public Prop overrides; + public String source; - public Prop(String key, String value, String origin) + public Prop(String key, String value, String source) { this.key = key; this.value = value; - this.origin = origin; - } - - public Prop(String key, String value, String origin, Prop overrides) - { - this(key,value,origin); - this.overrides = overrides; + this.source = source; } @Override @@ -72,15 +65,12 @@ public final class Props implements Iterable builder.append(key); builder.append(", value="); builder.append(value); - builder.append(", origin="); - builder.append(origin); - builder.append(", overrides="); - builder.append(overrides); + builder.append(", source="); + builder.append(source); builder.append("]"); return builder.toString(); } } - public static final String ORIGIN_SYSPROP = ""; public static String getValue(String arg) @@ -342,16 +332,7 @@ public final class Props implements Iterable public void setProperty(String key, String value, String origin) { - Prop prop = props.get(key); - if (prop == null) - { - prop = new Prop(key,value,origin); - } - else - { - prop = new Prop(key,value,origin,prop); - } - props.put(key,prop); + props.put(key,new Prop(key,value,origin)); } public int size() diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index ed06cfc48a7..235b0358626 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -35,7 +35,6 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; -import java.util.function.Function; import org.eclipse.jetty.start.Props.Prop; import org.eclipse.jetty.start.config.ConfigSource; @@ -123,9 +122,6 @@ public class StartArgs /** Map of enabled modules to the source of where that activation occurred */ Map> sources = new HashMap<>(); - /** Map of properties to where that property was declared */ - private Map propertySource = new HashMap<>(); - /** List of all active [files] sections from enabled modules */ private List files = new ArrayList<>(); @@ -148,7 +144,7 @@ public class StartArgs private List propertyFiles = new ArrayList<>(); private Props properties = new Props(); - private Set systemPropertyKeys = new HashSet<>(); + private Map systemPropertySource = new HashMap<>(); private List rawLibs = new ArrayList<>(); // jetty.base - build out commands @@ -205,12 +201,6 @@ public class StartArgs } } - public void addSystemProperty(String key, String value) - { - this.systemPropertyKeys.add(key); - System.setProperty(key,value); - } - private void addUniqueXmlFile(String xmlRef, Path xmlfile) throws IOException { if (!FS.canReadFile(xmlfile)) @@ -337,7 +327,7 @@ public class StartArgs List sortedKeys = new ArrayList<>(); for (Prop prop : properties) { - if (prop.origin.equals(Props.ORIGIN_SYSPROP)) + if (prop.source.equals(Props.ORIGIN_SYSPROP)) { continue; // skip } @@ -369,16 +359,7 @@ public class StartArgs { System.out.printf(" %s = %s%n",key,prop.value); if (StartLog.isDebugEnabled()) - { - System.out.printf(" origin: %s%n",prop.origin); - while (prop.overrides != null) - { - prop = prop.overrides; - System.out.printf(" (overrides)%n"); - System.out.printf(" %s = %s%n",key,prop.value); - System.out.printf(" origin: %s%n",prop.origin); - } - } + System.out.printf(" origin: %s%n",prop.source); } } @@ -388,26 +369,25 @@ public class StartArgs System.out.println("System Properties:"); System.out.println("------------------"); - if (systemPropertyKeys.isEmpty()) + if (systemPropertySource.keySet().isEmpty()) { System.out.println(" (no system properties specified)"); return; } List sortedKeys = new ArrayList<>(); - sortedKeys.addAll(systemPropertyKeys); + sortedKeys.addAll(systemPropertySource.keySet()); Collections.sort(sortedKeys); for (String key : sortedKeys) - { - String value = System.getProperty(key); - System.out.printf(" %s = %s%n",key,value); - } + dumpSystemProperty(key); } private void dumpSystemProperty(String key) { - System.out.printf(" %s = %s%n",key,System.getProperty(key)); + String value = System.getProperty(key); + String source = systemPropertySource.get(key); + System.out.printf(" %s = %s (%s)%n",key,value,source); } /** @@ -418,20 +398,20 @@ public class StartArgs */ private void ensureSystemPropertySet(String key) { - if (systemPropertyKeys.contains(key)) + if (systemPropertySource.containsKey(key)) { return; // done } if (properties.containsKey(key)) { - String val = properties.expand(properties.getString(key)); - if (val == null) - { - return; // no value to set - } + Prop prop = properties.getProp(key); + if (prop==null) + return; // no value set; + + String val = properties.expand(prop.value); // setup system property - systemPropertyKeys.add(key); + systemPropertySource.put(key,"property:"+prop.source); System.setProperty(key,val); } } @@ -446,7 +426,7 @@ public class StartArgs { StartLog.debug("Expanding System Properties"); - for (String key : systemPropertyKeys) + for (String key : systemPropertySource.keySet()) { String value = properties.getString(key); if (value!=null) @@ -588,11 +568,8 @@ public class StartArgs String key = assign[0]; String value = assign.length==1?"":assign[1]; - Property p = processProperty(key,value,"modules",k->{return System.getProperty(k);}); - if (p!=null) - { - cmd.addRawArg("-D"+p.key+"="+getProperties().expand(p.value)); - } + Prop p = processSystemProperty(key,value,null); + cmd.addRawArg("-D"+p.key+"="+getProperties().expand(p.value)); } else { @@ -601,7 +578,7 @@ public class StartArgs } // System Properties - for (String propKey : systemPropertyKeys) + for (String propKey : systemPropertySource.keySet()) { String value = System.getProperty(propKey); cmd.addEqualsArg("-D" + propKey,value); @@ -737,7 +714,7 @@ public class StartArgs public boolean hasSystemProperties() { - for (String key : systemPropertyKeys) + for (String key : systemPropertySource.keySet()) { // ignored keys if ("jetty.home".equals(key) || "jetty.base".equals(key) || "main.class".equals(key)) @@ -1096,13 +1073,10 @@ public class StartArgs String key = assign[0]; String value = assign.length==1?"":assign[1]; - Property p = processProperty(key,value,source,k->{return System.getProperty(k);}); - if (p!=null) - { - systemPropertyKeys.add(p.key); - setProperty(p.key,p.value,p.source); - System.setProperty(p.key,p.value); - } + Prop p = processSystemProperty(key,value,source); + systemPropertySource.put(p.key,p.source); + setProperty(p.key,p.value,p.source); + System.setProperty(p.key,p.value); return; } @@ -1124,11 +1098,8 @@ public class StartArgs String key = arg.substring(0,equals); String value = arg.substring(equals + 1); - Property p = processProperty(key,value,source,k->{return getProperties().getString(k);}); - if (p!=null) - { - setProperty(p.key,p.value,p.source); - } + processAndSetProperty(key,value,source); + return; } @@ -1157,41 +1128,69 @@ public class StartArgs throw new UsageException(UsageException.ERR_BAD_ARG,"Unrecognized argument: \"%s\" in %s",arg,source); } - protected Property processProperty(String key,String value,String source, Function getter) + protected Prop processSystemProperty(String key, String value, String source) { if (key.endsWith("+")) { key = key.substring(0,key.length() - 1); - String orig = getter.apply(key); + String orig = System.getProperty(key); if (orig == null || orig.isEmpty()) { if (value.startsWith(",")) value = value.substring(1); } + else + { + value = orig + value; + if (source!=null && systemPropertySource.containsKey(key)) + source = systemPropertySource.get(key) + "," + source; + } + } + else if (key.endsWith("?")) + { + key = key.substring(0,key.length() - 1); + String preset = System.getProperty(key); + if (preset!=null) + { + value = preset; + source = systemPropertySource.get(key); + } + else if (source!=null) + source = source+"?="; + } + + return new Prop(key, value, source); + } + + protected void processAndSetProperty(String key,String value,String source) + { + if (key.endsWith("+")) + { + key = key.substring(0,key.length() - 1); + Prop orig = getProperties().getProp(key); + if (orig == null) + { + if (value.startsWith(",")) + value = value.substring(1); + } else { - value = orig + value; - source = propertySource.get(key) + "," + source; + value = orig.value + value; + source = orig.source + "," + source; } } - if (key.endsWith("?")) + else if (key.endsWith("?")) { key = key.substring(0,key.length() - 1); - String preset = getter.apply(key); + Prop preset = getProperties().getProp(key); if (preset!=null) - { + return; + + if (source!=null) source = source+"?="; - value = preset; - } - } - else if (propertySource.containsKey(key)) - { - if (!propertySource.get(key).endsWith("[ini]")) - StartLog.warn("Property %s in %s already set in %s",key,source,propertySource.get(key)); - propertySource.put(key,source); } - return new Property(key,value,source); + setProperty(key,value,source); } private void enableModules(String source, List moduleNames) @@ -1303,22 +1302,4 @@ public class StartArgs return builder.toString(); } - static class Property - { - String key; - String value; - String source; - public Property(String key, String value, String source) - { - this.key = key; - this.value = value; - this.source = source; - } - - @Override - public String toString() - { - return String.format("%s=%s(%s)",key,value,source); - } - } } diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java index ed212777a2b..08a2ddf43ad 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java @@ -92,7 +92,9 @@ public class StartIni extends TextFile update = update.substring(0,update.lastIndexOf(".")); String source = baseHome.toShortForm(getFile()); - try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(getFile(),StandardCharsets.UTF_8,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.CREATE))) + PrintWriter writer = null; + + try { for (String line : getAllLines()) { @@ -102,23 +104,42 @@ public class StartIni extends TextFile String name = m.group(2); String value = m.group(3); Prop p = props.getProp(name); - if (p!=null && ("#".equals(m.group(1)) || !value.equals(p.value))) + + if (p!=null && (p.source==null || !p.source.endsWith("?=")) && ("#".equals(m.group(1)) || !value.equals(p.value))) { + if (writer==null) + { + writer = new PrintWriter(Files.newBufferedWriter(getFile(),StandardCharsets.UTF_8,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.CREATE)); + for (String l : getAllLines()) + { + if (line.equals(l)) + break; + writer.println(l); + } + } + StartLog.info("%-15s property updated %s=%s",update,name,p.value); writer.printf("%s=%s%n",name,p.value); } - else + else if (writer!=null) { writer.println(line); } } - else + else if (writer!=null) { writer.println(line); } } } + finally + { + if (writer!=null) + { + StartLog.info("%-15s updated %s",update,source); + writer.close(); + } + } - StartLog.info("%-15s updated %s",update,source); } } diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java index b366117adea..6d19755d068 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java @@ -142,7 +142,7 @@ public class ConfigurationAssert "jetty.home.uri".equals(name) || "jetty.base.uri".equals(name) || "user.dir".equals(name) || - prop.origin.equals(Props.ORIGIN_SYSPROP) || + prop.source.equals(Props.ORIGIN_SYSPROP) || name.startsWith("java.")) { // strip these out from assertion, to make assertions easier. diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/PropsTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/PropsTest.java index b5605391f53..8b70512485d 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/PropsTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/PropsTest.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.start; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; @@ -36,7 +35,7 @@ public class PropsTest assertThat(prefix,prop,notNullValue()); assertThat(prefix + ".key",prop.key,is(expectedKey)); assertThat(prefix + ".value",prop.value,is(expectedValue)); - assertThat(prefix + ".origin",prop.origin,is(expectedOrigin)); + assertThat(prefix + ".origin",prop.source,is(expectedOrigin)); } @Test @@ -49,7 +48,6 @@ public class PropsTest Prop prop = props.getProp("java.io.tmpdir"); assertProp("System Prop",prop,"java.io.tmpdir",expected,Props.ORIGIN_SYSPROP); - assertThat("System Prop.overrides",prop.overrides,nullValue()); } @Test @@ -63,25 +61,6 @@ public class PropsTest Prop prop = props.getProp("name"); assertProp(prefix,prop,"name","jetty",FROM_TEST); - assertThat(prefix + ".overrides",prop.overrides,nullValue()); - } - - @Test - public void testOverride() - { - Props props = new Props(); - props.setProperty("name","jetty",FROM_TEST); - props.setProperty("name","altjetty","(Alt-Jetty)"); - - String prefix = "Overriden"; - assertThat(prefix,props.getString("name"),is("altjetty")); - - Prop prop = props.getProp("name"); - assertProp(prefix,prop,"name","altjetty","(Alt-Jetty)"); - Prop older = prop.overrides; - assertThat(prefix + ".overrides",older,notNullValue()); - assertProp(prefix + ".overridden",older,"name","jetty",FROM_TEST); - assertThat(prefix + ".overridden",older.overrides,nullValue()); } @Test diff --git a/jetty-start/src/test/resources/usecases/parameterized.addToStart.assert.txt b/jetty-start/src/test/resources/usecases/parameterized.addToStart.assert.txt index b31ef3c69c5..46344a3d993 100644 --- a/jetty-start/src/test/resources/usecases/parameterized.addToStart.assert.txt +++ b/jetty-start/src/test/resources/usecases/parameterized.addToStart.assert.txt @@ -12,6 +12,7 @@ PROP|main.prop=value0 PROP|name=value PROP|name0=changed0 PROP|name1=changed1 +PROP|name2=two PROP|property=value PROP|property0=value0 diff --git a/jetty-start/src/test/resources/usecases/parameterized.commands.assert.txt b/jetty-start/src/test/resources/usecases/parameterized.commands.assert.txt index b31ef3c69c5..46344a3d993 100644 --- a/jetty-start/src/test/resources/usecases/parameterized.commands.assert.txt +++ b/jetty-start/src/test/resources/usecases/parameterized.commands.assert.txt @@ -12,6 +12,7 @@ PROP|main.prop=value0 PROP|name=value PROP|name0=changed0 PROP|name1=changed1 +PROP|name2=two PROP|property=value PROP|property0=value0 diff --git a/jetty-start/src/test/resources/usecases/parameterized.update.assert.txt b/jetty-start/src/test/resources/usecases/parameterized.update.assert.txt index 4e4570e277d..a581efdad66 100644 --- a/jetty-start/src/test/resources/usecases/parameterized.update.assert.txt +++ b/jetty-start/src/test/resources/usecases/parameterized.update.assert.txt @@ -10,8 +10,9 @@ LIB|${jetty.home}/lib/other.jar # The Properties we expect (order is irrelevant) PROP|main.prop=value0 PROP|name=value -PROP|name0=changed0 +PROP|name0=updated0 PROP|name1=changed1 +PROP|name2=two PROP|property=value PROP|property0=changed0 PROP|property1=changed1 diff --git a/jetty-start/src/test/resources/usecases/parameterized.update.prepare.txt b/jetty-start/src/test/resources/usecases/parameterized.update.prepare.txt index 6ecc31c4e0d..86a278a1792 100644 --- a/jetty-start/src/test/resources/usecases/parameterized.update.prepare.txt +++ b/jetty-start/src/test/resources/usecases/parameterized.update.prepare.txt @@ -8,3 +8,4 @@ name1=changed1 --update-ini property0=changed0 property1=changed1 +name0=updated0 \ No newline at end of file diff --git a/jetty-start/src/test/resources/usecases/parameterized/modules/parameterized.mod b/jetty-start/src/test/resources/usecases/parameterized/modules/parameterized.mod index c243eb73efa..7d09c7e9fe9 100644 --- a/jetty-start/src/test/resources/usecases/parameterized/modules/parameterized.mod +++ b/jetty-start/src/test/resources/usecases/parameterized/modules/parameterized.mod @@ -4,7 +4,10 @@ main [ini] name=value +name0?=default +name2?=two [ini-template] name0=value0 # name1=value1 +# name2=too From 8607387499744a3d708a621abbe690d97f8dcdbf Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 7 Mar 2018 17:15:05 +1100 Subject: [PATCH 11/87] better debug from test Signed-off-by: Greg Wilkins --- .../eclipse/jetty/server/ThreadStarvationTest.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java index 4d3c90cce11..8cd7fa3671e 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java @@ -325,13 +325,21 @@ public class ThreadStarvationTest byte buf[] = new byte[1024]; - while((len = in.read(buf,0,buf.length)) != -1) + try { - for(int x=0; x Date: Wed, 7 Mar 2018 18:06:57 +1100 Subject: [PATCH 12/87] Better dump for ManagedSelector Signed-off-by: Greg Wilkins --- .../org/eclipse/jetty/io/ManagedSelector.java | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index 90adb5c7873..36900ba547f 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -42,6 +42,7 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.jetty.io.ManagedSelector.Connect; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; @@ -185,24 +186,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable if (connect.timeout.cancel()) { key.interestOps(0); - execute(new Runnable() - { - @Override - public void run() - { - try - { - createEndPoint(channel,key); - } - catch(Throwable failure) - { - closeNoExceptions(channel); - LOG.warn(String.valueOf(failure)); - LOG.debug(failure); - connect.failed(failure); - } - } - }); + execute(new CreateEndPoint(connect,key)); } else { @@ -730,6 +714,12 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable ManagedSelector.this._selectorManager.connectionFailed(channel, failure, attachment); } } + + @Override + public String toString() + { + return String.format("Connect@%x{%s,%s}",hashCode(),channel,attachment); + } } private class CloseConnections implements SelectorUpdate @@ -816,7 +806,40 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } } + private final class CreateEndPoint implements Runnable + { + private final Connect _connect; + private final SelectionKey _key; + private CreateEndPoint(Connect connect, SelectionKey key) + { + _connect = connect; + _key = key; + } + + @Override + public void run() + { + try + { + createEndPoint(_connect.channel,_key); + } + catch(Throwable failure) + { + closeNoExceptions(_connect.channel); + LOG.warn(String.valueOf(failure)); + LOG.debug(failure); + _connect.failed(failure); + } + } + + @Override + public String toString() + { + return String.format("CreateEndPoint@%x{%s,%s}",hashCode(),_connect,_key); + } + } + private class DestroyEndPoint implements Runnable, Closeable { private final EndPoint endPoint; From 74055b983705b34b30af0908cb4343f29ffa68f3 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 7 Mar 2018 19:31:22 +1100 Subject: [PATCH 13/87] Jetty 9.4.x 2293 pending multiplexed (#2294) Issue #2293 Pending Multiplexed Connections Added a AtomicBiInteger to allow both total connections and pending connections to be encoded in the same atomic int. Signed-off-by: Greg Wilkins --- .../jetty/client/AbstractConnectionPool.java | 66 ++-- .../jetty/client/MultiplexConnectionPool.java | 15 + .../test/resources/jetty-logging.properties | 2 +- .../eclipse/jetty/util/AtomicBiInteger.java | 290 ++++++++++++++++++ .../jetty/util/AtomicBiIntegerTest.java | 105 +++++++ 5 files changed, 452 insertions(+), 26 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java create mode 100644 jetty-util/src/test/java/org/eclipse/jetty/util/AtomicBiIntegerTest.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java index 65f6454eceb..19ec8ba7bf8 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java @@ -20,10 +20,10 @@ package org.eclipse.jetty.client; import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.Destination; +import org.eclipse.jetty.util.AtomicBiInteger; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.annotation.ManagedAttribute; @@ -39,7 +39,12 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable private static final Logger LOG = Log.getLogger(AbstractConnectionPool.class); private final AtomicBoolean closed = new AtomicBoolean(); - private final AtomicInteger connectionCount = new AtomicInteger(); + + /** + * The connectionCount encodes both the total connections plus the pending connection counts, so both can be atomically changed. + * The bottom 32 bits represent the total connections and the top 32 bits represent the pending connections. + */ + private final AtomicBiInteger connections = new AtomicBiInteger(); private final Destination destination; private final int maxConnections; private final Callback requester; @@ -60,13 +65,19 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable @ManagedAttribute(value = "The number of connections", readonly = true) public int getConnectionCount() { - return connectionCount.get(); + return connections.getLo(); + } + + @ManagedAttribute(value = "The number of pending connections", readonly = true) + public int getPendingCount() + { + return connections.getHi(); } @Override public boolean isEmpty() { - return connectionCount.get() == 0; + return connections.getLo() == 0; } @Override @@ -80,29 +91,34 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable { Connection connection = activate(); if (connection == null) - connection = tryCreate(); + { + tryCreate(-1); + connection = activate(); + } return connection; } - private Connection tryCreate() + protected void tryCreate(int maxPending) { while (true) { - int current = getConnectionCount(); - final int next = current + 1; + long encoded = connections.get(); + int pending = AtomicBiInteger.getHi(encoded); + int total = AtomicBiInteger.getLo(encoded); - if (next > maxConnections) + if (LOG.isDebugEnabled()) + LOG.debug("tryCreate {}/{} connections {}/{} pending",total,maxConnections,pending,maxPending); + + if (total >= maxConnections) + return; + + if (maxPending>=0 && pending>=maxPending) + return; + + if (connections.compareAndSet(encoded,pending+1,total+1)) { if (LOG.isDebugEnabled()) - LOG.debug("Max connections {}/{} reached", current, maxConnections); - // Try again the idle connections - return activate(); - } - - if (connectionCount.compareAndSet(current, next)) - { - if (LOG.isDebugEnabled()) - LOG.debug("Connection {}/{} creation", next, maxConnections); + LOG.debug("newConnection {}/{} connections {}/{} pending", total+1, maxConnections, pending+1, maxPending); destination.newConnection(new Promise() { @@ -110,7 +126,8 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable public void succeeded(Connection connection) { if (LOG.isDebugEnabled()) - LOG.debug("Connection {}/{} creation succeeded {}", next, maxConnections, connection); + LOG.debug("Connection {}/{} creation succeeded {}", total+1, maxConnections, connection); + connections.update(-1,0); onCreated(connection); proceed(); } @@ -119,14 +136,13 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable public void failed(Throwable x) { if (LOG.isDebugEnabled()) - LOG.debug("Connection " + next + "/" + maxConnections + " creation failed", x); - connectionCount.decrementAndGet(); + LOG.debug("Connection " + (total+1) + "/" + maxConnections + " creation failed", x); + connections.update(-1,-1); requester.failed(x); } }); - // Try again the idle connections - return activate(); + return; } } } @@ -174,7 +190,7 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable protected void removed(Connection connection) { - int pooled = connectionCount.decrementAndGet(); + int pooled = connections.updateLo(-1); if (LOG.isDebugEnabled()) LOG.debug("Connection removed {} - pooled: {}", connection, pooled); } @@ -184,7 +200,7 @@ public abstract class AbstractConnectionPool implements ConnectionPool, Dumpable { if (closed.compareAndSet(false, true)) { - connectionCount.set(0); + connections.set(0,0); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java index e26aacb8c37..6f2f73ad708 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java @@ -41,6 +41,7 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements S private static final Logger LOG = Log.getLogger(MultiplexConnectionPool.class); private final ReentrantLock lock = new ReentrantLock(); + private final HttpDestination destination; private final Deque idleConnections; private final Map muxedConnections; private final Map busyConnections; @@ -49,12 +50,26 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements S public MultiplexConnectionPool(HttpDestination destination, int maxConnections, Callback requester, int maxMultiplex) { super(destination, maxConnections, requester); + this.destination = destination; this.idleConnections = new ArrayDeque<>(maxConnections); this.muxedConnections = new HashMap<>(maxConnections); this.busyConnections = new HashMap<>(maxConnections); this.maxMultiplex = maxMultiplex; } + @Override + public Connection acquire() + { + Connection connection = activate(); + if (connection == null) + { + int maxPending = 1 + destination.getQueuedRequestCount() / getMaxMultiplex(); + tryCreate(maxPending); + connection = activate(); + } + return connection; + } + protected void lock() { lock.lock(); diff --git a/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties b/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties index 287d28319e0..a7ef5da7827 100644 --- a/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-http-client-transport/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.client.LEVEL=DEBUG +org.eclipse.jetty.client.LEVEL=DEBUG org.eclipse.jetty.http2.hpack.LEVEL=INFO #org.eclipse.jetty.http2.LEVEL=DEBUG #org.eclipse.jetty.io.ssl.LEVEL=DEBUG diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java b/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java new file mode 100644 index 00000000000..34f89170786 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java @@ -0,0 +1,290 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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.util.concurrent.atomic.AtomicLong; + +/** + * An AtomicLong with additional methods to treat it has + * two hi/lo integers. + */ +public class AtomicBiInteger extends AtomicLong +{ + /** + * @return the hi integer value + */ + public int getHi() + { + return getHi(get()); + } + + /** + * @return the lo integer value + */ + public int getLo() + { + return getLo(get()); + } + + /** + * Atomically set the hi integer value without changing + * the lo value. + * @param hi the new hi value + */ + public int setHi(int hi) + { + while(true) + { + long encoded = get(); + long update = encodeHi(encoded,hi); + if (compareAndSet(encoded,update)) + return getHi(encoded); + } + } + + /** + * Atomically set the lo integer value without changing + * the hi value. + * @param lo the new lo value + */ + public int setLo(int lo) + { + while(true) + { + long encoded = get(); + long update = encodeLo(encoded,lo); + if (compareAndSet(encoded,update)) + return getLo(encoded); + } + } + + /** + * Set the hi and lo integer values. + * @param hi the new hi value + * @param lo the new lo value + */ + public void set(int hi, int lo) + { + set(encode(hi,lo)); + } + + /** + * Atomically sets the hi int value to the given updated value + * only if the current value {@code ==} the expected value. + * Concurrent changes to the lo value result in a retry. + * @param expect the expected value + * @param hi the new value + * @return {@code true} if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public boolean compareAndSetHi(int expect, int hi) + { + while(true) + { + long encoded = get(); + if (getHi(encoded)!=expect) + return false; + long update = encodeHi(encoded,hi); + if (compareAndSet(encoded,update)) + return true; + } + } + + /** + * Atomically sets the lo int value to the given updated value + * only if the current value {@code ==} the expected value. + * Concurrent changes to the hi value result in a retry. + * @param expect the expected value + * @param lo the new value + * @return {@code true} if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public boolean compareAndSetLo(int expect, int lo) + { + while(true) + { + long encoded = get(); + if (getLo(encoded)!=expect) + return false; + long update = encodeLo(encoded,lo); + if (compareAndSet(encoded,update)) + return true; + } + } + + /** + * Atomically sets the values to the given updated values + * only if the current encoded value {@code ==} the expected value. + * @param expect the expected encoded values + * @param hi the new hi value + * @param lo the new lo value + * @return {@code true} if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public boolean compareAndSet(long expect, int hi, int lo) + { + long encoded = get(); + long update = encode(hi,lo); + return compareAndSet(encoded,update); + } + + /** + * Atomically sets the values to the given updated values + * only if the current encoded value {@code ==} the expected value. + * @param expectHi the expected hi values + * @param hi the new hi value + * @param expectLo the expected lo values + * @param lo the new lo value + * @return {@code true} if successful. False return indicates that + * the actual value was not equal to the expected value. + */ + public boolean compareAndSet(int expectHi, int hi, int expectLo, int lo) + { + long encoded = encode(expectHi,expectLo); + long update = encode(hi,lo); + return compareAndSet(encoded,update); + } + + /** + * Atomically updates the current hi value with the results of + * applying the given delta, returning the updated value. + * + * @param delta the delta to apply + * @return the updated value + */ + public int updateHi(int delta) + { + while(true) + { + long encoded = get(); + int hi = getHi(encoded)+delta; + long update = encodeHi(encoded,hi); + if (compareAndSet(encoded,update)) + return hi; + } + } + + /** + * Atomically updates the current lo value with the results of + * applying the given delta, returning the updated value. + * + * @param delta the delta to apply + * @return the updated value + */ + public int updateLo(int delta) + { + while(true) + { + long encoded = get(); + int lo = getLo(encoded)+delta; + long update = encodeLo(encoded,lo); + if (compareAndSet(encoded,update)) + return lo; + } + } + + /** + * Atomically updates the current values with the results of + * applying the given deltas. + * + * @param deltaHi the delta to apply to the hi value + * @param deltaLo the delta to apply to the lo value + */ + public void update(int deltaHi, int deltaLo) + { + while(true) + { + long encoded = get(); + long update = encode(getHi(encoded)+deltaHi, getLo(encoded)+deltaLo); + if (compareAndSet(encoded,update)) + return; + } + } + + /** + * Get a hi int value from an encoded long + * @param encoded the encoded value + * @return the hi int value + */ + public static int getHi(long encoded) + { + return (int) ((encoded>>32)&0xFFFF_FFFFl); + } + + /** + * Get a lo int value from an encoded long + * @param encoded the encoded value + * @return the lo int value + */ + public static int getLo(long encoded) + { + return (int) (encoded&0xFFFF_FFFFl); + } + + /** + * Encode hi and lo int values into a long + * @param hi the hi int value + * @param lo the lo int value + * @return the encoded value + * + */ + public static long encode(int hi, int lo) + { + long h = ((long)hi)&0xFFFF_FFFFl; + long l = ((long)lo)&0xFFFF_FFFFl; + long encoded = (h<<32)+l; + return encoded; + } + + + /** + * Encode hi int values into an already encoded long + * @param encoded the encoded value + * @param hi the hi int value + * @return the encoded value + * + */ + public static long encodeHi(long encoded, int hi) + { + long h = ((long)hi)&0xFFFF_FFFFl; + long l = encoded&0xFFFF_FFFFl; + encoded = (h<<32)+l; + return encoded; + } + + /** + * Encode lo int values into an already encoded long + * @param encoded the encoded value + * @param lo the lo int value + * @return the encoded value + * + */ + public static long encodeLo(long encoded, int lo) + { + long h = (encoded>>32)&0xFFFF_FFFFl; + long l = ((long)lo)&0xFFFF_FFFFl; + encoded = (h<<32)+l; + return encoded; + } + + + + + +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/AtomicBiIntegerTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/AtomicBiIntegerTest.java new file mode 100644 index 00000000000..edda43df9e4 --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/AtomicBiIntegerTest.java @@ -0,0 +1,105 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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 static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class AtomicBiIntegerTest +{ + + @Test + public void testBitOperations() + { + long encoded; + + encoded = AtomicBiInteger.encode(0,0); + assertThat(AtomicBiInteger.getHi(encoded),is(0)); + assertThat(AtomicBiInteger.getLo(encoded),is(0)); + + encoded = AtomicBiInteger.encode(1,2); + assertThat(AtomicBiInteger.getHi(encoded),is(1)); + assertThat(AtomicBiInteger.getLo(encoded),is(2)); + + encoded = AtomicBiInteger.encode(Integer.MAX_VALUE,-1); + assertThat(AtomicBiInteger.getHi(encoded),is(Integer.MAX_VALUE)); + assertThat(AtomicBiInteger.getLo(encoded),is(-1)); + encoded = AtomicBiInteger.encodeLo(encoded,42); + assertThat(AtomicBiInteger.getHi(encoded),is(Integer.MAX_VALUE)); + assertThat(AtomicBiInteger.getLo(encoded),is(42)); + + encoded = AtomicBiInteger.encode(-1,Integer.MAX_VALUE); + assertThat(AtomicBiInteger.getHi(encoded),is(-1)); + assertThat(AtomicBiInteger.getLo(encoded),is(Integer.MAX_VALUE)); + encoded = AtomicBiInteger.encodeHi(encoded,42); + assertThat(AtomicBiInteger.getHi(encoded),is(42)); + assertThat(AtomicBiInteger.getLo(encoded),is(Integer.MAX_VALUE)); + + encoded = AtomicBiInteger.encode(Integer.MIN_VALUE,1); + assertThat(AtomicBiInteger.getHi(encoded),is(Integer.MIN_VALUE)); + assertThat(AtomicBiInteger.getLo(encoded),is(1)); + encoded = AtomicBiInteger.encodeLo(encoded,Integer.MAX_VALUE); + assertThat(AtomicBiInteger.getHi(encoded),is(Integer.MIN_VALUE)); + assertThat(AtomicBiInteger.getLo(encoded),is(Integer.MAX_VALUE)); + + encoded = AtomicBiInteger.encode(1,Integer.MIN_VALUE); + assertThat(AtomicBiInteger.getHi(encoded),is(1)); + assertThat(AtomicBiInteger.getLo(encoded),is(Integer.MIN_VALUE)); + encoded = AtomicBiInteger.encodeHi(encoded,Integer.MAX_VALUE); + assertThat(AtomicBiInteger.getHi(encoded),is(Integer.MAX_VALUE)); + assertThat(AtomicBiInteger.getLo(encoded),is(Integer.MIN_VALUE)); + } + + @Test + public void testSet() + { + AtomicBiInteger abi = new AtomicBiInteger(); + assertThat(abi.getHi(),is(0)); + assertThat(abi.getLo(),is(0)); + + abi.setHi(Integer.MAX_VALUE); + assertThat(abi.getHi(),is(Integer.MAX_VALUE)); + assertThat(abi.getLo(),is(0)); + + abi.setLo(Integer.MIN_VALUE); + assertThat(abi.getHi(),is(Integer.MAX_VALUE)); + assertThat(abi.getLo(),is(Integer.MIN_VALUE)); + } + + @Test + public void testCompareAndSet() + { + AtomicBiInteger abi = new AtomicBiInteger(); + assertThat(abi.getHi(),is(0)); + assertThat(abi.getLo(),is(0)); + + assertFalse(abi.compareAndSetHi(1,42)); + assertTrue(abi.compareAndSetHi(0,42)); + assertThat(abi.getHi(),is(42)); + assertThat(abi.getLo(),is(0)); + + assertFalse(abi.compareAndSetLo(1,-42)); + assertTrue(abi.compareAndSetLo(0,-42)); + assertThat(abi.getHi(),is(42)); + assertThat(abi.getLo(),is(-42)); + } + +} From b71cd70bf74df78084a22bd903673b6323c6e1a9 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 7 Mar 2018 11:52:28 +0100 Subject: [PATCH 14/87] Fixes #2297 - HTTP/2 client transport should honor HttpClient.connectBlocking. Introduced property connectBlocking in HTTP2Client so that it can be forwarded by HttpClient and then used for HTTP/2 connects. Also introduced HTTP2Client.bindAddress, again forwarded from HttpClient. Signed-off-by: Simone Bordet --- .../AbstractConnectorHttpClientTransport.java | 11 ++--- .../jetty/http2/client/HTTP2Client.java | 41 ++++++++++++++++++- .../http/HttpClientTransportOverHTTP2.java | 7 +++- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java index 4644c08a03e..669ba41d757 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java @@ -88,20 +88,21 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, destination.getHost()); context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, destination.getPort()); + boolean connected = true; if (client.isConnectBlocking()) { channel.socket().connect(address, (int)client.getConnectTimeout()); channel.configureBlocking(false); - selectorManager.accept(channel, context); } else { channel.configureBlocking(false); - if (channel.connect(address)) - selectorManager.accept(channel, context); - else - selectorManager.connect(channel, context); + connected = channel.connect(address); } + if (connected) + selectorManager.accept(channel, context); + else + selectorManager.connect(channel, context); } // Must catch all exceptions, since some like // UnresolvedAddressException are not IOExceptions. diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java index 1eb23d3da7b..83ff1c487e7 100644 --- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java +++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.http2.client; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; @@ -122,6 +123,8 @@ public class HTTP2Client extends ContainerLifeCycle private int selectors = 1; private long idleTimeout = 30000; private long connectTimeout = 10000; + private boolean connectBlocking; + private SocketAddress bindAddress; private int inputBufferSize = 8192; private List protocols = Arrays.asList("h2", "h2-17", "h2-16", "h2-15", "h2-14"); private int initialSessionRecvWindow = 16 * 1024 * 1024; @@ -266,6 +269,27 @@ public class HTTP2Client extends ContainerLifeCycle selector.setConnectTimeout(connectTimeout); } + @ManagedAttribute("Whether the connect() operation is blocking") + public boolean isConnectBlocking() + { + return connectBlocking; + } + + public void setConnectBlocking(boolean connectBlocking) + { + this.connectBlocking = connectBlocking; + } + + public SocketAddress getBindAddress() + { + return bindAddress; + } + + public void setBindAddress(SocketAddress bindAddress) + { + this.bindAddress = bindAddress; + } + @ManagedAttribute("The size of the buffer used to read from the network") public int getInputBufferSize() { @@ -325,10 +349,23 @@ public class HTTP2Client extends ContainerLifeCycle try { SocketChannel channel = SocketChannel.open(); + SocketAddress bindAddress = getBindAddress(); + if (bindAddress != null) + channel.bind(bindAddress); configure(channel); - channel.configureBlocking(false); + boolean connected = true; + if (isConnectBlocking()) + { + channel.socket().connect(address, (int)getConnectTimeout()); + channel.configureBlocking(false); + } + else + { + channel.configureBlocking(false); + connected = channel.connect(address); + } context = contextFrom(sslContextFactory, address, listener, promise, context); - if (channel.connect(address)) + if (connected) selector.accept(channel, context); else selector.connect(channel, context); diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java index 0bcb1ceb05e..f024d8974ef 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2.java @@ -124,14 +124,17 @@ public class HttpClientTransportOverHTTP2 extends AbstractHttpClientTransport @Override public void connect(InetSocketAddress address, Map context) { - client.setConnectTimeout(getHttpClient().getConnectTimeout()); + HttpClient httpClient = getHttpClient(); + client.setConnectTimeout(httpClient.getConnectTimeout()); + client.setConnectBlocking(httpClient.isConnectBlocking()); + client.setBindAddress(httpClient.getBindAddress()); SessionListenerPromise listenerPromise = new SessionListenerPromise(context); HttpDestinationOverHTTP2 destination = (HttpDestinationOverHTTP2)context.get(HTTP_DESTINATION_CONTEXT_KEY); SslContextFactory sslContextFactory = null; if (HttpScheme.HTTPS.is(destination.getScheme())) - sslContextFactory = getHttpClient().getSslContextFactory(); + sslContextFactory = httpClient.getSslContextFactory(); client.connect(sslContextFactory, address, listenerPromise, listenerPromise, context); } From 7004aaa5389eb1eb60c56ea8fd20a9621f322fa8 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 7 Mar 2018 20:58:03 +1000 Subject: [PATCH 15/87] #2298 Override the processor number with an environment variable Signed-off-by: olivier lamy --- .../annotations/AnnotationConfiguration.java | 3 +- .../org/eclipse/jetty/client/HttpClient.java | 3 +- .../http/HttpClientTransportOverHTTP.java | 3 +- .../http/HttpClientTransportOverFCGI.java | 3 +- .../server/proxy/FastCGIProxyServlet.java | 3 +- .../server/AbstractHttpClientServerTest.java | 5 +- .../org/eclipse/jetty/io/SelectorManager.java | 5 +- .../jetty/proxy/AbstractProxyServlet.java | 3 +- .../jetty/proxy/ProxyServletLoadTest.java | 3 +- .../jetty/server/AbstractConnector.java | 3 +- .../servlets/DataRateLimitedServlet.java | 3 +- .../eclipse/jetty/util/ProcessorUtils.java | 49 +++++++++++++++++++ .../jetty/util/thread/ExecutorThreadPool.java | 3 +- .../util/thread/ReservedThreadExecutor.java | 3 +- .../jetty/util/thread/ThreadPoolBudget.java | 3 +- .../jetty/util/ProcessorUtilsTest.java | 36 ++++++++++++++ .../jetty/util/QueueBenchmarkTest.java | 4 +- .../jetty/http/client/HttpClientLoadTest.java | 3 +- 18 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java create mode 100644 jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index 960e9515896..03bc217df77 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -47,6 +47,7 @@ import org.eclipse.jetty.annotations.AnnotationParser.Handler; import org.eclipse.jetty.plus.annotation.ContainerInitializer; import org.eclipse.jetty.util.JavaVersion; import org.eclipse.jetty.util.MultiException; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; @@ -453,7 +454,7 @@ public class AnnotationConfiguration extends AbstractConfiguration start = System.nanoTime(); //execute scan, either effectively synchronously (1 thread only), or asynchronously (limited by number of processors available) - final Semaphore task_limit = (isUseMultiThreading(context)? new Semaphore(Runtime.getRuntime().availableProcessors()):new Semaphore(1)); + final Semaphore task_limit = (isUseMultiThreading(context)? new Semaphore(ProcessorUtils.availableProcessors()):new Semaphore( 1)); final CountDownLatch latch = new CountDownLatch(_parserTasks.size()); final MultiException me = new MultiException(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index cdbea4365fc..53620d78bde 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -64,6 +64,7 @@ import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; import org.eclipse.jetty.util.Fields; import org.eclipse.jetty.util.Jetty; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.SocketAddressResolver; import org.eclipse.jetty.util.annotation.ManagedAttribute; @@ -213,7 +214,7 @@ public class HttpClient extends ContainerLifeCycle byteBufferPool = new MappedByteBufferPool(2048, executor instanceof ThreadPool.SizedThreadPool ? ((ThreadPool.SizedThreadPool)executor).getMaxThreads()/2 - : Runtime.getRuntime().availableProcessors()*2); + : ProcessorUtils.availableProcessors()*2); addBean(byteBufferPool); if (scheduler == null) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java index da25e45cedf..d91bc1da02a 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java @@ -27,6 +27,7 @@ import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.Origin; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -35,7 +36,7 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran { public HttpClientTransportOverHTTP() { - this(Math.max(1, Runtime.getRuntime().availableProcessors() / 2)); + this(Math.max( 1, ProcessorUtils.availableProcessors() / 2)); } public HttpClientTransportOverHTTP(int selectors) diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java index b5642f8841a..90aafa519eb 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpClientTransportOverFCGI.java @@ -32,6 +32,7 @@ import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.fcgi.FCGI; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -44,7 +45,7 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran public HttpClientTransportOverFCGI(String scriptRoot) { - this(Math.max(1, Runtime.getRuntime().availableProcessors() / 2), false, scriptRoot); + this( Math.max( 1, ProcessorUtils.availableProcessors() / 2), false, scriptRoot); } public HttpClientTransportOverFCGI(int selectors, boolean multiplexed, String scriptRoot) diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java index 2a0243c06cd..15b769f8f3d 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java @@ -40,6 +40,7 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.proxy.AsyncProxyServlet; +import org.eclipse.jetty.util.ProcessorUtils; /** * Specific implementation of {@link org.eclipse.jetty.proxy.AsyncProxyServlet.Transparent} for FastCGI. @@ -111,7 +112,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent String scriptRoot = config.getInitParameter(SCRIPT_ROOT_INIT_PARAM); if (scriptRoot == null) throw new IllegalArgumentException("Mandatory parameter '" + SCRIPT_ROOT_INIT_PARAM + "' not configured"); - int selectors = Math.max(1, Runtime.getRuntime().availableProcessors() / 2); + int selectors = Math.max( 1, ProcessorUtils.availableProcessors() / 2); String value = config.getInitParameter("selectors"); if (value != null) selectors = Integer.parseInt(value); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java index d8d41f538fd..f212c832a37 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.LeakDetector; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.After; @@ -59,8 +60,8 @@ public abstract class AbstractHttpClientServerTest ServerFCGIConnectionFactory fcgiConnectionFactory = new ServerFCGIConnectionFactory(new HttpConfiguration()); serverBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()); - connector = new ServerConnector(server, null, null, serverBufferPool, - 1, Math.max(1, Runtime.getRuntime().availableProcessors() / 2), fcgiConnectionFactory); + connector = new ServerConnector( server, null, null, serverBufferPool, + 1, Math.max( 1, ProcessorUtils.availableProcessors() / 2), fcgiConnectionFactory); // connector.setPort(9000); server.addConnector(connector); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java index 7da0ee066c8..318e69e9933 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java @@ -32,6 +32,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.IntUnaryOperator; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -68,10 +69,10 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump if (executor instanceof ThreadPool.SizedThreadPool) { int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads(); - int cpus = Runtime.getRuntime().availableProcessors(); + int cpus = ProcessorUtils.availableProcessors(); return Math.max(1,Math.min(cpus/2,threads/16)); } - return Math.max(1,Runtime.getRuntime().availableProcessors()/2); + return Math.max(1,ProcessorUtils.availableProcessors()/2); } protected SelectorManager(Executor executor, Scheduler scheduler) diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java index 4352745cd60..66b56dab016 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AbstractProxyServlet.java @@ -50,6 +50,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.util.HttpCookieStore; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -352,7 +353,7 @@ public abstract class AbstractProxyServlet extends HttpServlet */ protected HttpClient newHttpClient() { - int selectors = Math.max(1, Runtime.getRuntime().availableProcessors() / 2); + int selectors = Math.max(1,ProcessorUtils.availableProcessors()/2); String value = getServletConfig().getInitParameter("selectors"); if (value != null) selectors = Integer.parseInt(value); diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java index 04f0446a902..9e7256904d1 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletLoadTest.java @@ -42,6 +42,7 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -149,7 +150,7 @@ public class ProxyServletLoadTest startClient(); // Number of clients to simulate - int clientCount = Runtime.getRuntime().availableProcessors(); + int clientCount = ProcessorUtils.availableProcessors(); // Latch for number of clients still active (used to terminate test) final CountDownLatch activeClientLatch = new CountDownLatch(clientCount); 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 1baf71c2ee8..4129af1d889 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 @@ -42,6 +42,7 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.util.FutureCallback; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -196,7 +197,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co for (ConnectionFactory factory:factories) addConnectionFactory(factory); - int cores = Runtime.getRuntime().availableProcessors(); + int cores = ProcessorUtils.availableProcessors(); if (acceptors < 0) acceptors=Math.max(1, Math.min(4,cores/8)); if (acceptors > cores) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DataRateLimitedServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DataRateLimitedServlet.java index efa66326812..aaf2bf1709b 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DataRateLimitedServlet.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DataRateLimitedServlet.java @@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.HttpOutput; +import org.eclipse.jetty.util.ProcessorUtils; /** * A servlet that uses the Servlet 3.1 asynchronous IO API to server @@ -78,7 +79,7 @@ public class DataRateLimitedServlet extends HttpServlet if (tmp!=null) pauseNS=TimeUnit.MILLISECONDS.toNanos(Integer.parseInt(tmp)); tmp = getInitParameter("pool"); - int pool=tmp==null?Runtime.getRuntime().availableProcessors():Integer.parseInt(tmp); + int pool=tmp==null?ProcessorUtils.availableProcessors():Integer.parseInt(tmp); // Create and start a shared scheduler. scheduler=new ScheduledThreadPoolExecutor(pool); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java new file mode 100644 index 00000000000..18c43e98b52 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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; + +/** + * ProcessorUtils return the default value for processor number fron {@link Runtime#getRuntime()#availableProcessors()} + * but in a virtual environment you can override it using env var JETTY_AVAILABLE_PROCESSORS + */ +public class ProcessorUtils +{ + private static int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors(); + + static + { + String avlProcEnv = System.getenv( "JETTY_AVAILABLE_PROCESSORS" ); + if (avlProcEnv != null) + { + try + { + AVAILABLE_PROCESSORS = Integer.parseInt( avlProcEnv ); + } + catch ( NumberFormatException e ) + { + // ignore + } + } + } + + public static int availableProcessors() + { + return AVAILABLE_PROCESSORS; + } +} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java index b37202a8de9..fb95092a2ef 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java @@ -28,6 +28,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -78,7 +79,7 @@ public class ExecutorThreadPool extends ContainerLifeCycle implements ThreadPool public ExecutorThreadPool(ThreadPoolExecutor executor, int reservedThreads, ThreadGroup group) { - this(executor, Math.min(Runtime.getRuntime().availableProcessors(), executor.getCorePoolSize()), reservedThreads, group); + this( executor, Math.min(ProcessorUtils.availableProcessors(),executor.getCorePoolSize()),reservedThreads,group); } private ExecutorThreadPool(ThreadPoolExecutor executor, int minThreads, int reservedThreads, ThreadGroup group) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java index 39ca9a8ad12..a0959c90f9e 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.AbstractLifeCycle; @@ -96,7 +97,7 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec { if (capacity>=0) return capacity; - int cpus = Runtime.getRuntime().availableProcessors(); + int cpus = ProcessorUtils.availableProcessors(); if (executor instanceof ThreadPool.SizedThreadPool) { int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads(); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadPoolBudget.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadPoolBudget.java index d9725fcb61b..2269effe41f 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadPoolBudget.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadPoolBudget.java @@ -25,6 +25,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -97,7 +98,7 @@ public class ThreadPoolBudget */ public ThreadPoolBudget(ThreadPool.SizedThreadPool pool) { - this(pool,Math.min(Runtime.getRuntime().availableProcessors(),pool.getMinThreads())); + this(pool,Math.min(ProcessorUtils.availableProcessors(),pool.getMinThreads())); } /** diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java new file mode 100644 index 00000000000..df2acccf4df --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java @@ -0,0 +1,36 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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 org.junit.Assert; +import org.junit.Test; + +/** + * we cannot really add env var in a unit test... so only test we get default value + */ +public class ProcessorUtilsTest +{ + + @Test + public void get_default_value(){ + Assert.assertEquals(Runtime.getRuntime().availableProcessors(), ProcessorUtils.availableProcessors()); + } + + +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java index 24952179068..43350bb9f27 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/QueueBenchmarkTest.java @@ -47,7 +47,7 @@ public class QueueBenchmarkTest @Test public void testQueues() throws Exception { - int cores = Runtime.getRuntime().availableProcessors(); + int cores = ProcessorUtils.availableProcessors(); Assume.assumeTrue(cores > 1); final int readers = cores / 2; @@ -66,7 +66,7 @@ public class QueueBenchmarkTest @Test public void testBlockingQueues() throws Exception { - int cores = Runtime.getRuntime().availableProcessors(); + int cores = ProcessorUtils.availableProcessors(); Assume.assumeTrue(cores > 1); final int readers = cores / 2; diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java index ce97eb30642..615eb8708e1 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java @@ -56,6 +56,7 @@ import org.eclipse.jetty.unixsocket.UnixSocketConnector; import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.LeakDetector; +import org.eclipse.jetty.util.ProcessorUtils; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; @@ -86,7 +87,7 @@ public class HttpClientLoadTest extends AbstractTest unixSocketConnector.setUnixSocket( sockFile.toString() ); return unixSocketConnector; } - int cores = Runtime.getRuntime().availableProcessors(); + int cores = ProcessorUtils.availableProcessors(); ByteBufferPool byteBufferPool = new ArrayByteBufferPool(); byteBufferPool = new LeakTrackingByteBufferPool(byteBufferPool); return new ServerConnector(server, null, null, byteBufferPool, From 8dffd7e4765b4039ff54c96164b299c5d3ef479e Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 7 Mar 2018 22:07:49 +1000 Subject: [PATCH 16/87] fix javadoc Signed-off-by: olivier lamy --- .../main/java/org/eclipse/jetty/util/AtomicBiInteger.java | 1 + .../main/java/org/eclipse/jetty/util/ProcessorUtils.java | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java b/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java index 34f89170786..948262836e6 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java @@ -46,6 +46,7 @@ public class AtomicBiInteger extends AtomicLong * Atomically set the hi integer value without changing * the lo value. * @param hi the new hi value + * @return the hi int value */ public int setHi(int hi) { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java index 18c43e98b52..30491b9aaa6 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java @@ -19,7 +19,7 @@ package org.eclipse.jetty.util; /** - * ProcessorUtils return the default value for processor number fron {@link Runtime#getRuntime()#availableProcessors()} + * ProcessorUtils return the default value for processor number from {@link Runtime} * but in a virtual environment you can override it using env var JETTY_AVAILABLE_PROCESSORS */ public class ProcessorUtils @@ -42,6 +42,10 @@ public class ProcessorUtils } } + /** + * + * @return the number of processors + */ public static int availableProcessors() { return AVAILABLE_PROCESSORS; From bca53be4f4e481ef7fd4dd2e00032cc91f4c1bae Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 7 Mar 2018 07:55:05 -0600 Subject: [PATCH 17/87] Fixes #2282 - Fixing Fuzzer. + Client lifecycle now honored + Slow write now possible --- .../websocket/common/test/BlockheadClientRequest.java | 2 ++ .../websocket/common/test/BlockheadConnection.java | 2 +- .../eclipse/jetty/websocket/common/test/Fuzzer.java | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java index 8dd9b2801f9..ccd8a209412 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java @@ -225,6 +225,8 @@ public class BlockheadClientRequest extends HttpRequest implements Response.Comp endp, client.getExecutor()); + endp.setIdleTimeout(client.getIdleTimeout()); + connection.setUpgradeResponseHeaders(response.getHeaders()); // Now swap out the connection diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java index 2269e7f3f14..a8374e323b8 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java @@ -194,7 +194,7 @@ public class BlockheadConnection extends AbstractConnection implements Connectio { int len = Math.min(numBytes, buf.remaining()); ByteBuffer slice = buf.slice(); - buf.position(len); + buf.limit(len); try { getEndPoint().flush(slice); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java index 26910fcf0e4..d83ddabe863 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java @@ -84,6 +84,8 @@ public class Fuzzer implements AutoCloseable client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + this.generator = testcase.getLaxGenerator(); this.testname = testcase.getTestMethodName(); } @@ -111,6 +113,14 @@ public class Fuzzer implements AutoCloseable public void close() { this.clientConnection.close(); + try + { + this.client.stop(); + } + catch (Exception ignore) + { + LOG.ignore(ignore); + } } public void disconnect() @@ -121,6 +131,7 @@ public class Fuzzer implements AutoCloseable public void connect() throws IOException { BlockheadClientRequest request = this.client.newWsRequest(testcase.getServerURI()); + request.idleTimeout(2, TimeUnit.SECONDS); request.header("X-TestCase", testname); Future connFut = request.sendAsync(); From 5712b0217f9fc43a14bf729e341f5cfd877bb4d7 Mon Sep 17 00:00:00 2001 From: WalkerWatch Date: Wed, 7 Mar 2018 11:31:47 -0500 Subject: [PATCH 18/87] Issue #2179 - Documentation - Adding end date for 9.2 --- .../main/asciidoc/quick-start/introduction/what-version.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-documentation/src/main/asciidoc/quick-start/introduction/what-version.adoc b/jetty-documentation/src/main/asciidoc/quick-start/introduction/what-version.adoc index a14335c1845..52902ec03c8 100644 --- a/jetty-documentation/src/main/asciidoc/quick-start/introduction/what-version.adoc +++ b/jetty-documentation/src/main/asciidoc/quick-start/introduction/what-version.adoc @@ -35,7 +35,7 @@ _____ |Version |Year |Home |JVM |Protocols |Servlet |JSP |Status |9.4 |2016- |Eclipse |1.8 |HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI |3.1 |2.3 |Stable |9.3 |2015- |Eclipse |1.8 |HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI |3.1 |2.3 |Stable -|9.2 |2014- |Eclipse |1.7 |HTTP/1.1 RFC2616, javax.websocket, SPDY v3 |3.1 |2.3 |Deprecated / *End of Life January 2018* +|9.2 |2014-2018 |Eclipse |1.7 |HTTP/1.1 RFC2616, javax.websocket, SPDY v3 |3.1 |2.3 |Deprecated / *End of Life January 2018* |8 |2009-2014 |Eclipse/Codehaus |1.6 |HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3 |3.0 |2.2 |Deprecated / *End of Life November 2014* |7 |2008-2014 |Eclipse/Codehaus |1.5 |HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3 |2.5 |2.1 |Deprecated / *End of Life November 2014* |6 |2006-2010 |Codehaus |1.4-1.5 |HTTP/1.1 RFC2616 |2.5 |2.0 |Deprecated / *End of Life November 2010* From abf126284850366dacc122d8028f6f7ccf8507fd Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 7 Mar 2018 14:29:22 -0600 Subject: [PATCH 19/87] Issue #2282 - More work on websocket server side tests --- .../jsr356/DecoderReaderManySmallTest.java | 138 ++--- .../websocket/jsr356/DecoderReaderTest.java | 190 +++--- .../jetty/websocket/jsr356/EncoderTest.java | 168 +++--- jetty-websocket/websocket-client/pom.xml | 6 + .../websocket/client/BadNetworkTest.java | 52 +- .../websocket/client/ClientCloseTest.java | 154 +++-- .../websocket/client/ClientConnectTest.java | 288 ++++----- .../jetty/websocket/client/CookieTest.java | 68 ++- .../websocket/client/JettyTrackingSocket.java | 5 +- .../websocket/client/ServerReadThread.java | 133 ----- .../websocket/client/ServerWriteThread.java | 9 +- .../jetty/websocket/client/SessionTest.java | 75 +-- .../websocket/client/SlowClientTest.java | 80 ++- .../websocket/client/SlowServerTest.java | 119 ++-- .../client/TomcatServerQuirksTest.java | 71 ++- .../websocket/client/WebSocketClientTest.java | 233 ++++---- jetty-websocket/websocket-common/pom.xml | 6 + .../common/test/BlockheadClientRequest.java | 1 + .../common/test/BlockheadConnection.java | 32 +- .../common/test/BlockheadServer.java | 256 ++++++-- .../test/BlockheadServerConnection.java | 554 +----------------- .../test/IBlockheadServerConnection.java | 68 --- .../jetty/websocket/common/test/Timeouts.java | 9 + .../websocket/server/ab/TestABCase9.java | 1 - 24 files changed, 1102 insertions(+), 1614 deletions(-) delete mode 100644 jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerReadThread.java delete mode 100644 jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java index 1500064c44b..1d9240ff2d1 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -40,13 +41,19 @@ import javax.websocket.WebSocketContainer; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.common.CloseInfo; +import org.eclipse.jetty.websocket.common.OpCode; +import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; @@ -110,60 +117,9 @@ public class DecoderReaderManySmallTest } } - private static class EventIdServer implements Runnable - { - private BlockheadServer server; - private IBlockheadServerConnection sconnection; - private CountDownLatch connectLatch = new CountDownLatch(1); - - public EventIdServer(BlockheadServer server) - { - this.server = server; - } - - @Override - public void run() - { - try - { - sconnection = server.accept(); - sconnection.setSoTimeout(60000); - sconnection.upgrade(); - } - catch (Exception e) - { - LOG.warn(e); - } - finally - { - connectLatch.countDown(); - } - } - - public void writeSequentialIds(int from, int to) throws IOException - { - for (int id = from; id < to; id++) - { - TextFrame frame = new TextFrame(); - frame.setPayload(Integer.toString(id)); - sconnection.write(frame); - } - } - - public void close() throws IOException - { - sconnection.close(); - } - - public void awaitConnect() throws InterruptedException - { - connectLatch.await(1,TimeUnit.SECONDS); - } - } - private static final Logger LOG = Log.getLogger(DecoderReaderManySmallTest.class); - private BlockheadServer server; + private static BlockheadServer server; private WebSocketContainer client; @Before @@ -178,15 +134,15 @@ public class DecoderReaderManySmallTest ((LifeCycle)client).stop(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -194,31 +150,55 @@ public class DecoderReaderManySmallTest @Test public void testManyIds() throws Exception { + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + EventIdSocket ids = new EventIdSocket(); - EventIdServer idserver = new EventIdServer(server); - new Thread(idserver).start(); client.connectToServer(ids,server.getWsUri()); - idserver.awaitConnect(); - int from = 1000; - int to = 2000; - idserver.writeSequentialIds(from,to); - idserver.close(); - int count = from - to; - ids.awaitClose(); - // collect seen ids - List seen = new ArrayList<>(); - for(int i=0; i + { + WebSocketFrame wsFrame = (WebSocketFrame) frame; + if (wsFrame.getOpCode() == OpCode.TEXT) + { + String msg = wsFrame.getPayloadAsUTF8(); + if (msg == "generate") + { + for (int id = from; id < to; id++) + { + TextFrame event = new TextFrame(); + event.setPayload(Integer.toString(id)); + serverConn.write(event); + } + serverConn.write(new CloseInfo(StatusCode.NORMAL).asFrame()); + } + } + }); + + int count = from - to; + ids.awaitClose(); + // collect seen ids + List seen = new ArrayList<>(); + for (int i = 0; i < count; i++) + { + EventId id = ids.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + // validate that ids don't repeat. + Assert.assertFalse("Already saw ID: " + id.eventId, seen.contains(id.eventId)); + seen.add(id.eventId); + } + + // validate that all expected ids have been seen (order is irrelevant here) + for (int expected = from; expected < to; expected++) + { + Assert.assertTrue("Has expected id:" + expected, seen.contains(expected)); + } } } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java index 56792c47554..3d0f70ae66d 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java @@ -27,6 +27,8 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -49,13 +51,14 @@ import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; +import org.junit.BeforeClass; import org.junit.Test; public class DecoderReaderTest @@ -125,6 +128,7 @@ public class DecoderReaderTest @ClientEndpoint(decoders = { QuotesDecoder.class }) public static class QuotesSocket { + private static final Logger LOG = Log.getLogger(QuotesSocket.class); public LinkedBlockingQueue messageQueue = new LinkedBlockingQueue<>(); private CountDownLatch closeLatch = new CountDownLatch(1); @@ -137,12 +141,15 @@ public class DecoderReaderTest @OnMessage public synchronized void onMessage(Quotes msg) { - Integer h=hashCode(); messageQueue.offer(msg); - System.out.printf("%x: Quotes from: %s%n",h,msg.author); - for (String quote : msg.quotes) + if(LOG.isDebugEnabled()) { - System.out.printf("%x: - %s%n",h,quote); + String hashcode = Integer.toHexString(Objects.hashCode(this)); + LOG.debug("{}: Quotes from: {}", hashcode, msg.author); + for (String quote : msg.quotes) + { + LOG.debug("{}: - {}", hashcode, quote); + } } } @@ -152,82 +159,7 @@ public class DecoderReaderTest } } - private static class QuoteServer implements Runnable - { - private BlockheadServer server; - private IBlockheadServerConnection sconnection; - private CountDownLatch connectLatch = new CountDownLatch(1); - - public QuoteServer(BlockheadServer server) - { - this.server = server; - } - - @Override - public void run() - { - try - { - sconnection = server.accept(); - sconnection.setSoTimeout(60000); - sconnection.upgrade(); - } - catch (Exception e) - { - LOG.warn(e); - } - finally - { - connectLatch.countDown(); - } - } - - public void writeQuotes(String filename) throws IOException - { - // read file - File qfile = MavenTestingUtils.getTestResourceFile(filename); - List lines = new ArrayList<>(); - try (FileReader reader = new FileReader(qfile); BufferedReader buf = new BufferedReader(reader)) - { - String line; - while ((line = buf.readLine()) != null) - { - lines.add(line); - } - } - // write file out, each line on a separate frame, but as - // 1 whole message - for (int i = 0; i < lines.size(); i++) - { - WebSocketFrame frame; - if (i == 0) - { - frame = new TextFrame(); - } - else - { - frame = new ContinuationFrame(); - } - frame.setFin((i >= (lines.size() - 1))); - frame.setPayload(BufferUtil.toBuffer(lines.get(i) + "\n")); - sconnection.write(frame); - } - } - - public void close() throws IOException - { - sconnection.close(); - } - - public void awaitConnect() throws InterruptedException - { - connectLatch.await(1,TimeUnit.SECONDS); - } - } - - private static final Logger LOG = Log.getLogger(DecoderReaderTest.class); - - private BlockheadServer server; + private static BlockheadServer server; private WebSocketContainer client; @Before @@ -242,55 +174,91 @@ public class DecoderReaderTest ((LifeCycle)client).stop(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } - // TODO analyse and fix - @Ignore @Test public void testSingleQuotes() throws Exception { + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + QuotesSocket quoter = new QuotesSocket(); - QuoteServer qserver = new QuoteServer(server); - new Thread(qserver).start(); client.connectToServer(quoter,server.getWsUri()); - qserver.awaitConnect(); - qserver.writeQuotes("quotes-ben.txt"); - qserver.close(); - quoter.awaitClose(); - Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - Assert.assertThat("Quotes Author",quotes.author,is("Benjamin Franklin")); - Assert.assertThat("Quotes Count",quotes.quotes.size(),is(3)); + + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + writeQuotes(serverConn, "quotes-ben.txt"); + + Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Quotes Author", quotes.author, is("Benjamin Franklin")); + Assert.assertThat("Quotes Count", quotes.quotes.size(), is(3)); + } } - // TODO analyse and fix @Test - @Ignore ("Quotes appear to be able to arrive in any order?") + // @Ignore ("Quotes appear to be able to arrive in any order?") public void testTwoQuotes() throws Exception { + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + QuotesSocket quoter = new QuotesSocket(); - QuoteServer qserver = new QuoteServer(server); - new Thread(qserver).start(); client.connectToServer(quoter,server.getWsUri()); - qserver.awaitConnect(); - qserver.writeQuotes("quotes-ben.txt"); - qserver.writeQuotes("quotes-twain.txt"); - qserver.close(); - quoter.awaitClose(); - Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - Assert.assertThat("Quotes Author",quotes.author,is("Benjamin Franklin")); - Assert.assertThat("Quotes Count",quotes.quotes.size(),is(3)); - quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - Assert.assertThat("Quotes Author",quotes.author,is("Mark Twain")); + + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + writeQuotes( serverConn,"quotes-ben.txt"); + writeQuotes( serverConn,"quotes-twain.txt"); + Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Quotes Author", quotes.author, is("Benjamin Franklin")); + Assert.assertThat("Quotes Count", quotes.quotes.size(), is(3)); + quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + Assert.assertThat("Quotes Author", quotes.author, is("Mark Twain")); + } + } + + private void writeQuotes(BlockheadConnection conn, String filename) throws IOException + { + // read file + File qfile = MavenTestingUtils.getTestResourceFile(filename); + List lines = new ArrayList<>(); + try (FileReader reader = new FileReader(qfile); BufferedReader buf = new BufferedReader(reader)) + { + String line; + while ((line = buf.readLine()) != null) + { + lines.add(line); + } + } + // write file out, each line on a separate frame, but as + // 1 whole message + for (int i = 0; i < lines.size(); i++) + { + WebSocketFrame frame; + if (i == 0) + { + frame = new TextFrame(); + } + else + { + frame = new ContinuationFrame(); + } + frame.setFin((i >= (lines.size() - 1))); + frame.setPayload(BufferUtil.toBuffer(lines.get(i) + "\n")); + conn.write(frame); + } } } diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java index 807ca8444e2..8b83b999f3f 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java @@ -27,8 +27,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; import javax.websocket.ClientEndpointConfig; import javax.websocket.ContainerProvider; @@ -44,65 +44,21 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.extensions.Frame; +import org.eclipse.jetty.websocket.common.OpCode; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public class EncoderTest { - private static class EchoServer - { - private BlockheadServer server; - private IBlockheadServerConnection sconnection; - private CountDownLatch connectLatch = new CountDownLatch(1); - - public EchoServer(BlockheadServer server) - { - this.server = server; - } - - public void start() - { - CompletableFuture.runAsync(() -> { - try - { - sconnection = server.accept(); - sconnection.setSoTimeout(10000); - sconnection.upgrade(); - sconnection.enableIncomingEcho(true); - sconnection.startReadThread(); - } - catch (Exception e) - { - LOG.warn(e); - } - finally - { - connectLatch.countDown(); - } - }); - } - - public void stop() - { - if (this.sconnection != null) - { - try - { - this.sconnection.close(); - } - catch (IOException ignore) - { - /* ignore */ - } - } - } - } - public static class Quotes { private String author; @@ -184,10 +140,22 @@ public class EncoderTest private static final Logger LOG = Log.getLogger(EncoderTest.class); - private BlockheadServer server; - + private static BlockheadServer server; private WebSocketContainer client; + @BeforeClass + public static void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + server.stop(); + } + private void assertReceivedQuotes(String result, Quotes quotes) { Assert.assertThat("Quote Author",result,containsString("Author: " + quotes.getAuthor())); @@ -229,42 +197,33 @@ public class EncoderTest client = ContainerProvider.getWebSocketContainer(); client.setDefaultMaxSessionIdleTimeout(10000); } - + @After public void stopClient() throws Exception { ((LifeCycle)client).stop(); } - - @Before - public void startServer() throws Exception - { - server = new BlockheadServer(); - server.start(); - } - - @After - public void stopServer() throws Exception - { - server.stop(); - } @Test(timeout = 10000) public void testSingleQuotes() throws Exception { - EchoServer eserver = new EchoServer(server); - try + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + + QuotesSocket quoter = new QuotesSocket(); + + ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create(); + List> encoders = new ArrayList<>(); + encoders.add(QuotesEncoder.class); + builder.encoders(encoders); + ClientEndpointConfig cec = builder.build(); + client.connectToServer(quoter,cec,server.getWsUri()); + + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - eserver.start(); - - QuotesSocket quoter = new QuotesSocket(); - - ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create(); - List> encoders = new ArrayList<>(); - encoders.add(QuotesEncoder.class); - builder.encoders(encoders); - ClientEndpointConfig cec = builder.build(); - client.connectToServer(quoter,cec,server.getWsUri()); + // Setup echo of frames on server side + serverConn.setIncomingFrameConsumer(new DataFrameEcho(serverConn)); Quotes ben = getQuotes("quotes-ben.txt"); quoter.write(ben); @@ -272,27 +231,27 @@ public class EncoderTest String result = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertReceivedQuotes(result,ben); } - finally - { - eserver.stop(); - } } @Test(timeout = 10000) public void testTwoQuotes() throws Exception { - EchoServer eserver = new EchoServer(server); - try - { - eserver.start(); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); - QuotesSocket quoter = new QuotesSocket(); - ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create(); - List> encoders = new ArrayList<>(); - encoders.add(QuotesEncoder.class); - builder.encoders(encoders); - ClientEndpointConfig cec = builder.build(); - client.connectToServer(quoter,cec,server.getWsUri()); + QuotesSocket quoter = new QuotesSocket(); + ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create(); + List> encoders = new ArrayList<>(); + encoders.add(QuotesEncoder.class); + builder.encoders(encoders); + ClientEndpointConfig cec = builder.build(); + client.connectToServer(quoter,cec,server.getWsUri()); + + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // Setup echo of frames on server side + serverConn.setIncomingFrameConsumer(new DataFrameEcho(serverConn)); Quotes ben = getQuotes("quotes-ben.txt"); Quotes twain = getQuotes("quotes-twain.txt"); @@ -304,9 +263,26 @@ public class EncoderTest result = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertReceivedQuotes(result,twain); } - finally + } + + private static class DataFrameEcho implements Consumer + { + private final BlockheadConnection connection; + + public DataFrameEcho(BlockheadConnection connection) { - eserver.stop(); + this.connection = connection; + } + + @Override + public void accept(Frame frame) + { + if (OpCode.isDataFrame(frame.getOpCode())) + { + WebSocketFrame copy = WebSocketFrame.copy(frame); + copy.setMask(null); // remove client masking + connection.write(copy); + } } } } diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 91cc5fd0a65..74db3b95ff8 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -40,6 +40,12 @@ websocket-common ${project.version}
+ + org.eclipse.jetty + jetty-server + ${project.version} + test + org.eclipse.jetty.websocket websocket-common 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 index 85a26b59156..a556b401936 100644 --- 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 @@ -19,6 +19,7 @@ package org.eclipse.jetty.websocket.client; import java.net.URI; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -26,10 +27,13 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; /** @@ -39,7 +43,7 @@ public class BadNetworkTest { public ByteBufferPool bufferPool = new MappedByteBufferPool(); - private BlockheadServer server; + private static BlockheadServer server; private WebSocketClient client; @Before @@ -50,8 +54,8 @@ public class BadNetworkTest client.start(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); @@ -63,8 +67,8 @@ public class BadNetworkTest client.stop(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -77,12 +81,9 @@ public class BadNetworkTest URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection ssocket = server.accept(); - ssocket.upgrade(); - // Validate that we are connected future.get(30,TimeUnit.SECONDS); - wsocket.waitForConnected(30,TimeUnit.SECONDS); + wsocket.waitForConnected(); // Have client disconnect abruptly Session session = wsocket.getSession(); @@ -102,25 +103,28 @@ public class BadNetworkTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection ssocket = server.accept(); - ssocket.upgrade(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // Validate that we are connected + future.get(30, TimeUnit.SECONDS); + wsocket.waitForConnected(); - // Validate that we are connected - future.get(30,TimeUnit.SECONDS); - wsocket.waitForConnected(30,TimeUnit.SECONDS); + // Have server disconnect abruptly + serverConn.abort(); - // Have server disconnect abruptly - ssocket.disconnect(); + // Wait for close (as response to idle timeout) + wsocket.waitForClose(10, TimeUnit.SECONDS); - // Wait for close (as response to idle timeout) - 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); + // 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/ClientCloseTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java index 62da4dd5f7e..ef8072be26b 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java @@ -34,7 +34,10 @@ import java.nio.ByteBuffer; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; @@ -67,13 +70,15 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.RawFrameBuilder; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.hamcrest.Matcher; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; @@ -176,10 +181,10 @@ public class ClientCloseTest } } - private BlockheadServer server; + private static BlockheadServer server; private WebSocketClient client; - private void confirmConnection(CloseTrackingSocket clientSocket, Future clientFuture, IBlockheadServerConnection serverConns) throws Exception + private void confirmConnection(CloseTrackingSocket clientSocket, Future clientFuture, BlockheadConnection serverConns) throws Exception { // Wait for client connect on via future clientFuture.get(30,TimeUnit.SECONDS); @@ -193,10 +198,8 @@ public class ClientCloseTest final String echoMsg = "echo-test"; Future testFut = clientSocket.getRemote().sendStringByFuture(echoMsg); - serverConns.startReadThread(); - // Wait for send future - testFut.get(30,TimeUnit.SECONDS); + testFut.get(Timeouts.SEND, Timeouts.SEND_UNIT); // Read Frame on server side LinkedBlockingQueue serverCapture = serverConns.getFrameQueue(); @@ -220,7 +223,7 @@ public class ClientCloseTest } } - private void confirmServerReceivedCloseFrame(IBlockheadServerConnection serverConn, int expectedCloseCode, Matcher closeReasonMatcher) throws InterruptedException + private void confirmServerReceivedCloseFrame(BlockheadConnection serverConn, int expectedCloseCode, Matcher closeReasonMatcher) throws InterruptedException { LinkedBlockingQueue serverCapture = serverConn.getFrameQueue(); WebSocketFrame frame = serverCapture.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); @@ -282,8 +285,8 @@ public class ClientCloseTest client.start(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); @@ -295,8 +298,8 @@ public class ClientCloseTest client.stop(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -308,15 +311,15 @@ public class ClientCloseTest final int timeout = 5000; client.setMaxIdleTimeout(timeout); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CloseTrackingSocket clientSocket = new CloseTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); - serverConn.upgrade(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // client confirms connection via echo confirmConnection(clientSocket, clientConnectFuture, serverConn); @@ -348,10 +351,6 @@ public class ClientCloseTest // client close event on ws-endpoint clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.NORMAL), containsString("From Server")); } - finally - { - serverConn.disconnect(); - } } @Ignore("Need sbordet's help here") @@ -362,15 +361,15 @@ public class ClientCloseTest final int timeout = 1000; client.setMaxIdleTimeout(timeout); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CloseTrackingSocket clientSocket = new CloseTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); - serverConn.upgrade(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // client confirms connection via echo confirmConnection(clientSocket, clientConnectFuture, serverConn); @@ -402,10 +401,6 @@ public class ClientCloseTest assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); assertThat("OnError", clientSocket.error.get(), instanceOf(SocketTimeoutException.class)); } - finally - { - serverConn.disconnect(); - } } @Test @@ -415,15 +410,15 @@ public class ClientCloseTest final int timeout = 1000; client.setMaxIdleTimeout(timeout); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CloseTrackingSocket clientSocket = new CloseTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); - serverConn.upgrade(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // client confirms connection via echo confirmConnection(clientSocket, clientConnectFuture, serverConn); @@ -440,9 +435,10 @@ public class ClientCloseTest bad.putShort((short) StatusCode.NORMAL); bad.put(msg); BufferUtil.flipToFlush(bad, 0); - try (StacklessLogging quiet = new StacklessLogging(Parser.class)) + + try (StacklessLogging ignore = new StacklessLogging(Parser.class)) { - serverConn.write(bad); + serverConn.writeRaw(bad); // client should have noticed the error assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); @@ -453,11 +449,6 @@ public class ClientCloseTest confirmServerReceivedCloseFrame(serverConn, StatusCode.PROTOCOL, allOf(containsString("Invalid control frame"), containsString("length"))); } } - finally - { - // server disconnects - serverConn.disconnect(); - } // client triggers close event on client ws-endpoint clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.PROTOCOL),allOf(containsString("Invalid control frame"),containsString("length"))); @@ -470,15 +461,15 @@ public class ClientCloseTest final int timeout = 1000; client.setMaxIdleTimeout(timeout); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CloseTrackingSocket clientSocket = new CloseTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); - serverConn.upgrade(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // client confirms connection via echo confirmConnection(clientSocket, clientConnectFuture, serverConn); @@ -494,7 +485,7 @@ public class ClientCloseTest clientSocket.assertNoCloseEvent(); // server shuts down connection (no frame reply) - serverConn.disconnect(); + serverConn.abort(); // client reads -1 (EOF) // client triggers close event on client ws-endpoint @@ -504,10 +495,6 @@ public class ClientCloseTest containsString("Disconnected") )); } - finally - { - serverConn.disconnect(); - } } @Test @@ -517,15 +504,15 @@ public class ClientCloseTest final int timeout = 1000; client.setMaxIdleTimeout(timeout); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CloseTrackingSocket clientSocket = new CloseTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); - serverConn.upgrade(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // client confirms connection via echo confirmConnection(clientSocket, clientConnectFuture, serverConn); @@ -547,10 +534,6 @@ public class ClientCloseTest assertThat("OnError Latch", clientSocket.errorLatch.await(2, TimeUnit.SECONDS), is(true)); assertThat("OnError", clientSocket.error.get(), instanceOf(TimeoutException.class)); } - finally - { - serverConn.disconnect(); - } } @Test(timeout = 5000L) @@ -561,47 +544,58 @@ public class ClientCloseTest client.setMaxIdleTimeout(timeout); int clientCount = 3; - CloseTrackingSocket clientSockets[] = new CloseTrackingSocket[clientCount]; - IBlockheadServerConnection serverConns[] = new IBlockheadServerConnection[clientCount]; + List clientSockets = new ArrayList<>(); + List> serverConnFuts = new ArrayList<>(); + List serverConns = new ArrayList<>(); try { - // Connect Multiple Clients + // Open Multiple Clients for (int i = 0; i < clientCount; i++) { // Client Request Upgrade - clientSockets[i] = new CloseTrackingSocket(); - Future clientConnectFuture = client.connect(clientSockets[i], server.getWsUri()); + CloseTrackingSocket clientSocket = new CloseTrackingSocket(); + clientSockets.add(clientSocket); + Future clientConnectFuture = client.connect(clientSocket, server.getWsUri()); // Server accepts connection - serverConns[i] = server.accept(); - serverConns[i].upgrade(); + CompletableFuture serverConnFut = new CompletableFuture<>(); + serverConnFuts.add(serverConnFut); + server.addConnectFuture(serverConnFut); + BlockheadConnection serverConn = serverConnFut.get(); + serverConns.add(serverConn); // client confirms connection via echo - confirmConnection(clientSockets[i], clientConnectFuture, serverConns[i]); + confirmConnection(clientSocket, clientConnectFuture, serverConn); } - // client lifecycle stop + // client lifecycle stop (the meat of this test) client.stop(); // clients send close frames (code 1001, shutdown) for (int i = 0; i < clientCount; i++) { // server receives close frame - confirmServerReceivedCloseFrame(serverConns[i], StatusCode.SHUTDOWN, containsString("Shutdown")); + confirmServerReceivedCloseFrame(serverConns.get(i), StatusCode.SHUTDOWN, containsString("Shutdown")); } // clients disconnect for (int i = 0; i < clientCount; i++) { - clientSockets[i].assertReceivedCloseEvent(timeout, is(StatusCode.SHUTDOWN), containsString("Shutdown")); + clientSockets.get(i).assertReceivedCloseEvent(timeout, is(StatusCode.SHUTDOWN), containsString("Shutdown")); } } finally { - for(IBlockheadServerConnection serverConn: serverConns) + for(BlockheadConnection serverConn: serverConns) { - serverConn.disconnect(); + try + { + serverConn.close(); + } + catch (Exception ignore) + { + } } } } @@ -613,15 +607,15 @@ public class ClientCloseTest final int timeout = 1000; client.setMaxIdleTimeout(timeout); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CloseTrackingSocket clientSocket = new CloseTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); - serverConn.upgrade(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // client confirms connection via echo confirmConnection(clientSocket, clientConnectFuture, serverConn); @@ -643,9 +637,5 @@ public class ClientCloseTest // assert - close reason message contains (write failure) clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.ABNORMAL), containsString("EOF")); } - finally - { - serverConn.disconnect(); - } } } 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 index 5b570fb4053..f010f405be3 100644 --- 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 @@ -27,27 +27,37 @@ import static org.junit.Assert.assertThat; import java.io.IOException; import java.net.ConnectException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; import java.net.SocketTimeoutException; import java.net.URI; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.servlet.http.HttpServletResponse; + import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.common.AcceptHash; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.hamcrest.Matcher; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; /** @@ -58,8 +68,7 @@ public class ClientConnectTest { public ByteBufferPool bufferPool = new MappedByteBufferPool(); - private final int timeout = 500; - private BlockheadServer server; + private static BlockheadServer server; private WebSocketClient client; @SuppressWarnings("unchecked") @@ -88,25 +97,32 @@ public class ClientConnectTest { client = new WebSocketClient(); client.setBufferPool(bufferPool); - client.setConnectTimeout(timeout); + client.setConnectTimeout(Timeouts.CONNECT_UNIT.toMillis(Timeouts.CONNECT)); client.start(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); } + @Before + public void resetServerHandler() + { + // for each test, reset the server request handling to default + server.resetRequestHandling(); + } + @After public void stopClient() throws Exception { client.stop(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -119,12 +135,9 @@ public class ClientConnectTest URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection connection = server.accept(); - connection.upgrade(); - Session sess = future.get(30,TimeUnit.SECONDS); - wsocket.waitForConnected(1, TimeUnit.SECONDS); + wsocket.waitForConnected(); assertThat("Connect.UpgradeRequest", wsocket.connectUpgradeRequest, notNullValue()); assertThat("Connect.UpgradeResponse", wsocket.connectUpgradeResponse, notNullValue()); @@ -139,48 +152,56 @@ public class ClientConnectTest URI wsUri = server.getWsUri(); HttpClient httpClient = new HttpClient(); - httpClient.start(); - - WebSocketUpgradeRequest req = new WebSocketUpgradeRequest(new WebSocketClient(), httpClient, wsUri, wsocket); - req.header("X-Foo","Req"); - CompletableFuture sess = req.sendAsync(); + try + { + httpClient.start(); - sess.thenAccept((s) -> { - System.out.printf("Session: %s%n",s); - s.close(); - assertThat("Connect.UpgradeRequest",wsocket.connectUpgradeRequest,notNullValue()); - assertThat("Connect.UpgradeResponse",wsocket.connectUpgradeResponse,notNullValue()); - }); - - IBlockheadServerConnection connection = server.accept(); - connection.upgrade(); + WebSocketUpgradeRequest req = new WebSocketUpgradeRequest(new WebSocketClient(), httpClient, wsUri, wsocket); + req.header("X-Foo", "Req"); + CompletableFuture sess = req.sendAsync(); + + sess.thenAccept((s) -> { + System.out.printf("Session: %s%n", s); + s.close(); + assertThat("Connect.UpgradeRequest", wsocket.connectUpgradeRequest, notNullValue()); + assertThat("Connect.UpgradeResponse", wsocket.connectUpgradeResponse, notNullValue()); + }); + } + finally + { + httpClient.stop(); + } } @Test public void testUpgradeWithAuthorizationHeader() throws Exception { JettyTrackingSocket wsocket = new JettyTrackingSocket(); - + + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest(); // actual value for this test is irrelevant, its important that this // header actually be sent with a value (the value specified) upgradeRequest.setHeader("Authorization", "Bogus SHA1"); Future future = client.connect(wsocket,wsUri,upgradeRequest); - - IBlockheadServerConnection connection = server.accept(); - List requestLines = connection.upgrade(); - - Session sess = future.get(30,TimeUnit.SECONDS); - sess.close(); - String authLine = requestLines.stream() - .filter((line) -> line.startsWith("Authorization:")) - .findFirst().get(); - - assertThat("Request Container Authorization", authLine, is("Authorization: Bogus SHA1")); - assertThat("Connect.UpgradeRequest", wsocket.connectUpgradeRequest, notNullValue()); - assertThat("Connect.UpgradeResponse", wsocket.connectUpgradeResponse, notNullValue()); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + HttpFields upgradeRequestHeaders = serverConn.getUpgradeRequestHeaders(); + + Session sess = future.get(30, TimeUnit.SECONDS); + sess.close(); + + HttpField authHeader = upgradeRequestHeaders.getField(HttpHeader.AUTHORIZATION); + assertThat("Server Request Authorization Header", authHeader, is(notNullValue())); + assertThat("Server Request Authorization Value", authHeader.getValue(), is("Authorization: Bogus SHA1")); + assertThat("Connect.UpgradeRequest", wsocket.connectUpgradeRequest, notNullValue()); + assertThat("Connect.UpgradeResponse", wsocket.connectUpgradeResponse, notNullValue()); + } } @Test @@ -188,16 +209,15 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + // Force 404 response, no upgrade for this test + server.setRequestHandling((req, resp) -> { + resp.setStatus(HttpServletResponse.SC_NOT_FOUND); + return true; + }); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection connection = server.accept(); - connection.readRequest(); - // no upgrade, just fail with a 404 error - connection.respond("HTTP/1.1 404 NOT FOUND\r\n" + - "Content-Length: 0\r\n" + - "\r\n"); - // The attempt to get upgrade response future should throw error try { @@ -219,16 +239,15 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + // Force 200 response, no response body content, no upgrade for this test + server.setRequestHandling((req, resp) -> { + resp.setStatus(HttpServletResponse.SC_OK); + return true; + }); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection connection = server.accept(); - connection.readRequest(); - // Send OK to GET but not upgrade - connection.respond("HTTP/1.1 200 OK\r\n" + - "Content-Length: 0\r\n" + - "\r\n"); - // The attempt to get upgrade response future should throw error try { @@ -250,22 +269,17 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + // Force 200 response, no response body content, incomplete websocket response headers, no actual upgrade for this test + server.setRequestHandling((req, resp) -> { + String key = req.getHeader(HttpHeader.SEC_WEBSOCKET_KEY.toString()); + resp.setStatus(HttpServletResponse.SC_OK); + resp.setHeader(HttpHeader.SEC_WEBSOCKET_ACCEPT.toString(), AcceptHash.hashKey(key)); + return true; + }); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection connection = server.accept(); - List requestLines = connection.readRequestLines(); - String key = connection.parseWebSocketKey(requestLines); - - // Send OK to GET but not upgrade - StringBuilder resp = new StringBuilder(); - resp.append("HTTP/1.1 200 OK\r\n"); // intentionally 200 (not 101) - // Include a value accept key - resp.append("Sec-WebSocket-Accept: ").append(AcceptHash.hashKey(key)).append("\r\n"); - resp.append("Content-Length: 0\r\n"); - resp.append("\r\n"); - connection.respond(resp.toString()); - // The attempt to get upgrade response future should throw error try { @@ -287,21 +301,18 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + // Force 101 response, with invalid Connection header, invalid handshake + server.setRequestHandling((req, resp) -> { + String key = req.getHeader(HttpHeader.SEC_WEBSOCKET_KEY.toString()); + resp.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + resp.setHeader(HttpHeader.CONNECTION.toString(), "close"); + resp.setHeader(HttpHeader.SEC_WEBSOCKET_ACCEPT.toString(), AcceptHash.hashKey(key)); + return true; + }); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection connection = server.accept(); - List requestLines = connection.readRequestLines(); - String key = connection.parseWebSocketKey(requestLines); - - // Send Switching Protocols 101, but invalid 'Connection' header - StringBuilder resp = new StringBuilder(); - resp.append("HTTP/1.1 101 Switching Protocols\r\n"); - resp.append("Sec-WebSocket-Accept: ").append(AcceptHash.hashKey(key)).append("\r\n"); - resp.append("Connection: close\r\n"); - resp.append("\r\n"); - connection.respond(resp.toString()); - // The attempt to get upgrade response future should throw error try { @@ -323,21 +334,18 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + // Force 101 response, with no Connection header, invalid handshake + server.setRequestHandling((req, resp) -> { + String key = req.getHeader(HttpHeader.SEC_WEBSOCKET_KEY.toString()); + resp.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + // Intentionally leave out Connection header + resp.setHeader(HttpHeader.SEC_WEBSOCKET_ACCEPT.toString(), AcceptHash.hashKey(key)); + return true; + }); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection connection = server.accept(); - List requestLines = connection.readRequestLines(); - String key = connection.parseWebSocketKey(requestLines); - - // Send Switching Protocols 101, but no 'Connection' header - StringBuilder resp = new StringBuilder(); - resp.append("HTTP/1.1 101 Switching Protocols\r\n"); - resp.append("Sec-WebSocket-Accept: ").append(AcceptHash.hashKey(key)).append("\r\n"); - // Intentionally leave out Connection header - resp.append("\r\n"); - connection.respond(resp.toString()); - // The attempt to get upgrade response future should throw error try { @@ -359,14 +367,16 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); + // Force 101 response, with invalid response accept header + server.setRequestHandling((req, resp) -> { + resp.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + resp.setHeader(HttpHeader.SEC_WEBSOCKET_ACCEPT.toString(), "rubbish"); + return true; + }); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection 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 { @@ -388,27 +398,34 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); - URI wsUri = server.getWsUri(); - Future future = client.connect(wsocket,wsUri); + try(ServerSocket serverSocket = new ServerSocket()) + { + InetAddress addr = InetAddress.getByName("localhost"); + InetSocketAddress endpoint = new InetSocketAddress(addr, 0); + serverSocket.bind(endpoint, 1); + int port = serverSocket.getLocalPort(); + URI wsUri = URI.create(String.format("ws://%s:%d/", addr.getHostAddress(), port)); + Future future = client.connect(wsocket, wsUri); - // Intentionally not accept incoming socket. - // server.accept(); + // Intentionally not accept incoming socket. + // serverSocket.accept(); - try - { - future.get(3,TimeUnit.SECONDS); - Assert.fail("Should have Timed Out"); - } - catch (ExecutionException e) - { - assertExpectedError(e,wsocket,instanceOf(UpgradeException.class)); - // Possible Passing Path (active session wait timeout) - wsocket.assertNotOpened(); - } - catch (TimeoutException e) - { - // Possible Passing Path (concurrency timeout) - wsocket.assertNotOpened(); + try + { + future.get(3, TimeUnit.SECONDS); + Assert.fail("Should have Timed Out"); + } + catch (ExecutionException e) + { + assertExpectedError(e, wsocket, instanceOf(UpgradeException.class)); + // Possible Passing Path (active session wait timeout) + wsocket.assertNotOpened(); + } + catch (TimeoutException e) + { + // Possible Passing Path (concurrency timeout) + wsocket.assertNotOpened(); + } } } @@ -449,24 +466,29 @@ public class ClientConnectTest { JettyTrackingSocket wsocket = new JettyTrackingSocket(); - URI wsUri = server.getWsUri(); - Future future = client.connect(wsocket,wsUri); - - IBlockheadServerConnection ssocket = server.accept(); - Assert.assertNotNull(ssocket); - // Intentionally don't upgrade - // ssocket.upgrade(); - - // The attempt to get upgrade response future should throw error - try + try(ServerSocket serverSocket = new ServerSocket()) { - future.get(3,TimeUnit.SECONDS); - Assert.fail("Expected ExecutionException -> TimeoutException"); - } - catch (ExecutionException e) - { - // Expected path - java.net.ConnectException ? - assertExpectedError(e,wsocket,instanceOf(ConnectException.class)); + InetAddress addr = InetAddress.getByName("localhost"); + InetSocketAddress endpoint = new InetSocketAddress(addr, 0); + serverSocket.bind(endpoint, 1); + int port = serverSocket.getLocalPort(); + URI wsUri = URI.create(String.format("ws://%s:%d/", addr.getHostAddress(), port)); + Future future = client.connect(wsocket, wsUri); + + // Accept the connection, but do nothing on it (no response, no upgrade, etc) + serverSocket.accept(); + + // The attempt to get upgrade response future should throw error + try + { + future.get(3, TimeUnit.SECONDS); + Assert.fail("Expected ExecutionException -> TimeoutException"); + } + catch (ExecutionException e) + { + // Expected path - java.net.ConnectException ? + assertExpectedError(e, wsocket, instanceOf(ConnectException.class)); + } } } } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java index 18f827598d0..59da9370884 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/CookieTest.java @@ -25,25 +25,30 @@ import static org.junit.Assert.assertTrue; import java.net.CookieManager; import java.net.HttpCookie; import java.util.Collections; -import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketAdapter; -import org.eclipse.jetty.websocket.api.util.QuoteUtil; +import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.frames.TextFrame; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public class CookieTest @@ -83,8 +88,8 @@ public class CookieTest } } + private static BlockheadServer server; private WebSocketClient client; - private BlockheadServer server; @Before public void startClient() throws Exception @@ -93,8 +98,8 @@ public class CookieTest client.start(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); @@ -109,8 +114,8 @@ public class CookieTest } } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -132,18 +137,22 @@ public class CookieTest cookie.setMaxAge(100000); cookieMgr.getCookieStore().add(server.getWsUri(),cookie); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CookieTrackingSocket clientSocket = new CookieTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri()); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // client confirms upgrade and receipt of frame + String serverCookies = confirmClientUpgradeAndCookies(clientSocket, clientConnectFuture, serverConn); - // client confirms upgrade and receipt of frame - String serverCookies = confirmClientUpgradeAndCookies(clientSocket,clientConnectFuture,serverConn); - - assertThat("Cookies seen at server side",serverCookies,containsString("hello=world")); - assertThat("Cookies seen at server side",serverCookies,containsString("foo=bar is the word")); + assertThat("Cookies seen at server side", serverCookies, containsString("hello=world")); + assertThat("Cookies seen at server side", serverCookies, containsString("foo=bar is the word")); + } } @Test @@ -157,32 +166,35 @@ public class CookieTest ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setCookies(Collections.singletonList(cookie)); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Client connects CookieTrackingSocket clientSocket = new CookieTrackingSocket(); Future clientConnectFuture = client.connect(clientSocket,server.getWsUri(),request); - // Server accepts connect - IBlockheadServerConnection serverConn = server.accept(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // client confirms upgrade and receipt of frame + String serverCookies = confirmClientUpgradeAndCookies(clientSocket, clientConnectFuture, serverConn); - // client confirms upgrade and receipt of frame - String serverCookies = confirmClientUpgradeAndCookies(clientSocket,clientConnectFuture,serverConn); - - Assert.assertThat("Cookies seen at server side",serverCookies,containsString("hello=world")); + Assert.assertThat("Cookies seen at server side", serverCookies, containsString("hello=world")); + } } - private String confirmClientUpgradeAndCookies(CookieTrackingSocket clientSocket, Future clientConnectFuture, IBlockheadServerConnection serverConn) + private String confirmClientUpgradeAndCookies(CookieTrackingSocket clientSocket, Future clientConnectFuture, BlockheadConnection serverConn) throws Exception { - // Server upgrades - List upgradeRequestLines = serverConn.upgrade(); - List upgradeRequestCookies = serverConn.regexFind(upgradeRequestLines,"^Cookie: (.*)$"); + // Server side upgrade information + HttpFields upgradeRequestHeaders = serverConn.getUpgradeRequestHeaders(); + HttpField cookieField = upgradeRequestHeaders.getField(HttpHeader.COOKIE); // Server responds with cookies it knows about TextFrame serverCookieFrame = new TextFrame(); serverCookieFrame.setFin(true); - serverCookieFrame.setPayload(QuoteUtil.join(upgradeRequestCookies,",")); + serverCookieFrame.setPayload(cookieField.getValue()); serverConn.write(serverCookieFrame); - serverConn.flush(); // Confirm client connect on future clientConnectFuture.get(10,TimeUnit.SECONDS); @@ -193,7 +205,7 @@ public class CookieTest LOG.debug("Cookies seen at server: {}",cookies); // Server closes connection - serverConn.close(StatusCode.NORMAL); + serverConn.write(new CloseInfo(StatusCode.NORMAL).asFrame()); return cookies; } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java index 7a2162c1ee1..28bdc82072c 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/JettyTrackingSocket.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.api.WebSocketAdapter; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.Assert; /** @@ -159,9 +160,9 @@ public class JettyTrackingSocket extends WebSocketAdapter Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true)); } - public void waitForConnected(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException + public void waitForConnected() throws InterruptedException { - Assert.assertThat("Client Socket Connected",openLatch.await(timeoutDuration,timeoutUnit),is(true)); + Assert.assertThat("Client Socket Connected",openLatch.await(Timeouts.CONNECT,Timeouts.CONNECT_UNIT),is(true)); } public void waitForMessage(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException 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 deleted file mode 100644 index 82a3e3cbb70..00000000000 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerReadThread.java +++ /dev/null @@ -1,133 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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 static org.hamcrest.Matchers.is; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; -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.common.CloseInfo; -import org.eclipse.jetty.websocket.common.OpCode; -import org.eclipse.jetty.websocket.common.WebSocketFrame; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; -import org.eclipse.jetty.websocket.common.test.Timeouts; -import org.junit.Assert; - -public class ServerReadThread extends Thread -{ - private static final int BUFFER_SIZE = 8192; - private static final Logger LOG = Log.getLogger(ServerReadThread.class); - private final IBlockheadServerConnection conn; - private boolean active = true; - private int slowness = -1; // disabled is default - private final AtomicInteger frameCount = new AtomicInteger(); - private final CountDownLatch expectedMessageCount; - - public ServerReadThread(IBlockheadServerConnection sconnection, int expectedMessages) - { - this.conn = sconnection; - this.expectedMessageCount = new CountDownLatch(expectedMessages); - } - - public void cancel() - { - active = false; - } - - public int getFrameCount() - { - return frameCount.get(); - } - - public int getSlowness() - { - return slowness; - } - - @Override - public void run() - { - ByteBufferPool bufferPool = conn.getBufferPool(); - ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE,false); - BufferUtil.clearToFill(buf); - - try - { - while (active) - { - BufferUtil.clearToFill(buf); - int len = conn.read(buf); - - if (len > 0) - { - LOG.debug("Read {} bytes",len); - BufferUtil.flipToFlush(buf,0); - conn.getParser().parse(buf); - } - - LinkedBlockingQueue frames = conn.getFrameQueue(); - WebSocketFrame frame; - while ((frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT)) != 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(getSlowness()); - } - } - } - catch (IOException | InterruptedException e) - { - LOG.warn(e); - } - finally - { - bufferPool.release(buf); - } - } - - 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 index 76deb81b2bd..80fd5fb510b 100644 --- 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 @@ -18,24 +18,23 @@ package org.eclipse.jetty.websocket.client; -import java.io.IOException; 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.common.frames.TextFrame; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; public class ServerWriteThread extends Thread { private static final Logger LOG = Log.getLogger(ServerWriteThread.class); - private final IBlockheadServerConnection conn; + private final BlockheadConnection conn; private int slowness = -1; private int messageCount = 100; private String message = "Hello"; - public ServerWriteThread(IBlockheadServerConnection conn) + public ServerWriteThread(BlockheadConnection conn) { this.conn = conn; } @@ -74,7 +73,7 @@ public class ServerWriteThread extends Thread } } } - catch (InterruptedException | IOException e) + catch (InterruptedException e) { LOG.warn(e); } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java index ea6eef03f9c..a6c229482a0 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SessionTest.java @@ -26,35 +26,37 @@ import static org.junit.Assert.assertThat; import java.net.URI; import java.util.Collection; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; -import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; -import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class SessionTest { - private BlockheadServer server; + private static BlockheadServer server; - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -69,6 +71,10 @@ public class SessionTest { JettyTrackingSocket cliSock = new JettyTrackingSocket(); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + client.getPolicy().setIdleTimeout(10000); URI wsUri = server.getWsUri(); @@ -76,31 +82,33 @@ public class SessionTest request.setSubProtocols("echo"); Future future = client.connect(cliSock,wsUri,request); - final IBlockheadServerConnection srvSock = server.accept(); - srvSock.upgrade(); - Session sess = future.get(30000, TimeUnit.MILLISECONDS); - Assert.assertThat("Session", sess, notNullValue()); - Assert.assertThat("Session.open", sess.isOpen(), is(true)); - Assert.assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); - Assert.assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); - - cliSock.assertWasOpened(); - cliSock.assertNotClosed(); - - Collection sessions = client.getBeans(WebSocketSession.class); - Assert.assertThat("client.connectionManager.sessions.size", sessions.size(), is(1)); - - RemoteEndpoint remote = cliSock.getSession().getRemote(); - remote.sendStringByFuture("Hello World!"); - if (remote.getBatchMode() == BatchMode.ON) + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - remote.flush(); - } + // Setup echo of frames on server side + serverConn.setIncomingFrameConsumer((frame)->{ + WebSocketFrame copy = WebSocketFrame.copy(frame); + serverConn.write(copy); + }); + + Session sess = future.get(30000, TimeUnit.MILLISECONDS); + Assert.assertThat("Session", sess, notNullValue()); + Assert.assertThat("Session.open", sess.isOpen(), is(true)); + Assert.assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); + Assert.assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); + + cliSock.assertWasOpened(); + cliSock.assertNotClosed(); + + Collection sessions = client.getBeans(WebSocketSession.class); + Assert.assertThat("client.connectionManager.sessions.size", sessions.size(), is(1)); + + RemoteEndpoint remote = cliSock.getSession().getRemote(); + remote.sendStringByFuture("Hello World!"); + if (remote.getBatchMode() == BatchMode.ON) + { + remote.flush(); + } - try - { - srvSock.enableIncomingEcho(true); - srvSock.startReadThread(); // wait for response from server cliSock.waitForMessage(30000, TimeUnit.MILLISECONDS); @@ -111,11 +119,6 @@ public class SessionTest assertThat("Message", received, containsString("Hello World!")); cliSock.close(); - srvSock.close(); - } - finally - { - srvSock.disconnect(); } cliSock.waitForClose(30000, TimeUnit.MILLISECONDS); 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 index d727c44b176..58f26b225ee 100644 --- 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 @@ -19,23 +19,32 @@ package org.eclipse.jetty.websocket.client; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; import java.net.URI; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.common.CloseInfo; +import org.eclipse.jetty.websocket.common.OpCode; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public class SlowClientTest { - private BlockheadServer server; + private static BlockheadServer server; private WebSocketClient client; @Before @@ -46,8 +55,8 @@ public class SlowClientTest client.start(); } - @Before - public void startServer() throws Exception + @BeforeClass + public static void startServer() throws Exception { server = new BlockheadServer(); server.start(); @@ -59,8 +68,8 @@ public class SlowClientTest client.stop(); } - @After - public void stopServer() throws Exception + @AfterClass + public static void stopServer() throws Exception { server.stop(); } @@ -74,39 +83,50 @@ public class SlowClientTest URI wsUri = server.getWsUri(); Future future = client.connect(tsocket, wsUri); - IBlockheadServerConnection sconnection = server.accept(); - sconnection.setSoTimeout(60000); - sconnection.upgrade(); + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); // Confirm connected - future.get(30,TimeUnit.SECONDS); - tsocket.waitForConnected(30,TimeUnit.SECONDS); + future.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + tsocket.waitForConnected(); int messageCount = 10; - // Setup server read thread - ServerReadThread reader = new ServerReadThread(sconnection, messageCount); - reader.start(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // Have client write slowly. + ClientWriteThread writer = new ClientWriteThread(tsocket.getSession()); + writer.setMessageCount(messageCount); + writer.setMessage("Hello"); + writer.setSlowness(10); + writer.start(); + writer.join(); - // Have client write slowly. - ClientWriteThread writer = new ClientWriteThread(tsocket.getSession()); - writer.setMessageCount(messageCount); - writer.setMessage("Hello"); - writer.setSlowness(10); - writer.start(); - writer.join(); + LinkedBlockingQueue serverFrames = serverConn.getFrameQueue(); - reader.waitForExpectedMessageCount(1, TimeUnit.MINUTES); + for (int i = 0; i < messageCount; i++) + { + WebSocketFrame serverFrame = serverFrames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + String prefix = "Server frame[" + i + "]"; + assertThat(prefix + ".opcode", serverFrame.getOpCode(), is(OpCode.TEXT)); + assertThat(prefix + ".payload", serverFrame.getPayloadAsUTF8(), is("Hello/" + i + "/")); + } - // Verify receive - Assert.assertThat("Frame Receive Count", reader.getFrameCount(), is(messageCount)); + // Close + tsocket.getSession().close(StatusCode.NORMAL, "Done"); - // Close - tsocket.getSession().close(StatusCode.NORMAL, "Done"); + // confirm close received on server + WebSocketFrame serverFrame = serverFrames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("close frame", serverFrame.getOpCode(), is(OpCode.CLOSE)); + CloseInfo closeInfo = new CloseInfo(serverFrame); + assertThat("close info", closeInfo.getStatusCode(), is(StatusCode.NORMAL)); + WebSocketFrame respClose = WebSocketFrame.copy(serverFrame); + respClose.setMask(null); // remove client mask (if present) + serverConn.write(respClose); - Assert.assertTrue("Client Socket Closed", tsocket.closeLatch.await(3, TimeUnit.MINUTES)); - tsocket.assertCloseCode(StatusCode.NORMAL); - - reader.cancel(); // stop reading + // Verify server response + Assert.assertTrue("Client Socket Closed", tsocket.closeLatch.await(3, TimeUnit.MINUTES)); + tsocket.assertCloseCode(StatusCode.NORMAL); + } } } 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 index 09050221515..a20ce355200 100644 --- 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 @@ -19,16 +19,22 @@ package org.eclipse.jetty.websocket.client; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import java.net.URI; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.client.masks.ZeroMasker; +import org.eclipse.jetty.websocket.common.OpCode; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -73,80 +79,93 @@ public class SlowServerTest client.setMasker(new ZeroMasker()); client.setMaxIdleTimeout(60000); + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); Future future = client.connect(tsocket,wsUri); - IBlockheadServerConnection sconnection = server.accept(); - sconnection.setSoTimeout(60000); - sconnection.upgrade(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // slow down reads + serverConn.setIncomingFrameConsumer((frame)-> { + try + { + TimeUnit.MILLISECONDS.sleep(100); + } + catch (InterruptedException ignore) + { + } + }); - // Confirm connected - future.get(30,TimeUnit.SECONDS); - tsocket.waitForConnected(30,TimeUnit.SECONDS); + // Confirm connected + future.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + tsocket.waitForConnected(); - int messageCount = 10; + int messageCount = 10; - // Setup slow server read thread - ServerReadThread reader = new ServerReadThread(sconnection, messageCount); - reader.setSlowness(100); // slow it down - reader.start(); + // Have client write as quickly as it can. + ClientWriteThread writer = new ClientWriteThread(tsocket.getSession()); + writer.setMessageCount(messageCount); + writer.setMessage("Hello"); + writer.setSlowness(-1); // disable slowness + writer.start(); + writer.join(); - // Have client write as quickly as it can. - ClientWriteThread writer = new ClientWriteThread(tsocket.getSession()); - writer.setMessageCount(messageCount); - writer.setMessage("Hello"); - writer.setSlowness(-1); // disable slowness - writer.start(); - writer.join(); + // Verify receive + LinkedBlockingQueue serverFrames = serverConn.getFrameQueue(); + for(int i=0; i< messageCount; i++) + { + WebSocketFrame serverFrame = serverFrames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + String prefix = "Server Frame[" + i + "]"; + Assert.assertThat(prefix, serverFrame, is(notNullValue())); + Assert.assertThat(prefix + ".opCode", serverFrame.getOpCode(), is(OpCode.TEXT)); + Assert.assertThat(prefix + ".payload", serverFrame.getPayloadAsUTF8(), is("Hello")); + } - // Verify receive - reader.waitForExpectedMessageCount(10,TimeUnit.SECONDS); - Assert.assertThat("Frame Receive Count",reader.getFrameCount(),is(messageCount)); + // Close + tsocket.getSession().close(StatusCode.NORMAL, "Done"); - // Close - tsocket.getSession().close(StatusCode.NORMAL,"Done"); - - Assert.assertTrue("Client Socket Closed",tsocket.closeLatch.await(10,TimeUnit.SECONDS)); - tsocket.assertCloseCode(StatusCode.NORMAL); - - reader.cancel(); // stop reading + Assert.assertTrue("Client Socket Closed", tsocket.closeLatch.await(10, TimeUnit.SECONDS)); + tsocket.assertCloseCode(StatusCode.NORMAL); + } } @Test public void testServerSlowToSend() throws Exception { JettyTrackingSocket clientSocket = new JettyTrackingSocket(); - client.setMasker(new ZeroMasker()); client.setMaxIdleTimeout(60000); + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); Future clientConnectFuture = client.connect(clientSocket,wsUri); - IBlockheadServerConnection serverConn = server.accept(); - serverConn.setSoTimeout(60000); - serverConn.upgrade(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // Confirm connected + clientConnectFuture.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + clientSocket.waitForConnected(); - // Confirm connected - clientConnectFuture.get(30,TimeUnit.SECONDS); - clientSocket.waitForConnected(30,TimeUnit.SECONDS); + // Have server write slowly. + int messageCount = 1000; - // Have server write slowly. - int messageCount = 1000; + ServerWriteThread writer = new ServerWriteThread(serverConn); + writer.setMessageCount(messageCount); + writer.setMessage("Hello"); + writer.setSlowness(10); + writer.start(); + writer.join(); - ServerWriteThread writer = new ServerWriteThread(serverConn); - writer.setMessageCount(messageCount); - writer.setMessage("Hello"); - writer.setSlowness(10); - writer.start(); - writer.join(); + // Verify receive + Assert.assertThat("Message Receive Count", clientSocket.messageQueue.size(), is(messageCount)); - // Verify receive - Assert.assertThat("Message Receive Count",clientSocket.messageQueue.size(),is(messageCount)); + // Close server connection (by exiting try-with-resources) + } - // Close - serverConn.close(StatusCode.NORMAL); - - Assert.assertTrue("Client Socket Closed",clientSocket.closeLatch.await(10,TimeUnit.SECONDS)); + Assert.assertTrue("Client Socket Closed", clientSocket.closeLatch.await(10, TimeUnit.SECONDS)); clientSocket.assertCloseCode(StatusCode.NORMAL); } } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java index 08e878ef32e..4a91c18e7cc 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java @@ -21,15 +21,19 @@ package org.eclipse.jetty.websocket.client; import java.net.URI; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; +import org.junit.AfterClass; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; public class TomcatServerQuirksTest @@ -59,6 +63,21 @@ public class TomcatServerQuirksTest } } + private static BlockheadServer server; + + @BeforeClass + public static void startServer() throws Exception + { + server = new BlockheadServer(); + server.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + server.stop(); + } + /** * Test for when encountering a "Transfer-Encoding: chunked" on a Upgrade Response header. *
    @@ -71,57 +90,55 @@ public class TomcatServerQuirksTest @Test public void testTomcat7_0_32_WithTransferEncoding() throws Exception { - BlockheadServer server = new BlockheadServer(); WebSocketClient client = new WebSocketClient(); + server.setRequestHandling((req, resp) -> { + // Add the extra problematic header that triggers bug found in jetty-io + resp.setHeader("Transfer-Encoding", "chunked"); + return true; + }); + try { final int bufferSize = 512; - server.start(); - // Setup Client Factory client.start(); // Create End User WebSocket Class LatchedSocket websocket = new LatchedSocket(); + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + // Open connection URI wsURI = server.getWsUri(); client.connect(websocket,wsURI); - // Accept incoming connection - IBlockheadServerConnection socket = server.accept(); - socket.setSoTimeout(2000); // timeout - - // Issue upgrade - // Add the extra problematic header that triggers bug found in jetty-io - socket.addResponseHeader("Transfer-Encoding","chunked"); - socket.upgrade(); - // Wait for proper upgrade Assert.assertTrue("Timed out waiting for Client side WebSocket open event",websocket.openLatch.await(1,TimeUnit.SECONDS)); - // Have server write frame. - byte payload[] = new byte[bufferSize / 2]; - Arrays.fill(payload,(byte)'x'); - ByteBuffer serverFrame = BufferUtil.allocate(bufferSize); - BufferUtil.flipToFill(serverFrame); - serverFrame.put((byte)(0x80 | 0x01)); // FIN + TEXT - serverFrame.put((byte)0x7E); // No MASK and 2 bytes length - serverFrame.put((byte)(payload.length >> 8)); // first length byte - serverFrame.put((byte)(payload.length & 0xFF)); // second length byte - serverFrame.put(payload); - BufferUtil.flipToFlush(serverFrame,0); - socket.write(serverFrame); - socket.flush(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // Have server write frame. + byte payload[] = new byte[bufferSize / 2]; + Arrays.fill(payload, (byte) 'x'); + ByteBuffer serverFrame = BufferUtil.allocate(bufferSize); + BufferUtil.flipToFill(serverFrame); + serverFrame.put((byte) (0x80 | 0x01)); // FIN + TEXT + serverFrame.put((byte) 0x7E); // No MASK and 2 bytes length + serverFrame.put((byte) (payload.length >> 8)); // first length byte + serverFrame.put((byte) (payload.length & 0xFF)); // second length byte + serverFrame.put(payload); + BufferUtil.flipToFlush(serverFrame, 0); + serverConn.writeRaw(serverFrame); + } Assert.assertTrue(websocket.dataLatch.await(1000,TimeUnit.SECONDS)); } finally { client.stop(); - server.stop(); } } } 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 b22e3646d93..7b741145e56 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 @@ -31,6 +31,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -39,35 +40,48 @@ import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeRequest; +import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.FutureWriteCallback; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.BlockheadServer; -import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public class WebSocketClientTest { - private BlockheadServer server; + private static BlockheadServer server; private WebSocketClient client; @Before - public void startClientServer() throws Exception + public void startClient() throws Exception { client = new WebSocketClient(); client.start(); + } + + @BeforeClass + public static void startServer() throws Exception + { server = new BlockheadServer(); server.start(); } @After - public void stopClientServer() throws Exception + public void stopClient() throws Exception { client.stop(); + } + + @AfterClass + public void stopServer() throws Exception + { server.stop(); } @@ -94,45 +108,44 @@ public class WebSocketClientTest client.getPolicy().setIdleTimeout(10000); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setSubProtocols("echo"); Future future = client.connect(cliSock,wsUri,request); - final IBlockheadServerConnection srvSock = server.accept(); - srvSock.upgrade(); - - Session sess = future.get(30,TimeUnit.SECONDS); - assertThat("Session",sess,notNullValue()); - assertThat("Session.open",sess.isOpen(),is(true)); - assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); - - cliSock.assertWasOpened(); - cliSock.assertNotClosed(); - - Collection sessions = client.getOpenSessions(); - assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); - - RemoteEndpoint remote = cliSock.getSession().getRemote(); - remote.sendStringByFuture("Hello World!"); - if (remote.getBatchMode() == BatchMode.ON) - remote.flush(); - - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - srvSock.enableIncomingEcho(true); - srvSock.startReadThread(); + // Setup echo of frames on server side + serverConn.setIncomingFrameConsumer((frame)->{ + WebSocketFrame copy = WebSocketFrame.copy(frame); + serverConn.write(copy); + }); + + Session sess = future.get(30,TimeUnit.SECONDS); + assertThat("Session",sess,notNullValue()); + assertThat("Session.open",sess.isOpen(),is(true)); + assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); + assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + + cliSock.assertWasOpened(); + cliSock.assertNotClosed(); + + Collection sessions = client.getOpenSessions(); + assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); + + RemoteEndpoint remote = cliSock.getSession().getRemote(); + remote.sendStringByFuture("Hello World!"); + if (remote.getBatchMode() == BatchMode.ON) + remote.flush(); // wait for response from server String received = cliSock.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("Message", received, containsString("Hello World")); } - finally - { - srvSock.close(); - srvSock.disconnect(); - } } @Test @@ -141,58 +154,65 @@ public class WebSocketClientTest client.setMaxIdleTimeout(160000); JettyTrackingSocket cliSock = new JettyTrackingSocket(); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setSubProtocols("echo"); Future future = client.connect(cliSock,wsUri,request); - final IBlockheadServerConnection srvSock = server.accept(); - srvSock.upgrade(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + Session sess = future.get(30, TimeUnit.SECONDS); + assertThat("Session", sess, notNullValue()); + assertThat("Session.open", sess.isOpen(), is(true)); + assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); + assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); - Session sess = future.get(30,TimeUnit.SECONDS); - assertThat("Session",sess,notNullValue()); - assertThat("Session.open",sess.isOpen(),is(true)); - assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + cliSock.assertWasOpened(); + cliSock.assertNotClosed(); - cliSock.assertWasOpened(); - cliSock.assertNotClosed(); + Collection sessions = client.getBeans(WebSocketSession.class); + assertThat("client.connectionManager.sessions.size", sessions.size(), is(1)); - Collection sessions = client.getBeans(WebSocketSession.class); - assertThat("client.connectionManager.sessions.size",sessions.size(),is(1)); + FutureWriteCallback callback = new FutureWriteCallback(); - FutureWriteCallback callback = new FutureWriteCallback(); - - cliSock.getSession().getRemote().sendString("Hello World!",callback); - callback.get(1,TimeUnit.SECONDS); + cliSock.getSession().getRemote().sendString("Hello World!", callback); + callback.get(1, TimeUnit.SECONDS); + } } @Test public void testBasicEcho_FromServer() throws Exception { + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + JettyTrackingSocket wsocket = new JettyTrackingSocket(); Future future = client.connect(wsocket,server.getWsUri()); - // Server - final IBlockheadServerConnection srvSock = server.accept(); - srvSock.upgrade(); + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + // Validate connect + Session sess = future.get(30, TimeUnit.SECONDS); + assertThat("Session", sess, notNullValue()); + assertThat("Session.open", sess.isOpen(), is(true)); + assertThat("Session.upgradeRequest", sess.getUpgradeRequest(), notNullValue()); + assertThat("Session.upgradeResponse", sess.getUpgradeResponse(), notNullValue()); - // Validate connect - Session sess = future.get(30,TimeUnit.SECONDS); - assertThat("Session",sess,notNullValue()); - assertThat("Session.open",sess.isOpen(),is(true)); - assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue()); - assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue()); + // Have server send initial message + serverConn.write(new TextFrame().setPayload("Hello World")); - // Have server send initial message - srvSock.write(new TextFrame().setPayload("Hello World")); + // Verify connect + future.get(30, TimeUnit.SECONDS); + wsocket.assertWasOpened(); - // Verify connect - future.get(30,TimeUnit.SECONDS); - wsocket.assertWasOpened(); - - String received = wsocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - assertThat("Message", received, containsString("Hello World")); + String received = wsocket.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("Message", received, containsString("Hello World")); + } } @Test @@ -203,9 +223,6 @@ public class WebSocketClientTest URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection ssocket = server.accept(); - ssocket.upgrade(); - future.get(30,TimeUnit.SECONDS); Assert.assertTrue(wsocket.openLatch.await(1,TimeUnit.SECONDS)); @@ -224,37 +241,6 @@ public class WebSocketClientTest assertThat("Remote Socket Address / Port",remote.getPort(),greaterThan(0)); } - @Test - public void testMessageBiggerThanBufferSize() throws Exception - { - int bufferSize = 512; - - JettyTrackingSocket wsocket = new JettyTrackingSocket(); - - URI wsUri = server.getWsUri(); - Future future = client.connect(wsocket,wsUri); - - IBlockheadServerConnection ssocket = server.accept(); - ssocket.upgrade(); - - future.get(30,TimeUnit.SECONDS); - - Assert.assertTrue(wsocket.openLatch.await(1,TimeUnit.SECONDS)); - - int length = bufferSize + (bufferSize / 2); // 1.5 times buffer size - ssocket.write(0x80 | 0x01); // FIN + TEXT - ssocket.write(0x7E); // No MASK and 2 bytes length - ssocket.write(length >> 8); // first length byte - ssocket.write(length & 0xFF); // second length byte - for (int i = 0; i < length; ++i) - { - ssocket.write('x'); - } - ssocket.flush(); - - Assert.assertTrue(wsocket.dataLatch.await(1000,TimeUnit.SECONDS)); - } - /** * Ensure that @WebSocket(maxTextMessageSize = 100*1024) behaves as expected. * @@ -266,29 +252,34 @@ public class WebSocketClientTest { MaxMessageSocket wsocket = new MaxMessageSocket(); + // Hook into server connection creation + CompletableFuture serverConnFut = new CompletableFuture<>(); + server.addConnectFuture(serverConnFut); + URI wsUri = server.getWsUri(); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection ssocket = server.accept(); - ssocket.upgrade(); - - wsocket.awaitConnect(1,TimeUnit.SECONDS); - - Session sess = future.get(30,TimeUnit.SECONDS); - assertThat("Session",sess,notNullValue()); - assertThat("Session.open",sess.isOpen(),is(true)); - - // Create string that is larger than default size of 64k - // but smaller than maxMessageSize of 100k - byte buf[] = new byte[80 * 1024]; - Arrays.fill(buf,(byte)'x'); - String msg = StringUtil.toUTF8String(buf,0,buf.length); - - wsocket.getSession().getRemote().sendStringByFuture(msg); - try + try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - ssocket.enableIncomingEcho(true); - ssocket.startReadThread(); + // Setup echo of frames on server side + serverConn.setIncomingFrameConsumer((frame)->{ + WebSocketFrame copy = WebSocketFrame.copy(frame); + serverConn.write(copy); + }); + + wsocket.awaitConnect(1,TimeUnit.SECONDS); + + Session sess = future.get(30,TimeUnit.SECONDS); + assertThat("Session",sess,notNullValue()); + assertThat("Session.open",sess.isOpen(),is(true)); + + // Create string that is larger than default size of 64k + // but smaller than maxMessageSize of 100k + byte buf[] = new byte[80 * 1024]; + Arrays.fill(buf,(byte)'x'); + String msg = StringUtil.toUTF8String(buf,0,buf.length); + + wsocket.getSession().getRemote().sendStringByFuture(msg); // wait for response from server wsocket.waitForMessage(1, TimeUnit.SECONDS); @@ -297,11 +288,6 @@ public class WebSocketClientTest Assert.assertTrue(wsocket.dataLatch.await(2, TimeUnit.SECONDS)); } - finally - { - ssocket.close(); - ssocket.disconnect(); - } } @Test @@ -312,9 +298,6 @@ public class WebSocketClientTest URI wsUri = server.getWsUri().resolve("/test?snack=cashews&amount=handful&brand=off"); Future future = client.connect(wsocket,wsUri); - IBlockheadServerConnection ssocket = server.accept(); - ssocket.upgrade(); - future.get(30,TimeUnit.SECONDS); Assert.assertTrue(wsocket.openLatch.await(1,TimeUnit.SECONDS)); diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index 2e7e2393291..a3340c7c432 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -36,6 +36,12 @@ ${project.version} test + + org.eclipse.jetty + jetty-server + ${project.version} + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java index ccd8a209412..57381ddb3db 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java @@ -227,6 +227,7 @@ public class BlockheadClientRequest extends HttpRequest implements Response.Comp endp.setIdleTimeout(client.getIdleTimeout()); + connection.setUpgradeRequestHeaders(this.getHeaders()); connection.setUpgradeResponseHeaders(response.getHeaders()); // Now swap out the connection diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java index a8374e323b8..93e5fc3c822 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java @@ -23,6 +23,7 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.io.AbstractConnection; @@ -58,6 +59,7 @@ public class BlockheadConnection extends AbstractConnection implements Connectio private final IncomingCapture incomingCapture; private ByteBuffer networkBuffer; private HttpFields upgradeResponseHeaders; + private HttpFields upgradeRequestHeaders; public BlockheadConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) { @@ -115,6 +117,11 @@ public class BlockheadConnection extends AbstractConnection implements Connectio } } + public ByteBufferPool getBufferPool() + { + return bufferPool; + } + public LinkedBlockingQueue getFrameQueue() { return incomingCapture.incomingFrames; @@ -140,6 +147,11 @@ public class BlockheadConnection extends AbstractConnection implements Connectio return getEndPoint().getRemoteAddress(); } + public HttpFields getUpgradeRequestHeaders() + { + return upgradeRequestHeaders; + } + public HttpFields getUpgradeResponseHeaders() { return upgradeResponseHeaders; @@ -175,11 +187,21 @@ public class BlockheadConnection extends AbstractConnection implements Connectio LOG.warn("Connection Error", cause); } + public void setUpgradeRequestHeaders(HttpFields upgradeRequestHeaders) + { + this.upgradeRequestHeaders = upgradeRequestHeaders; + } + public void setUpgradeResponseHeaders(HttpFields upgradeResponseHeaders) { this.upgradeResponseHeaders = upgradeResponseHeaders; } + public void setIncomingFrameConsumer(Consumer consumer) + { + this.incomingCapture.frameConsumer = consumer; + } + public void write(WebSocketFrame frame) { networkOutgoing.outgoingFrame(frame, null, BatchMode.OFF); @@ -197,7 +219,11 @@ public class BlockheadConnection extends AbstractConnection implements Connectio buf.limit(len); try { - getEndPoint().flush(slice); + boolean done = false; + while (!done) + { + done = getEndPoint().flush(slice); + } } catch (IOException e) { @@ -311,6 +337,7 @@ public class BlockheadConnection extends AbstractConnection implements Connectio { public final LinkedBlockingQueue incomingFrames = new LinkedBlockingQueue<>(); public final LinkedBlockingQueue incomingErrors = new LinkedBlockingQueue<>(); + public Consumer frameConsumer; @Override public void incomingError(Throwable cause) @@ -321,6 +348,9 @@ public class BlockheadConnection extends AbstractConnection implements Connectio @Override public void incomingFrame(Frame frame) { + if(frameConsumer != null) + frameConsumer.accept(frame); + incomingFrames.offer(WebSocketFrame.copy(frame)); } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java index 72d1cb87828..832a15422e1 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java @@ -18,45 +18,116 @@ package org.eclipse.jetty.websocket.common.test; -import static org.hamcrest.Matchers.*; - import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; import java.net.URI; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.BiFunction; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConnection; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.junit.Assert; +import org.eclipse.jetty.websocket.api.WebSocketBehavior; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; +import org.eclipse.jetty.websocket.common.AcceptHash; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; +import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; /** - * A overly simplistic websocket server used during testing. + * A Server capable of WebSocket upgrade useful for testing. *

    - * This is not meant to be performant or accurate. In fact, having the server misbehave is a useful trait during testing. + * This implementation exists to allow for testing of non-standard server behaviors, + * especially around the WebSocket Upgrade process. */ public class BlockheadServer { private static final Logger LOG = Log.getLogger(BlockheadServer.class); - private ServerSocket serverSocket; + public static final String SEC_WEBSOCKET_EXTENSIONS = HttpHeader.SEC_WEBSOCKET_EXTENSIONS.toString(); + + private final Server server; + private final ServerConnector connector; + private final BlockheadServerHandler serverHandler; + private final WebSocketPolicy policy; + private final WebSocketContainerScope websocketContainer; + private final WebSocketExtensionFactory extensionFactory; private URI wsUri; - public IBlockheadServerConnection accept() throws IOException + public BlockheadServer() { - LOG.debug(".accept()"); - assertIsStarted(); - Socket socket = serverSocket.accept(); - return new BlockheadServerConnection(socket); + this.server = new Server(); + this.connector = new ServerConnector(this.server); + this.connector.setPort(0); + this.server.addConnector(connector); + + this.policy = new WebSocketPolicy(WebSocketBehavior.SERVER); + this.websocketContainer = new SimpleContainerScope(policy); + this.extensionFactory = new WebSocketExtensionFactory(websocketContainer); + + HandlerList handlers = new HandlerList(); + this.serverHandler = new BlockheadServerHandler(websocketContainer, extensionFactory); + handlers.addHandler(this.serverHandler); + handlers.addHandler(new DefaultHandler()); + this.server.setHandler(handlers); } - private void assertIsStarted() + public void addConnectFuture(CompletableFuture serverConnFut) { - Assert.assertThat("ServerSocket",serverSocket,notNullValue()); - Assert.assertThat("ServerSocket.isBound",serverSocket.isBound(),is(true)); - Assert.assertThat("ServerSocket.isClosed",serverSocket.isClosed(),is(false)); + this.serverHandler.getWSConnectionFutures().offer(serverConnFut); + } - Assert.assertThat("WsUri",wsUri,notNullValue()); + public WebSocketExtensionFactory getExtensionFactory() + { + return extensionFactory; + } + + public WebSocketPolicy getPolicy() + { + return policy; + } + + public WebSocketContainerScope getWebsocketContainer() + { + return websocketContainer; + } + + /** + * Set PRE-Request Handling function. + * + * @param requestFunction the function to handle the request (before upgrade), do whatever you want. + * Note that if you return true, the request will not process into the default Upgrade flow, + * false will allow the default Upgrade flow. + */ + public void setRequestHandling(BiFunction requestFunction) + { + this.serverHandler.setFunction(requestFunction); + } + + public void resetRequestHandling() + { + this.serverHandler.setFunction(null); } public URI getWsUri() @@ -64,28 +135,145 @@ public class BlockheadServer return wsUri; } - public void start() throws IOException + public void start() throws Exception { - InetAddress addr = InetAddress.getByName("localhost"); - serverSocket = new ServerSocket(); - InetSocketAddress endpoint = new InetSocketAddress(addr,0); - serverSocket.bind(endpoint,1); - int port = serverSocket.getLocalPort(); - String uri = String.format("ws://%s:%d/",addr.getHostAddress(),port); - wsUri = URI.create(uri); - LOG.debug("Server Started on {} -> {}",endpoint,wsUri); + this.server.start(); + + wsUri = URI.create("ws://localhost:" + this.connector.getLocalPort() + "/"); + + LOG.debug("BlockheadServer available on {}", wsUri); } - public void stop() + public void stop() throws Exception { LOG.debug("Stopping Server"); - try + this.server.stop(); + } + + public static class BlockheadServerHandler extends AbstractHandler + { + private final WebSocketContainerScope container; + private final WebSocketExtensionFactory extensionFactory; + private BiFunction requestFunction; + private LinkedBlockingQueue> futuresQueue; + + public BlockheadServerHandler(WebSocketContainerScope websocketContainer, WebSocketExtensionFactory extensionFactory) { - serverSocket.close(); + super(); + this.container = websocketContainer; + this.extensionFactory = extensionFactory; + this.futuresQueue = new LinkedBlockingQueue<>(); } - catch (IOException ignore) + + public Queue> getWSConnectionFutures() { - /* ignore */ + return futuresQueue; + } + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + Response baseResponse = (Response) response; + if(requestFunction != null) + { + if(requestFunction.apply(baseRequest, baseResponse)) + { + baseRequest.setHandled(true); + return; + } + } + + CompletableFuture connFut = this.futuresQueue.poll(); + + try + { + baseRequest.setHandled(true); + + // default/simplified Upgrade flow + String key = request.getHeader("Sec-WebSocket-Key"); + + if (key == null) + { + throw new IllegalStateException("Missing request header 'Sec-WebSocket-Key'"); + } + + // build response + response.setHeader("Upgrade", "WebSocket"); + response.addHeader("Connection", "Upgrade"); + response.addHeader("Sec-WebSocket-Accept", AcceptHash.hashKey(key)); + + response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + + // Initialize / Negotiate Extensions + ExtensionStack extensionStack = new ExtensionStack(extensionFactory); + + if (response.containsHeader(SEC_WEBSOCKET_EXTENSIONS)) + { + // Use pre-negotiated extension list from response + List extensionConfigs = new ArrayList<>(); + response.getHeaders(SEC_WEBSOCKET_EXTENSIONS).forEach( + (value) -> extensionConfigs.addAll(ExtensionConfig.parseList(value))); + extensionStack.negotiate(extensionConfigs); + } + else + { + // Use what was given to us + Enumeration e = request.getHeaders(SEC_WEBSOCKET_EXTENSIONS); + List extensionConfigs = ExtensionConfig.parseEnum(e); + extensionStack.negotiate(extensionConfigs); + + String negotiatedHeaderValue = ExtensionConfig.toHeaderValue(extensionStack.getNegotiatedExtensions()); + response.setHeader(SEC_WEBSOCKET_EXTENSIONS, negotiatedHeaderValue); + } + + WebSocketPolicy policy = this.container.getPolicy().clonePolicy(); + + // Get original HTTP connection + HttpConnection http = (HttpConnection) request.getAttribute("org.eclipse.jetty.server.HttpConnection"); + + EndPoint endp = http.getEndPoint(); + Connector connector = http.getConnector(); + Executor executor = connector.getExecutor(); + ByteBufferPool bufferPool = connector.getByteBufferPool(); + + // Setup websocket connection + BlockheadServerConnection wsConnection = new BlockheadServerConnection( + policy, + bufferPool, + extensionStack, + endp, + executor); + + if (LOG.isDebugEnabled()) + { + LOG.debug("HttpConnection: {}", http); + LOG.debug("BlockheadServerConnection: {}", wsConnection); + } + + wsConnection.setUpgradeRequestHeaders(baseRequest.getHttpFields()); + wsConnection.setUpgradeResponseHeaders(baseResponse.getHttpFields()); + + // Tell jetty about the new upgraded connection + request.setAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, wsConnection); + + if (LOG.isDebugEnabled()) + LOG.debug("Websocket upgrade {} {}", request.getRequestURI(), wsConnection); + + if(connFut != null) + connFut.complete(wsConnection); + + } + catch(Throwable cause) + { + if(connFut != null) + connFut.completeExceptionally(cause); + LOG.warn(cause); + } + } + + public void setFunction(BiFunction function) + { + this.requestFunction = function; } } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java index b1a9d910198..a0a02ca77ae 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java @@ -18,561 +18,17 @@ package org.eclipse.jetty.websocket.common.test; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.Socket; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.concurrent.Executor; import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.BatchMode; +import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.websocket.api.WebSocketPolicy; -import org.eclipse.jetty.websocket.api.WriteCallback; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.api.extensions.Frame; -import org.eclipse.jetty.websocket.api.extensions.Frame.Type; -import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; -import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; -import org.eclipse.jetty.websocket.common.AcceptHash; -import org.eclipse.jetty.websocket.common.CloseInfo; -import org.eclipse.jetty.websocket.common.Generator; -import org.eclipse.jetty.websocket.common.OpCode; -import org.eclipse.jetty.websocket.common.Parser; -import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; -import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; -import org.eclipse.jetty.websocket.common.frames.CloseFrame; -import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; -import org.junit.Assert; -public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames, Runnable, IBlockheadServerConnection +public class BlockheadServerConnection extends BlockheadConnection { - private static final Logger LOG = Log.getLogger(BlockheadServerConnection.class); - - private final int BUFFER_SIZE = 8192; - private final Socket socket; - private final ByteBufferPool bufferPool; - private final WebSocketPolicy policy; - private final LinkedBlockingQueue incomingFrames = new LinkedBlockingQueue<>(); - private final LinkedBlockingQueue incomingErrors = new LinkedBlockingQueue<>(); - private final Parser parser; - private final Generator generator; - private final AtomicInteger parseCount; - private final WebSocketExtensionFactory extensionRegistry; - private final AtomicBoolean echoing = new AtomicBoolean(false); - private final AtomicBoolean reading = new AtomicBoolean(false); - private Thread readThread; - - /** Set to true to disable timeouts (for debugging reasons) */ - private boolean debug = false; - private OutputStream out; - private InputStream in; - - private Map extraResponseHeaders = new HashMap<>(); - private OutgoingFrames outgoing = this; - - public BlockheadServerConnection(Socket socket) + public BlockheadServerConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) { - this.socket = socket; - this.policy = WebSocketPolicy.newServerPolicy(); - this.policy.setMaxBinaryMessageSize(100000); - this.policy.setMaxTextMessageSize(100000); - // This is a blockhead server connection, no point tracking leaks on this object. - this.bufferPool = new MappedByteBufferPool(BUFFER_SIZE); - this.parser = new Parser(policy,bufferPool); - this.parseCount = new AtomicInteger(0); - this.generator = new Generator(policy,bufferPool,false); - this.extensionRegistry = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool)); - } - - /** - * Add an extra header for the upgrade response (from the server). No extra work is done to ensure the key and value are sane for http. - * @param rawkey the raw key - * @param rawvalue the raw value - */ - @Override - public void addResponseHeader(String rawkey, String rawvalue) - { - extraResponseHeaders.put(rawkey,rawvalue); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection#close() - */ - @Override - public void close() throws IOException - { - write(new CloseFrame()); - flush(); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection#close(int) - */ - @Override - public void close(int statusCode) throws IOException - { - CloseInfo close = new CloseInfo(statusCode); - write(close.asFrame()); - flush(); - } - - @Override - public void disconnect() - { - LOG.debug("disconnect"); - reading.set(false); - IO.close(in); - IO.close(out); - if (socket != null) - { - try - { - socket.close(); - } - catch (IOException ignore) - { - /* ignore */ - } - } - } - @Override - public void flush() throws IOException - { - getOutputStream().flush(); - } - - @Override - public ByteBufferPool getBufferPool() - { - return bufferPool; - } - - public InputStream getInputStream() throws IOException - { - if (in == null) - { - in = socket.getInputStream(); - } - return in; - } - - private OutputStream getOutputStream() throws IOException - { - if (out == null) - { - out = socket.getOutputStream(); - } - return out; - } - - @Override - public Parser getParser() - { - return parser; - } - - public WebSocketPolicy getPolicy() - { - return policy; - } - - @Override - public void incomingError(Throwable e) - { - incomingErrors.offer(e); - } - - @Override - public void incomingFrame(Frame frame) - { - LOG.debug("incomingFrame({})",frame); - int count = parseCount.incrementAndGet(); - if ((count % 10) == 0) - { - LOG.info("Server parsed {} frames",count); - } - incomingFrames.offer(WebSocketFrame.copy(frame)); - - if (frame.getOpCode() == OpCode.CLOSE) - { - CloseInfo close = new CloseInfo(frame); - LOG.debug("Close frame: {}",close); - } - - Type type = frame.getType(); - - if (echoing.get() && (type.isData() || type.isContinuation())) - { - try - { - write(WebSocketFrame.copy(frame).setMasked(false)); - } - catch (IOException e) - { - LOG.warn(e); - } - } - } - - @Override - public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode) - { - ByteBuffer headerBuf = generator.generateHeaderBytes(frame); - if (LOG.isDebugEnabled()) - { - LOG.debug("writing out: {}",BufferUtil.toDetailString(headerBuf)); - } - - try - { - BufferUtil.writeTo(headerBuf,out); - if (frame.hasPayload()) - BufferUtil.writeTo(frame.getPayload(),out); - out.flush(); - if (callback != null) - { - callback.writeSuccess(); - } - - if (frame.getOpCode() == OpCode.CLOSE) - { - disconnect(); - } - } - catch (Throwable t) - { - if (callback != null) - { - callback.writeFailed(t); - } - } - } - - public List parseExtensions(List requestLines) - { - List extensionConfigs = new ArrayList<>(); - - List hits = regexFind(requestLines, "^Sec-WebSocket-Extensions: (.*)$"); - - for (String econf : hits) - { - // found extensions - ExtensionConfig config = ExtensionConfig.parse(econf); - extensionConfigs.add(config); - } - - return extensionConfigs; - } - - @Override - public String parseWebSocketKey(List requestLines) - { - List hits = regexFind(requestLines,"^Sec-WebSocket-Key: (.*)$"); - if (hits.size() <= 0) - { - return null; - } - - Assert.assertThat("Number of Sec-WebSocket-Key headers", hits.size(), is(1)); - - String key = hits.get(0); - return key; - } - - @Override - public int read(ByteBuffer buf) throws IOException - { - int len = 0; - while ((in.available() > 0) && (buf.remaining() > 0)) - { - buf.put((byte)in.read()); - len++; - } - return len; - } - - @Override - public LinkedBlockingQueue getFrameQueue() - { - return incomingFrames; - } - - @Override - public String readRequest() throws IOException - { - LOG.debug("Reading client request"); - StringBuilder request = new StringBuilder(); - BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream())); - for (String line = in.readLine(); line != null; line = in.readLine()) - { - if (line.length() == 0) - { - break; - } - request.append(line).append("\r\n"); - LOG.debug("read line: {}",line); - } - - LOG.debug("Client Request:{}{}","\n",request); - return request.toString(); - } - - @Override - public List readRequestLines() throws IOException - { - LOG.debug("Reading client request header"); - List lines = new ArrayList<>(); - - BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream())); - for (String line = in.readLine(); line != null; line = in.readLine()) - { - if (line.length() == 0) - { - break; - } - lines.add(line); - } - - return lines; - } - - @Override - public List regexFind(List lines, String pattern) - { - List hits = new ArrayList<>(); - - Pattern patKey = Pattern.compile(pattern,Pattern.CASE_INSENSITIVE); - - Matcher mat; - for (String line : lines) - { - mat = patKey.matcher(line); - if (mat.matches()) - { - if (mat.groupCount() >= 1) - { - hits.add(mat.group(1)); - } - else - { - hits.add(mat.group(0)); - } - } - } - - return hits; - } - - @Override - public void respond(String rawstr) throws IOException - { - LOG.debug("respond(){}{}","\n",rawstr); - getOutputStream().write(rawstr.getBytes()); - flush(); - } - - @Override - public void run() - { - LOG.debug("Entering read thread"); - - long totalReadBytes = 0; - ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE, false); - while(reading.get()) - { - try - { - BufferUtil.clearToFill(buf); - long len = read(buf); - if (len > 0) - { - totalReadBytes += len; - LOG.debug("Read {} bytes", len); - BufferUtil.flipToFlush(buf, 0); - parser.parse(buf); - } - - try - { - TimeUnit.MILLISECONDS.sleep(20); - } - catch (InterruptedException gnore) - { - /* ignore */ - } - } - catch (IOException e) - { - LOG.debug("Exception during echo loop", e); - } - catch (Throwable t) - { - LOG.warn("Exception during echo loop", t); - } - } - - LOG.debug("Read {} total bytes (exiting)",totalReadBytes); - bufferPool.release(buf); - } - - @Override - public void setSoTimeout(int ms) throws SocketException - { - socket.setSoTimeout(ms); - } - - @Override - public void startReadThread() - { - if (readThread != null) - { - throw new IllegalStateException("Read thread already declared/started!"); - } - readThread = new Thread(this,"Blockhead-Server-Read"); - LOG.debug("Starting Read Thread: {}", readThread); - reading.set(true); - readThread.start(); - } - - @Override - public void enableIncomingEcho(boolean enabled) - { - echoing.set(enabled); - } - - @Override - public List upgrade() throws IOException - { - List requestLines = readRequestLines(); - List extensionConfigs = parseExtensions(requestLines); - String key = parseWebSocketKey(requestLines); - - LOG.debug("Client Request Extensions: {}",extensionConfigs); - LOG.debug("Client Request Key: {}",key); - - Assert.assertThat("Request: Sec-WebSocket-Key",key,notNullValue()); - - // collect extensions configured in response header - ExtensionStack extensionStack = new ExtensionStack(extensionRegistry); - extensionStack.negotiate(extensionConfigs); - - // Start with default routing - extensionStack.setNextIncoming(this); - extensionStack.setNextOutgoing(this); - - // Configure Parser / Generator - extensionStack.configure(parser); - extensionStack.configure(generator); - - // Start Stack - try - { - extensionStack.start(); - } - catch (Exception e) - { - throw new IOException("Unable to start Extension Stack"); - } - - // Configure Parser - parser.setIncomingFramesHandler(extensionStack); - - // Setup Response - StringBuilder resp = new StringBuilder(); - resp.append("HTTP/1.1 101 Upgrade\r\n"); - resp.append("Connection: upgrade\r\n"); - resp.append("Content-Length: 0\r\n"); - resp.append("Sec-WebSocket-Accept: "); - resp.append(AcceptHash.hashKey(key)).append("\r\n"); - if (extensionStack.hasNegotiatedExtensions()) - { - // Respond to used extensions - resp.append("Sec-WebSocket-Extensions: "); - boolean delim = false; - for (ExtensionConfig ext : extensionStack.getNegotiatedExtensions()) - { - if (delim) - { - resp.append(", "); - } - resp.append(ext.getParameterizedName()); - delim = true; - } - resp.append("\r\n"); - } - if (extraResponseHeaders.size() > 0) - { - for (Map.Entry xheader : extraResponseHeaders.entrySet()) - { - resp.append(xheader.getKey()); - resp.append(": "); - resp.append(xheader.getValue()); - resp.append("\r\n"); - } - } - resp.append("\r\n"); - - // Write Response - LOG.debug("Response: {}",resp.toString()); - write(resp.toString().getBytes()); - return requestLines; - } - - private void write(byte[] bytes) throws IOException - { - getOutputStream().write(bytes); - } - - public void write(byte[] buf, int offset, int length) throws IOException - { - getOutputStream().write(buf,offset,length); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection#write(org.eclipse.jetty.websocket.api.extensions.Frame) - */ - @Override - public void write(Frame frame) throws IOException - { - LOG.debug("write(Frame->{}) to {}",frame,outgoing); - outgoing.outgoingFrame(frame,null,BatchMode.OFF); - } - - @Override - public void write(int b) throws IOException - { - getOutputStream().write(b); - } - - @Override - public void write(ByteBuffer buf) throws IOException - { - byte arr[] = BufferUtil.toArray(buf); - if ((arr != null) && (arr.length > 0)) - { - getOutputStream().write(arr); - } + super(policy, bufferPool, extensionStack, endp, executor); } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java deleted file mode 100644 index a44ec00e6dd..00000000000 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java +++ /dev/null @@ -1,68 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.common.test; - -import java.io.IOException; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.LinkedBlockingQueue; - -import org.eclipse.jetty.io.ByteBufferPool; -import org.eclipse.jetty.websocket.api.extensions.Frame; -import org.eclipse.jetty.websocket.common.Parser; -import org.eclipse.jetty.websocket.common.WebSocketFrame; - -@Deprecated -public interface IBlockheadServerConnection -{ - public void close() throws IOException; - public void close(int statusCode) throws IOException; - public void disconnect(); - - public void write(Frame frame) throws IOException; - public void write(ByteBuffer buf) throws IOException; - public void write(int b) throws IOException; - public void flush() throws IOException; - - public LinkedBlockingQueue getFrameQueue(); - - public void enableIncomingEcho(boolean enabled); - public void startReadThread(); - - public String readRequest() throws IOException; - public List readRequestLines() throws IOException; - public String parseWebSocketKey(List requestLines); - /** - * Add an extra header for the upgrade response (from the server). No extra work is done to ensure the key and value are sane for http. - * @param rawkey the raw key - * @param rawvalue the raw value - */ - public void addResponseHeader(String rawkey, String rawvalue); - public List upgrade() throws IOException; - public void setSoTimeout(int ms) throws SocketException; - - public void respond(String rawstr) throws IOException; - public List regexFind(List lines, String pattern); - public ByteBufferPool getBufferPool(); - public Parser getParser(); - - @Deprecated - public int read(ByteBuffer buf) throws IOException; -} \ No newline at end of file diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java index b9092fbc6a5..d82d964bf08 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java @@ -20,11 +20,20 @@ package org.eclipse.jetty.websocket.common.test; import java.util.concurrent.TimeUnit; +/** + * A central place for all of the various test timeouts within the websocket testing. + */ public class Timeouts { + // establish a connection timeout public static final long CONNECT = 2; public static final TimeUnit CONNECT_UNIT = TimeUnit.SECONDS; + // poll for an event timeout public static final long POLL_EVENT = 2; public static final TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS; + + // send a message timeout + public static final long SEND = 2; + public static final TimeUnit SEND_UNIT = TimeUnit.SECONDS; } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java index 210783d547d..998922e20d1 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java @@ -70,7 +70,6 @@ public class TestABCase9 extends AbstractABCase int offset = 0; boolean fin; ByteBuffer buf; - ; byte op = opcode; while (remaining > 0) { From a3100e02118fca25358c8b59baea9bd95b86e92f Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 7 Mar 2018 22:35:21 +0100 Subject: [PATCH 20/87] Issue #2288 - Cleanup the statistics classes. (#2290) * Issue #2288 - Cleanup the statistics classes. Cleaned up code, added Javadocs. Renamed SampleStatistics.set(long) to record(long). Signed-off-by: Simone Bordet * toString stddev Signed-off-by: Greg Wilkins --- .../jetty/io/ConnectionStatistics.java | 2 +- .../jetty/server/ConnectorStatistics.java | 6 +- .../server/handler/StatisticsHandler.java | 6 +- .../jetty/server/session/SessionHandler.java | 8 +- .../util/statistic/CounterStatistic.java | 64 +++++++------- .../jetty/util/statistic/SampleStatistic.java | 87 ++++++++++++------- .../util/statistic/SampleStatisticTest.java | 7 +- 7 files changed, 101 insertions(+), 79 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java index 6ea289b805e..871d57c6353 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java @@ -94,7 +94,7 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio _connections.decrement(); long elapsed = System.currentTimeMillis() - connection.getCreatedTimeStamp(); - _connectionsDuration.set(elapsed); + _connectionsDuration.record(elapsed); long bytesIn = connection.getBytesIn(); if (bytesIn > 0) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java index c6aa891fbba..519f71e7561 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectorStatistics.java @@ -80,10 +80,10 @@ public class ConnectorStatistics extends AbstractLifeCycle implements Dumpable, { long msgsIn=connection.getMessagesIn(); long msgsOut=connection.getMessagesOut(); - _messagesIn.set(msgsIn); - _messagesOut.set(msgsOut); + _messagesIn.record(msgsIn); + _messagesOut.record(msgsOut); _connectionStats.decrement(); - _connectionDurationStats.set(System.currentTimeMillis()-connection.getCreatedTimeStamp()); + _connectionDurationStats.record(System.currentTimeMillis()-connection.getCreatedTimeStamp()); Sample sample=_samples.remove(connection); if (sample!=null) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java index e12dc2133c6..3bb9f43d34a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java @@ -102,7 +102,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful final long elapsed = System.currentTimeMillis()-request.getTimeStamp(); long d=_requestStats.decrement(); - _requestTimeStats.set(elapsed); + _requestTimeStats.record(elapsed); updateResponse(request); @@ -184,7 +184,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful final long dispatched=now-start; _dispatchedStats.decrement(); - _dispatchedTimeStats.set(dispatched); + _dispatchedTimeStats.record(dispatched); if (state.isSuspended()) { @@ -197,7 +197,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful else if (state.isInitial()) { long d=_requestStats.decrement(); - _requestTimeStats.set(dispatched); + _requestTimeStats.record(dispatched); updateResponse(baseRequest); // If we have no more dispatches, should we signal shutdown? diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index 5a7c46fee23..f793222103d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -18,8 +18,6 @@ package org.eclipse.jetty.server.session; -import static java.lang.Math.round; - import java.io.IOException; import java.util.Arrays; import java.util.Collections; @@ -63,9 +61,11 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.util.statistic.SampleStatistic; +import org.eclipse.jetty.util.thread.Locker.Lock; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.Scheduler; -import org.eclipse.jetty.util.thread.Locker.Lock; + +import static java.lang.Math.round; /* ------------------------------------------------------------ */ /** @@ -1235,7 +1235,7 @@ public class SessionHandler extends ScopedHandler if (session != null) { - _sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0)); + _sessionTimeStats.record(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0)); session.finishInvalidate(); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java index 22a207aa5ef..933f84de2b3 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java @@ -22,51 +22,53 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; -/* ------------------------------------------------------------ */ -/** Statistics on a counter value. - *

    - * Keep total, current and maximum values of a counter that - * can be incremented and decremented. The total refers only - * to increments. - * +/** + *

    Statistics on a counter value.

    + *

    This class keeps the total, current and maximum value of a counter + * that can be incremented and decremented. The total refers only to increments.

    */ public class CounterStatistic { - protected final LongAccumulator _max = new LongAccumulator(Math::max,0L); - protected final AtomicLong _current = new AtomicLong(); - protected final LongAdder _total = new LongAdder(); + private final LongAccumulator _max = new LongAccumulator(Math::max, 0L); + private final AtomicLong _current = new AtomicLong(); + private final LongAdder _total = new LongAdder(); - /* ------------------------------------------------------------ */ + /** + * Resets the max and total to the current value. + */ public void reset() { _total.reset(); _max.reset(); - long current=_current.get(); + long current = _current.get(); _total.add(current); _max.accumulate(current); } - /* ------------------------------------------------------------ */ + /** + * Resets the max, total and current value to the given parameter. + * + * @param value the new current value + */ public void reset(final long value) { _current.set(value); _total.reset(); _max.reset(); - if (value>0) + if (value > 0) { _total.add(value); _max.accumulate(value); } } - /* ------------------------------------------------------------ */ /** - * @param delta the amount to add to the count - * @return the new value + * @param delta the amount to add to the counter + * @return the new counter value */ public long add(final long delta) { - long value=_current.addAndGet(delta); + long value = _current.addAndGet(delta); if (delta > 0) { _total.add(delta); @@ -75,60 +77,56 @@ public class CounterStatistic return value; } - /* ------------------------------------------------------------ */ /** - * increment the value by one - * @return the new value, post increment + * Increments the value by one. + * + * @return the new counter value after the increment */ public long increment() { - long value=_current.incrementAndGet(); + long value = _current.incrementAndGet(); _total.increment(); _max.accumulate(value); return value; } - /* ------------------------------------------------------------ */ /** - * decrement by 1 - * @return the new value, post-decrement + * Decrements the value by one. + * + * @return the new counter value after the decrement */ public long decrement() { return _current.decrementAndGet(); } - /* ------------------------------------------------------------ */ /** - * @return max value + * @return max counter value */ public long getMax() { return _max.get(); } - /* ------------------------------------------------------------ */ /** - * @return current value + * @return current counter value */ public long getCurrent() { return _current.get(); } - /* ------------------------------------------------------------ */ /** - * @return total value + * @return total counter value */ public long getTotal() { return _total.sum(); } - /* ------------------------------------------------------------ */ @Override public String toString() { - return String.format("%s@%x{c=%d,m=%d,t=%d}",this.getClass().getSimpleName(),hashCode(),_current.get(),_max.get(),_total.sum()); + return String.format("%s@%x{c=%d,m=%d,t=%d}", getClass().getSimpleName(), hashCode(), getCurrent(), getMax(), getTotal()); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java index 3a5dd2faa71..db8cf39a330 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java @@ -22,31 +22,26 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; -import org.eclipse.jetty.util.Atomics; - - /** - * SampledStatistics - *

    - * Provides max, total, mean, count, variance, and standard deviation of continuous sequence of samples. - *

    - * Calculates estimates of mean, variance, and standard deviation characteristics of a sample using a non synchronized + *

    Statistics on a sampled value.

    + *

    Provides max, total, mean, count, variance, and standard deviation of continuous sequence of samples.

    + *

    Calculates estimates of mean, variance, and standard deviation characteristics of a sample using a non synchronized * approximation of the on-line algorithm presented in Donald Knuth's Art of Computer Programming, Volume 2, - * Semi numerical Algorithms, 3rd edition, page 232, Boston: Addison-Wesley. that cites a 1962 paper by B.P. Welford that - * can be found by following Note on a Method for Calculating Corrected Sums - * of Squares and Products - *

    - * This algorithm is also described in Wikipedia at - * Algorithms for calculating variance + * Semi numerical Algorithms, 3rd edition, page 232, Boston: Addison-Wesley. That cites a 1962 paper by B.P. Welford: + * Note on a Method for Calculating Corrected Sums of Squares and Products

    + *

    This algorithm is also described in Wikipedia in the section "Online algorithm": + * Algorithms for calculating variance.

    */ public class SampleStatistic { - protected final LongAccumulator _max = new LongAccumulator(Math::max,0L); - protected final AtomicLong _total = new AtomicLong(); - protected final AtomicLong _count = new AtomicLong(); - protected final LongAdder _totalVariance100 = new LongAdder(); + private final LongAccumulator _max = new LongAccumulator(Math::max, 0L); + private final AtomicLong _total = new AtomicLong(); + private final AtomicLong _count = new AtomicLong(); + private final LongAdder _totalVariance100 = new LongAdder(); + /** + * Resets the statistics. + */ public void reset() { _max.reset(); @@ -55,61 +50,89 @@ public class SampleStatistic _totalVariance100.reset(); } - public void set(final long sample) + /** + * Records a sample value. + * + * @param sample the value to record. + */ + public void record(long sample) { long total = _total.addAndGet(sample); long count = _count.incrementAndGet(); - if (count>1) + if (count > 1) { - long mean10 = total*10/count; - long delta10 = sample*10 - mean10; - _totalVariance100.add(delta10*delta10); + long mean10 = total * 10 / count; + long delta10 = sample * 10 - mean10; + _totalVariance100.add(delta10 * delta10); } _max.accumulate(sample); } /** - * @return the max value + * @deprecated use {@link #record(long)} instead + */ + @Deprecated + public void set(long sample) + { + record(sample); + } + + /** + * @return the max value of the recorded samples */ public long getMax() { return _max.get(); } + /** + * @return the sum of all the recorded samples + */ public long getTotal() { return _total.get(); } + /** + * @return the number of samples recorded + */ public long getCount() { return _count.get(); } + /** + * @return the average value of the samples recorded, or zero if there are no samples + */ public double getMean() { - return (double)_total.get()/_count.get(); + long count = getCount(); + return count > 0 ? (double)_total.get() / _count.get() : 0.0D; } + /** + * @return the variance of the samples recorded, or zero if there are less than 2 samples + */ public double getVariance() { - final long variance100 = _totalVariance100.sum(); - final long count = _count.get(); - - return count>1?((double)variance100)/100.0/(count-1):0.0; + long variance100 = _totalVariance100.sum(); + long count = getCount(); + return count > 1 ? variance100 / 100.0D / (count - 1) : 0.0D; } + /** + * @return the standard deviation of the samples recorded + */ public double getStdDev() { return Math.sqrt(getVariance()); } - /* ------------------------------------------------------------ */ @Override public String toString() { - return String.format("%s@%x{c=%d,m=%d,t=%d,v100=%d}",this.getClass().getSimpleName(),hashCode(),_count.get(),_max.get(),_total.get(),_totalVariance100.sum()); + return String.format("%s@%x{count=%d,mean=%d,total=%d,stddev=%f}", getClass().getSimpleName(), hashCode(), getCount(), getMax(), getTotal(), getStdDev()); } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java index 3c984f7af16..9abec3bf588 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java @@ -18,12 +18,12 @@ package org.eclipse.jetty.util.statistic; -import static org.junit.Assert.assertEquals; - import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /* ------------------------------------------------------------ */ public class SampleStatisticTest @@ -55,12 +55,13 @@ public class SampleStatisticTest { stats.reset(); for (long x : data[d]) - stats.set(x); + stats.record(x); assertEquals("count"+d,data[d].length, (int)stats.getCount()); assertNearEnough("mean"+d,results[d][0], stats.getMean()); assertNearEnough("stddev"+d,results[d][1], stats.getStdDev()); } + System.err.println(stats); } private void assertNearEnough(String test,double expected, double actual) From 35be19b818d625ecfdec52e23e3703973c087515 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 8 Mar 2018 08:46:24 +1100 Subject: [PATCH 21/87] Also use system property #2298 Signed-off-by: Greg Wilkins --- .../eclipse/jetty/util/ProcessorUtils.java | 19 ++++++++++++------- .../jetty/util/ProcessorUtilsTest.java | 17 +++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java index 30491b9aaa6..df0d8e3f1a6 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java @@ -19,21 +19,24 @@ package org.eclipse.jetty.util; /** - * ProcessorUtils return the default value for processor number from {@link Runtime} - * but in a virtual environment you can override it using env var JETTY_AVAILABLE_PROCESSORS + * ProcessorUtils provides access to runtime info about processors, that may be + * overridden by system properties of environment variables. This can be useful + * in virtualised environments where the runtime may miss report the available + * resources. */ public class ProcessorUtils { - private static int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors(); + public static final String AVAILABLE_PROCESSORS = "JETTY_AVAILABLE_PROCESSORS"; + private static int __availableProcessors = Runtime.getRuntime().availableProcessors(); static { - String avlProcEnv = System.getenv( "JETTY_AVAILABLE_PROCESSORS" ); + String avlProcEnv = System.getProperty(AVAILABLE_PROCESSORS,System.getenv(AVAILABLE_PROCESSORS)); if (avlProcEnv != null) { try { - AVAILABLE_PROCESSORS = Integer.parseInt( avlProcEnv ); + __availableProcessors = Integer.parseInt( avlProcEnv ); } catch ( NumberFormatException e ) { @@ -43,11 +46,13 @@ public class ProcessorUtils } /** - * + * Obtain the number of available processors, from System Property "JETTY_AVAILABLE_PROCESSORS", + * or if not set then environment variable "JETTY_AVAILABLE_PROCESSORS" or if not set then + * {@link Runtime#availableProcessors()}. * @return the number of processors */ public static int availableProcessors() { - return AVAILABLE_PROCESSORS; + return __availableProcessors; } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java index df2acccf4df..a9b17822be9 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.util; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; /** @@ -26,11 +27,15 @@ import org.junit.Test; */ public class ProcessorUtilsTest { - - @Test - public void get_default_value(){ - Assert.assertEquals(Runtime.getRuntime().availableProcessors(), ProcessorUtils.availableProcessors()); + @BeforeClass + public static void beforeClass() + { + System.setProperty("JETTY_AVAILABLE_PROCESSORS","42"); + } + + @Test + public void getPropertyValue() + { + Assert.assertEquals(42, ProcessorUtils.availableProcessors()); } - - } From f6c1b76e71c257981a1ae0d0653f559821422785 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 7 Mar 2018 22:47:31 +0100 Subject: [PATCH 22/87] Issue #2131 - Introduce a monitored thread pool. (#2260) * Issue #2131 - Introduce a monitored thread pool. Signed-off-by: Simone Bordet * Issue #2131 - Introduce a monitored thread pool. Updated to use SampleStatistic and CounterStatistics. Signed-off-by: Simone Bordet * Issue #2131 - Introduce a monitored thread pool. Adding statistics fields as beans. Signed-off-by: Simone Bordet --- .../thread/MonitoredQueuedThreadPool.java | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/thread/MonitoredQueuedThreadPool.java diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/MonitoredQueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/MonitoredQueuedThreadPool.java new file mode 100644 index 00000000000..9c120ddc0a8 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/MonitoredQueuedThreadPool.java @@ -0,0 +1,162 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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 org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.annotation.ManagedOperation; +import org.eclipse.jetty.util.statistic.CounterStatistic; +import org.eclipse.jetty.util.statistic.SampleStatistic; + +/** + *

    A {@link QueuedThreadPool} subclass that monitors its own activity by recording queue and task statistics.

    + */ +@ManagedObject +public class MonitoredQueuedThreadPool extends QueuedThreadPool +{ + private final CounterStatistic queueStats = new CounterStatistic(); + private final SampleStatistic queueLatencyStats = new SampleStatistic(); + private final SampleStatistic taskLatencyStats = new SampleStatistic(); + private final CounterStatistic threadStats = new CounterStatistic(); + + public MonitoredQueuedThreadPool() + { + this(256); + } + + public MonitoredQueuedThreadPool(int maxThreads) + { + super(maxThreads, maxThreads, 24 * 3600 * 1000, new BlockingArrayQueue<>(maxThreads, 256)); + addBean(queueStats); + addBean(queueLatencyStats); + addBean(taskLatencyStats); + addBean(threadStats); + } + + @Override + public void execute(final Runnable job) + { + queueStats.increment(); + long begin = System.nanoTime(); + super.execute(new Runnable() + { + @Override + public void run() + { + long queueLatency = System.nanoTime() - begin; + queueStats.decrement(); + threadStats.increment(); + queueLatencyStats.set(queueLatency); + long start = System.nanoTime(); + try + { + job.run(); + } + finally + { + long taskLatency = System.nanoTime() - start; + threadStats.decrement(); + taskLatencyStats.set(taskLatency); + } + } + + @Override + public String toString() + { + return job.toString(); + } + }); + } + + /** + * Resets the statistics. + */ + @ManagedOperation(value = "resets the statistics", impact = "ACTION") + public void reset() + { + queueStats.reset(); + queueLatencyStats.reset(); + taskLatencyStats.reset(); + threadStats.reset(0); + } + + /** + * @return the number of tasks executed + */ + @ManagedAttribute("the number of tasks executed") + public long getTasks() + { + return taskLatencyStats.getTotal(); + } + + /** + * @return the maximum number of busy threads + */ + @ManagedAttribute("the maximum number of busy threads") + public int getMaxBusyThreads() + { + return (int)threadStats.getMax(); + } + + /** + * @return the maximum task queue size + */ + @ManagedAttribute("the maximum task queue size") + public int getMaxQueueSize() + { + return (int)queueStats.getMax(); + } + + /** + * @return the average time a task remains in the queue, in nanoseconds + */ + @ManagedAttribute("the average time a task remains in the queue, in nanoseconds") + public long getAverageQueueLatency() + { + return (long)queueLatencyStats.getMean(); + } + + /** + * @return the maximum time a task remains in the queue, in nanoseconds + */ + @ManagedAttribute("the maximum time a task remains in the queue, in nanoseconds") + public long getMaxQueueLatency() + { + return queueLatencyStats.getMax(); + } + + /** + * @return the average task execution time, in nanoseconds + */ + @ManagedAttribute("the average task execution time, in nanoseconds") + public long getAverageTaskLatency() + { + return (long)taskLatencyStats.getMean(); + } + + /** + * @return the maximum task execution time, in nanoseconds + */ + @ManagedAttribute("the maximum task execution time, in nanoseconds") + public long getMaxTaskLatency() + { + return taskLatencyStats.getMax(); + } +} From a10eb59f82f9d6d2df8c5e1970fa6f92a114b442 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 8 Mar 2018 10:30:55 +1100 Subject: [PATCH 23/87] Added warning against wildcard #1053 From recommendation of @freetom Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/servlets/CrossOriginFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java index 70545d2c0a8..f61208695ee 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java @@ -54,7 +54,8 @@ import org.eclipse.jetty.util.log.Logger; *
    allowedOrigins
    *
    a comma separated list of origins that are * allowed to access the resources. Default value is *, meaning all - * origins. + * origins. Note that using wild cards can result in security problems + * for requests identifying hosts that do not exist. *

    * If an allowed origin contains one or more * characters (for example * http://*.domain.com), then "*" characters are converted to ".*", "." From e76f6d7bafe9b13c270e111941deac861dc84244 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 7 Mar 2018 17:41:45 -0600 Subject: [PATCH 24/87] Issue #2282 - more websocket test stablization Signed-off-by: Joakim Erdfelt --- .../websocket/client/ClientConnectTest.java | 7 ++++--- .../websocket/client/SlowServerTest.java | 14 +------------- .../client/TomcatServerQuirksTest.java | 2 +- .../websocket/client/WebSocketClientTest.java | 10 ++++++++-- .../test/BlockheadClientConnection.java | 10 ++++++++-- .../common/test/BlockheadClientRequest.java | 3 +-- .../common/test/BlockheadConnection.java | 19 +++++++++++++++---- .../common/test/BlockheadServer.java | 5 +---- .../test/BlockheadServerConnection.java | 10 ++++++++-- .../jetty/websocket/common/test/Fuzzer.java | 2 ++ .../websocket/server/ab/TestABCase9.java | 3 ++- 11 files changed, 51 insertions(+), 34 deletions(-) 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 index f010f405be3..a66f39bf846 100644 --- 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 @@ -186,7 +186,7 @@ public class ClientConnectTest ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest(); // actual value for this test is irrelevant, its important that this // header actually be sent with a value (the value specified) - upgradeRequest.setHeader("Authorization", "Bogus SHA1"); + upgradeRequest.setHeader("Authorization", "Basic YWxhZGRpbjpvcGVuc2VzYW1l"); Future future = client.connect(wsocket,wsUri,upgradeRequest); try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) @@ -194,13 +194,14 @@ public class ClientConnectTest HttpFields upgradeRequestHeaders = serverConn.getUpgradeRequestHeaders(); Session sess = future.get(30, TimeUnit.SECONDS); - sess.close(); HttpField authHeader = upgradeRequestHeaders.getField(HttpHeader.AUTHORIZATION); assertThat("Server Request Authorization Header", authHeader, is(notNullValue())); - assertThat("Server Request Authorization Value", authHeader.getValue(), is("Authorization: Bogus SHA1")); + assertThat("Server Request Authorization Value", authHeader.getValue(), is("Basic YWxhZGRpbjpvcGVuc2VzYW1l")); assertThat("Connect.UpgradeRequest", wsocket.connectUpgradeRequest, notNullValue()); assertThat("Connect.UpgradeResponse", wsocket.connectUpgradeResponse, notNullValue()); + + sess.close(); } } 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 index a20ce355200..0350fcdf3f4 100644 --- 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 @@ -28,7 +28,6 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.client.masks.ZeroMasker; import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; @@ -120,14 +119,8 @@ public class SlowServerTest String prefix = "Server Frame[" + i + "]"; Assert.assertThat(prefix, serverFrame, is(notNullValue())); Assert.assertThat(prefix + ".opCode", serverFrame.getOpCode(), is(OpCode.TEXT)); - Assert.assertThat(prefix + ".payload", serverFrame.getPayloadAsUTF8(), is("Hello")); + Assert.assertThat(prefix + ".payload", serverFrame.getPayloadAsUTF8(), is("Hello/" + i + "/")); } - - // Close - tsocket.getSession().close(StatusCode.NORMAL, "Done"); - - Assert.assertTrue("Client Socket Closed", tsocket.closeLatch.await(10, TimeUnit.SECONDS)); - tsocket.assertCloseCode(StatusCode.NORMAL); } } @@ -161,11 +154,6 @@ public class SlowServerTest // Verify receive Assert.assertThat("Message Receive Count", clientSocket.messageQueue.size(), is(messageCount)); - - // Close server connection (by exiting try-with-resources) } - - Assert.assertTrue("Client Socket Closed", clientSocket.closeLatch.await(10, TimeUnit.SECONDS)); - clientSocket.assertCloseCode(StatusCode.NORMAL); } } diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java index 4a91c18e7cc..9dc57240b5f 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java @@ -95,7 +95,7 @@ public class TomcatServerQuirksTest server.setRequestHandling((req, resp) -> { // Add the extra problematic header that triggers bug found in jetty-io resp.setHeader("Transfer-Encoding", "chunked"); - return true; + return false; }); try 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 7b741145e56..b4601b8b5f3 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 @@ -25,6 +25,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; import java.util.Arrays; @@ -70,6 +71,8 @@ public class WebSocketClientTest public static void startServer() throws Exception { server = new BlockheadServer(); + server.getPolicy().setMaxTextMessageSize(200 * 1024); + server.getPolicy().setMaxBinaryMessageSize(200 * 1024); server.start(); } @@ -80,7 +83,7 @@ public class WebSocketClientTest } @AfterClass - public void stopServer() throws Exception + public static void stopServer() throws Exception { server.stop(); } @@ -122,6 +125,7 @@ public class WebSocketClientTest // Setup echo of frames on server side serverConn.setIncomingFrameConsumer((frame)->{ WebSocketFrame copy = WebSocketFrame.copy(frame); + copy.setMask(null); // strip client mask (if present) serverConn.write(copy); }); @@ -237,7 +241,8 @@ public class WebSocketClientTest assertThat("Local Socket Address / Host",local.getAddress().getHostAddress(),notNullValue()); assertThat("Local Socket Address / Port",local.getPort(),greaterThan(0)); - assertThat("Remote Socket Address / Host",remote.getAddress().getHostAddress(),is(wsUri.getHost())); + String uriHostAddress = InetAddress.getByName(wsUri.getHost()).getHostAddress(); + assertThat("Remote Socket Address / Host",remote.getAddress().getHostAddress(),is(uriHostAddress)); assertThat("Remote Socket Address / Port",remote.getPort(),greaterThan(0)); } @@ -264,6 +269,7 @@ public class WebSocketClientTest // Setup echo of frames on server side serverConn.setIncomingFrameConsumer((frame)->{ WebSocketFrame copy = WebSocketFrame.copy(frame); + copy.setMask(null); // strip client mask (if present) serverConn.write(copy); }); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java index 72d7ff2c859..75d2a40950c 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.websocket.common.test; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.ThreadLocalRandom; @@ -29,9 +30,14 @@ import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; public class BlockheadClientConnection extends BlockheadConnection { - public BlockheadClientConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + public BlockheadClientConnection(WebSocketPolicy policy, + ByteBufferPool bufferPool, + ExtensionStack extensionStack, + CompletableFuture openFut, + EndPoint endp, + Executor executor) { - super(policy, bufferPool, extensionStack, endp, executor); + super(policy, bufferPool, extensionStack, openFut, endp, executor); } @Override diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java index 57381ddb3db..2f81c5bc2ab 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java @@ -222,6 +222,7 @@ public class BlockheadClientRequest extends HttpRequest implements Response.Comp client.getPolicy(), client.getBufferPool(), extensionStack, + fut, endp, client.getExecutor()); @@ -232,8 +233,6 @@ public class BlockheadClientRequest extends HttpRequest implements Response.Comp // Now swap out the connection endp.upgrade(connection); - - fut.complete(connection); } /** diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java index 93e5fc3c822..52a1f9852ad 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.common.test; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.function.Consumer; @@ -57,11 +58,12 @@ public class BlockheadConnection extends AbstractConnection implements Connectio private final ExtensionStack extensionStack; private final OutgoingNetwork networkOutgoing; private final IncomingCapture incomingCapture; + private final CompletableFuture openFuture; private ByteBuffer networkBuffer; private HttpFields upgradeResponseHeaders; private HttpFields upgradeRequestHeaders; - public BlockheadConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + public BlockheadConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, CompletableFuture openFut, EndPoint endp, Executor executor) { super(endp, executor); this.LOG = Log.getLogger(this.getClass()); @@ -70,6 +72,7 @@ public class BlockheadConnection extends AbstractConnection implements Connectio this.parser = new Parser(policy, bufferPool); this.generator = new Generator(policy, bufferPool, false); this.extensionStack = extensionStack; + this.openFuture = openFut; this.extensionStack.configure(this.parser); this.extensionStack.configure(this.generator); @@ -179,22 +182,26 @@ public class BlockheadConnection extends AbstractConnection implements Connectio public void onOpen() { super.onOpen(); + if(this.openFuture != null) + this.openFuture.complete(this); fillInterested(); } public void processConnectionError(Throwable cause) { LOG.warn("Connection Error", cause); + if(this.openFuture != null) + this.openFuture.completeExceptionally(cause); } public void setUpgradeRequestHeaders(HttpFields upgradeRequestHeaders) { - this.upgradeRequestHeaders = upgradeRequestHeaders; + this.upgradeRequestHeaders = new HttpFields(upgradeRequestHeaders); } public void setUpgradeResponseHeaders(HttpFields upgradeResponseHeaders) { - this.upgradeResponseHeaders = upgradeResponseHeaders; + this.upgradeResponseHeaders = new HttpFields(upgradeResponseHeaders); } public void setIncomingFrameConsumer(Consumer consumer) @@ -209,7 +216,11 @@ public class BlockheadConnection extends AbstractConnection implements Connectio public void writeRaw(ByteBuffer buf) throws IOException { - getEndPoint().flush(buf); + boolean done = false; + while (!done) + { + done = getEndPoint().flush(buf); + } } public void writeRaw(ByteBuffer buf, int numBytes) throws IOException diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java index 832a15422e1..b671eb9d334 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java @@ -241,6 +241,7 @@ public class BlockheadServer policy, bufferPool, extensionStack, + connFut, endp, executor); @@ -258,10 +259,6 @@ public class BlockheadServer if (LOG.isDebugEnabled()) LOG.debug("Websocket upgrade {} {}", request.getRequestURI(), wsConnection); - - if(connFut != null) - connFut.complete(wsConnection); - } catch(Throwable cause) { diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java index a0a02ca77ae..fa4445743c4 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.websocket.common.test; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import org.eclipse.jetty.io.ByteBufferPool; @@ -27,8 +28,13 @@ import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; public class BlockheadServerConnection extends BlockheadConnection { - public BlockheadServerConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + public BlockheadServerConnection(WebSocketPolicy policy, + ByteBufferPool bufferPool, + ExtensionStack extensionStack, + CompletableFuture openFut, + EndPoint endp, + Executor executor) { - super(policy, bufferPool, extensionStack, endp, executor); + super(policy, bufferPool, extensionStack, openFut, endp, executor); } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java index d83ddabe863..16982e294d2 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.common.test; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import java.io.IOException; import java.net.SocketException; @@ -184,6 +185,7 @@ public class Fuzzer implements AutoCloseable LOG.debug("{} {}",prefix,actual); + Assert.assertThat(prefix, actual, is(notNullValue())); Assert.assertThat(prefix + ".opcode",OpCode.name(actual.getOpCode()),is(OpCode.name(expected.getOpCode()))); prefix += "/" + actual.getOpCode(); if (expected.getOpCode() == OpCode.CLOSE) diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java index 998922e20d1..68b798f9648 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; import org.eclipse.jetty.websocket.common.frames.DataFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.Test; /** @@ -176,7 +177,7 @@ public class TestABCase9 extends AbstractABCase fuzzer.connect(); fuzzer.setSendMode(Fuzzer.SendMode.BULK); fuzzer.send(send); - fuzzer.expect(expect); + fuzzer.expect(expect, Timeouts.POLL_EVENT*2, Timeouts.POLL_EVENT_UNIT); } } From 5541fcbdba7c58ab441f78e881ba034b7320e9be Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 7 Mar 2018 18:34:03 -0600 Subject: [PATCH 25/87] Issue #2282 - final testing tweaks Signed-off-by: Joakim Erdfelt --- .../jetty/websocket/jsr356/DecoderReaderTest.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java index 3d0f70ae66d..cf7f6106a30 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java @@ -207,8 +207,16 @@ public class DecoderReaderTest } } + /** + * Test that multiple quotes can go through decoder without issue. + *

    + * Since this decoder is Reader based, this is a useful test to ensure + * that the Reader creation / dispatch / hand off to the user endpoint + * works properly. + *

    + * @throws Exception + */ @Test - // @Ignore ("Quotes appear to be able to arrive in any order?") public void testTwoQuotes() throws Exception { // Hook into server connection creation @@ -221,10 +229,11 @@ public class DecoderReaderTest try (BlockheadConnection serverConn = serverConnFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { writeQuotes( serverConn,"quotes-ben.txt"); - writeQuotes( serverConn,"quotes-twain.txt"); Quotes quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Quotes Author", quotes.author, is("Benjamin Franklin")); Assert.assertThat("Quotes Count", quotes.quotes.size(), is(3)); + + writeQuotes( serverConn,"quotes-twain.txt"); quotes = quoter.messageQueue.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Quotes Author", quotes.author, is("Mark Twain")); } From c22eedac8b58c0b8abc650b4be7f906605a898e0 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 7 Mar 2018 10:10:28 +1000 Subject: [PATCH 26/87] upgrade surefire version to 2.21.0 Signed-off-by: olivier lamy use a property for surefire version and align version Signed-off-by: olivier lamy --- jetty-maven-plugin/pom.xml | 1 - .../jetty-simple-webapp/pom.xml | 2 +- .../jetty-simple-webapp/pom.xml | 2 +- .../it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml | 2 +- .../it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml | 2 +- pom.xml | 10 +++------- 6 files changed, 7 insertions(+), 12 deletions(-) diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 92d25548c94..0317e5c6ffc 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -13,7 +13,6 @@ 3.5.0 3.5 ${project.groupId}.maven.plugin - 2.20.1 false FREEBEER diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml index c43b9f0e7b1..ed07bd37fe6 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml @@ -65,7 +65,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20 + @surefireVersion@ ${jetty.port.file} diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml index aee069f4651..40f2b144fe4 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/pom.xml @@ -72,7 +72,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20 + @surefireVersion@ ${jetty.port.file} diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml index 2d8381239d5..df71841c32c 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/pom.xml @@ -68,7 +68,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20 + @surefireVersion@ ${jetty.port.file} diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml index 14bb7e933ef..7c0f1bc1b75 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/pom.xml @@ -64,7 +64,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20 + @surefireVersion@ ${jetty.port.file} diff --git a/pom.xml b/pom.xml index 53325f8c75d..bae5df5fa97 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,7 @@ 6.0 1.20 benchmarks + 2.21.0 @@ -439,7 +440,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.20.1 + ${surefireVersion} org.apache.maven.plugins @@ -593,7 +594,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20 + ${surefireVersion} @{argLine} -Dfile.encoding=UTF-8 -Duser.language=en -Duser.region=US -showversion -Xmx1g -Xms1g -XX:+PrintGCDetails false @@ -1022,11 +1023,6 @@ true - - org.apache.maven.plugins - maven-failsafe-plugin - 2.21.0-SNAPSHOT - From 4c24c457de6720266303d8c00de07dd04e91f209 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Sat, 10 Mar 2018 15:05:02 +0100 Subject: [PATCH 27/87] Fixes #2312 - HTTP/2 Connection.Listener notified after first request. Signed-off-by: Simone Bordet --- .../jetty/http2/client/HTTP2ClientConnectionFactory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java index 8d48028f9da..64df651c950 100644 --- a/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java +++ b/jetty-http2/http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java @@ -124,15 +124,15 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory { session.frames(null, this, prefaceFrame, settingsFrame); } - // Only start reading from server after we have sent the client preface, - // otherwise we risk to read the server preface (a SETTINGS frame) and - // reply to that before we have the chance to send the client preface. - super.onOpen(); } @Override public void succeeded() { + // Only start reading from server after we have sent the client preface, + // otherwise we risk to read the server preface (a SETTINGS frame) and + // reply to that before we have the chance to send the client preface. + super.onOpen(); promise.succeeded(getSession()); } From 21bdb367fdfdcde1f4d9c79ae136652ea138c080 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Sat, 10 Mar 2018 15:11:40 +0100 Subject: [PATCH 28/87] Fixes #2313 - Dump HTTP/2 channel state. Dumping also HttpChannelOverHTTP2 when dumping the HTTP2Stream. The channel is now stored as a field in HTTP2Stream rather than as an attribute to save the attributes map allocation. Consequently, IStream has now getter/setter for the property "attachment" that is used to store the channel without having a type dependency on HttpChannel. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/http2/HTTP2Flusher.java | 2 +- .../org/eclipse/jetty/http2/HTTP2Stream.java | 17 ++++++++++-- .../java/org/eclipse/jetty/http2/IStream.java | 15 +++++++---- .../client/http/HttpChannelOverHTTP2.java | 9 +++++++ .../client/http/HttpSenderOverHTTP2.java | 4 ++- .../http2/server/HTTP2ServerConnection.java | 27 ++++++++++--------- .../http2/server/HttpTransportOverHTTP2.java | 2 +- 7 files changed, 53 insertions(+), 23 deletions(-) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java index 9199bf665d8..cce85626b15 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Flusher.java @@ -223,7 +223,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable IStream stream = entry.stream; if (stream != null && !entry.isControl()) { - Object channel = stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + Object channel = stream.getAttachment(); if (channel instanceof WriteFlusher.Listener) ((WriteFlusher.Listener)channel).onFlushed(update - Frame.HEADER_LENGTH); } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java index e8c10f3d85b..4cd67c4a24e 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java @@ -47,6 +47,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa { private static final Logger LOG = Log.getLogger(HTTP2Stream.class); + private final AtomicReference attachment = new AtomicReference<>(); private final AtomicReference> attributes = new AtomicReference<>(); private final AtomicReference closeState = new AtomicReference<>(CloseState.NOT_CLOSED); private final AtomicReference writing = new AtomicReference<>(); @@ -73,6 +74,18 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa return streamId; } + @Override + public Object getAttachment() + { + return attachment.get(); + } + + @Override + public void setAttachment(Object attachment) + { + this.attachment.set(attachment); + } + @Override public boolean isLocal() { @@ -460,7 +473,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa @Override public String toString() { - return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b,%s}", getClass().getSimpleName(), - hashCode(), getId(), sendWindow, recvWindow, isReset(), closeState); + return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b,%s,attachment=%s}", getClass().getSimpleName(), + hashCode(), getId(), sendWindow, recvWindow, isReset(), closeState, attachment); } } diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java index 669e8c9807d..3fe92bbaf23 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/IStream.java @@ -32,12 +32,17 @@ import org.eclipse.jetty.util.Callback; public interface IStream extends Stream, Closeable { /** - *

    The constant used as attribute key to store/retrieve the HTTP - * channel associated with this stream

    - * - * @see #setAttribute(String, Object) + * @return the object attached to this stream + * @see #setAttachment(Object) */ - public static final String CHANNEL_ATTRIBUTE = IStream.class.getName() + ".channel"; + public Object getAttachment(); + + /** + * Attaches the given object to this stream for later retrieval. + * + * @param attachment the object to attach to this stream + */ + public void setAttachment(Object attachment); /** * @return whether this stream is local or remote diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java index b3372e49f6f..cdc4662fc1a 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java @@ -120,4 +120,13 @@ public class HttpChannelOverHTTP2 extends HttpChannel super.exchangeTerminated(exchange, result); release(); } + + @Override + public String toString() + { + return String.format("%s[send=%s,recv=%s]", + super.toString(), + sender, + receiver); + } } diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java index 6a3a99e749c..4950c949d3d 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.IStream; import org.eclipse.jetty.http2.api.Stream; import org.eclipse.jetty.http2.frames.DataFrame; import org.eclipse.jetty.http2.frames.HeadersFrame; @@ -64,7 +65,8 @@ public class HttpSenderOverHTTP2 extends HttpSender @Override public void succeeded(Stream stream) { - getHttpChannel().setStream(stream); + channel.setStream(stream); + ((IStream)stream).setAttachment(channel); stream.setIdleTimeout(request.getIdleTimeout()); if (content.hasContent() && !expects100Continue(request)) diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java index fb18d564a72..f0cbf40091b 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java @@ -25,6 +25,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Queue; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicLong; @@ -172,7 +173,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { if (LOG.isDebugEnabled()) LOG.debug("Processing {} on {}", frame, stream); - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) { Runnable task = channel.onRequestContent(frame, callback); @@ -189,7 +190,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { if (LOG.isDebugEnabled()) LOG.debug("Processing trailers {} on {}", frame, stream); - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) { Runnable task = channel.onRequestTrailers(frame); @@ -200,7 +201,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection public boolean onStreamTimeout(IStream stream, Throwable failure) { - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); boolean result = channel != null && channel.onStreamTimeout(failure, task -> offerTask(task, true)); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", stream, failure); @@ -211,7 +212,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection { if (LOG.isDebugEnabled()) LOG.debug("Processing failure on {}: {}", stream, failure); - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) { Runnable task = channel.onFailure(failure, callback); @@ -227,13 +228,13 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection public boolean onSessionTimeout(Throwable failure) { ISession session = getSession(); - boolean result = true; - for (Stream stream : session.getStreams()) - { - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); - if (channel != null) - result &= channel.isRequestIdle(); - } + // Compute whether all requests are idle. + boolean result = session.getStreams().stream() + .map(stream -> (IStream)stream) + .map(stream -> (HttpChannelOverHTTP2)stream.getAttachment()) + .filter(Objects::nonNull) + .map(HttpChannelOverHTTP2::isRequestIdle) + .reduce(true, Boolean::logicalAnd); if (LOG.isDebugEnabled()) LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", session, failure); return result; @@ -284,7 +285,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection if (LOG.isDebugEnabled()) LOG.debug("Creating channel {} for {}", channel, this); } - stream.setAttribute(IStream.CHANNEL_ATTRIBUTE, channel); + stream.setAttachment(channel); return channel; } @@ -379,7 +380,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection @Override public void recycle() { - getStream().removeAttribute(IStream.CHANNEL_ATTRIBUTE); + getStream().setAttachment(null); super.recycle(); offerHttpChannel(this); } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java index b11817837fe..d862891c8f8 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpTransportOverHTTP2.java @@ -248,7 +248,7 @@ public class HttpTransportOverHTTP2 implements HttpTransport // Consume the existing queued data frames to // avoid stalling the session flow control. - HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE); + HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttachment(); if (channel != null) channel.consumeInput(); } From ff341fb42060c3c337414a1fa8f04a132aa9d225 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 12 Mar 2018 11:30:00 +0100 Subject: [PATCH 29/87] Issue #2313 - Dump HTTP/2 channel state. Added HTTP/2 stream age to toString(). Signed-off-by: Simone Bordet --- .../java/org/eclipse/jetty/http2/HTTP2Stream.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java index 4cd67c4a24e..91e635d6b96 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.nio.channels.WritePendingException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -53,6 +54,7 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa private final AtomicReference writing = new AtomicReference<>(); private final AtomicInteger sendWindow = new AtomicInteger(); private final AtomicInteger recvWindow = new AtomicInteger(); + private final long timeStamp = System.nanoTime(); private final ISession session; private final int streamId; private final boolean local; @@ -473,7 +475,15 @@ public class HTTP2Stream extends IdleTimeout implements IStream, Callback, Dumpa @Override public String toString() { - return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b,%s,attachment=%s}", getClass().getSimpleName(), - hashCode(), getId(), sendWindow, recvWindow, isReset(), closeState, attachment); + return String.format("%s@%x#%d{sendWindow=%s,recvWindow=%s,reset=%b,%s,age=%d,attachment=%s}", + getClass().getSimpleName(), + hashCode(), + getId(), + sendWindow, + recvWindow, + isReset(), + closeState, + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - timeStamp), + attachment); } } From 8b391a88ddc94d647aeb323a057bf8d35910f847 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 12 Mar 2018 18:58:34 +0100 Subject: [PATCH 30/87] Fixes #2318 - HttpParser.Listener.onBadMessage() should take BadMessageException. Changed the signature of HttpParser.Listener.onBadMessage() to take a BadMessageException and updated dependent code. Signed-off-by: Simone Bordet --- .../client/http/HttpReceiverOverHTTP.java | 6 +++--- .../eclipse/jetty/client/HttpClientTest.java | 10 ++++------ .../fcgi/parser/ResponseContentParser.java | 4 ++-- .../fcgi/server/ServerFCGIConnection.java | 6 +++--- .../org/eclipse/jetty/http/HttpParser.java | 20 ++++++++++++++----- .../http/HttpGeneratorServerHTTPTest.java | 17 ++++++++-------- .../eclipse/jetty/http/HttpParserTest.java | 9 +++++---- .../org/eclipse/jetty/http/HttpTester.java | 4 ++-- .../http2/server/HttpChannelOverHTTP2.java | 8 ++++---- .../org/eclipse/jetty/server/HttpChannel.java | 14 +++++++------ .../jetty/server/HttpChannelOverHttp.java | 8 ++++---- .../eclipse/jetty/server/LocalConnector.java | 5 ----- 12 files changed, 58 insertions(+), 53 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java index b211ed32574..6886a39b230 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java @@ -26,7 +26,7 @@ import org.eclipse.jetty.client.HttpExchange; import org.eclipse.jetty.client.HttpReceiver; import org.eclipse.jetty.client.HttpResponse; import org.eclipse.jetty.client.HttpResponseException; -import org.eclipse.jetty.http.HttpCompliance; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpParser; @@ -325,13 +325,13 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res } @Override - public void badMessage(int status, String reason) + public void badMessage(BadMessageException failure) { HttpExchange exchange = getHttpExchange(); if (exchange != null) { HttpResponse response = exchange.getResponse(); - response.status(status).reason(reason); + response.status(failure.getCode()).reason(failure.getReason()); failAndClose(new HttpResponseException("HTTP protocol violation: bad response on " + getHttpConnection(), response)); } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java index e5bcef5e9ed..220408a58fa 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java @@ -18,8 +18,6 @@ package org.eclipse.jetty.client; -import static org.junit.Assert.assertThat; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -1297,8 +1295,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest } catch(ExecutionException e) { - assertThat(e.getCause(), Matchers.instanceOf(BadMessageException.class)); - assertThat(e.getCause().getMessage(), Matchers.containsString("Unknown content")); + Assert.assertThat(e.getCause(), Matchers.instanceOf(BadMessageException.class)); + Assert.assertThat(e.getCause().getMessage(), Matchers.containsString("Unknown content")); } } @@ -1311,8 +1309,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest } catch(ExecutionException e) { - assertThat(e.getCause(), Matchers.instanceOf(BadMessageException.class)); - assertThat(e.getCause().getMessage(), Matchers.containsString("Unknown content")); + Assert.assertThat(e.getCause(), Matchers.instanceOf(BadMessageException.class)); + Assert.assertThat(e.getCause().getMessage(), Matchers.containsString("Unknown content")); } } diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java index f6b970b2f4d..e70d603c6c2 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java @@ -305,9 +305,9 @@ public class ResponseContentParser extends StreamContentParser } @Override - public void badMessage(int status, String reason) + public void badMessage(BadMessageException failure) { - fail(new BadMessageException(status, reason)); + fail(failure); } protected void fail(Throwable failure) diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java index 3c2d55b78d9..a9e7d4fc329 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnection.java @@ -25,7 +25,9 @@ import java.util.concurrent.ConcurrentMap; import org.eclipse.jetty.fcgi.FCGI; import org.eclipse.jetty.fcgi.generator.Flusher; import org.eclipse.jetty.fcgi.parser.ServerParser; +import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.AbstractConnection; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; @@ -187,9 +189,7 @@ public class ServerFCGIConnection extends AbstractConnection if (LOG.isDebugEnabled()) LOG.debug("Request {} failure on {}: {}", request, channel, failure); if (channel != null) - { - channel.onBadMessage(400, failure.toString()); - } + channel.onBadMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400, null, failure)); } } } 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 fdbab907d06..d6884effcdf 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 @@ -1499,7 +1499,7 @@ public class HttpParser if (DEBUG) LOG.debug("{} EOF in {}",this,_state); setState(State.CLOSED); - _handler.badMessage(HttpStatus.BAD_REQUEST_400,null); + _handler.badMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400)); break; } } @@ -1525,7 +1525,7 @@ public class HttpParser if (_headerComplete) _handler.earlyEOF(); else - _handler.badMessage(x._code, x._reason); + _handler.badMessage(x); } protected boolean parseContent(ByteBuffer buffer) @@ -1804,10 +1804,20 @@ public class HttpParser /* ------------------------------------------------------------ */ /** Called to signal that a bad HTTP message has been received. - * @param status The bad status to send - * @param reason The textual reason for badness + * @param failure the failure with the bad message information */ - public void badMessage(int status, String reason); + public default void badMessage(BadMessageException failure) + { + badMessage(failure.getCode(), failure.getReason()); + } + + /** + * @deprecated use {@link #badMessage(BadMessageException)} instead + */ + @Deprecated + public default void badMessage(int status, String reason) + { + } /* ------------------------------------------------------------ */ /** @return the size in bytes of the per parser header cache diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java index 6f1d21eb8e5..e071a362d7b 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java @@ -18,13 +18,6 @@ package org.eclipse.jetty.http; -import static org.hamcrest.Matchers.either; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; @@ -38,6 +31,12 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; +import static org.hamcrest.Matchers.either; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + @RunWith(Parameterized.class) public class HttpGeneratorServerHTTPTest { @@ -261,9 +260,9 @@ public class HttpGeneratorServerHTTPTest } @Override - public void badMessage(int status, String reason) + public void badMessage(BadMessageException failure) { - throw new IllegalStateException(reason); + throw failure; } @Override diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index 98e1f9a9044..c6a428b8571 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -18,8 +18,6 @@ package org.eclipse.jetty.http; -import static org.hamcrest.Matchers.contains; - import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -34,6 +32,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import static org.hamcrest.Matchers.contains; + public class HttpParserTest { static @@ -2201,9 +2201,10 @@ public class HttpParserTest } @Override - public void badMessage(int status, String reason) + public void badMessage(BadMessageException failure) { - _bad = reason == null ? ("" + status) : reason; + String reason = failure.getReason(); + _bad = reason == null ? String.valueOf(failure.getCode()) : reason; } @Override diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java index 2d713f04509..60d5a50c06e 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTester.java @@ -408,9 +408,9 @@ public class HttpTester } @Override - public void badMessage(int status, String reason) + public void badMessage(BadMessageException failure) { - throw new RuntimeException(reason); + throw failure; } public ByteBuffer generate() diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index 007976d24b6..bfbe7c56195 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -145,12 +145,12 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ } catch (BadMessageException x) { - onBadMessage(x.getCode(), x.getReason()); + onBadMessage(x); return null; } catch (Throwable x) { - onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null); + onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); return null; } } @@ -177,12 +177,12 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ } catch (BadMessageException x) { - onBadMessage(x.getCode(), x.getReason()); + onBadMessage(x); return null; } catch (Throwable x) { - onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null); + onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); return null; } } 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 c523b4a9108..df4dcebe050 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 @@ -707,12 +707,14 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor return _request.getHttpInput().earlyEOF(); } - public void onBadMessage(int status, String reason) + public void onBadMessage(BadMessageException failure) { + int status = failure.getCode(); + String reason = failure.getReason(); if (status < 400 || status > 599) - status = HttpStatus.BAD_REQUEST_400; + failure = new BadMessageException(HttpStatus.BAD_REQUEST_400, reason, failure); - notifyRequestFailure(_request, new BadMessageException(status, reason)); + notifyRequestFailure(_request, failure); Action action; try @@ -721,10 +723,10 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor } catch(IllegalStateException e) { - // The bad message cannot be handled in the current state, so throw - // to hopefull somebody that can handle + // The bad message cannot be handled in the current state, + // so rethrow, hopefully somebody will be able to handle. abort(e); - throw new BadMessageException(status,reason); + throw failure; } try diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java index 2a5e0c70d0e..79f0a8d7ea0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelOverHttp.java @@ -269,7 +269,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque } @Override - public void badMessage(int status, String reason) + public void badMessage(BadMessageException failure) { _httpConnection.getGenerator().setPersistent(false); try @@ -283,7 +283,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque LOG.ignore(e); } - onBadMessage(status, reason); + onBadMessage(failure); } @Override @@ -333,7 +333,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque { if (_unknownExpectation) { - badMessage(HttpStatus.EXPECTATION_FAILED_417, null); + badMessage(new BadMessageException(HttpStatus.EXPECTATION_FAILED_417)); return false; } @@ -374,7 +374,7 @@ public class HttpChannelOverHttp extends HttpChannel implements HttpParser.Reque upgrade()) return true; - badMessage(HttpStatus.UPGRADE_REQUIRED_426, null); + badMessage(new BadMessageException(HttpStatus.UPGRADE_REQUIRED_426)); _httpConnection.getParser().close(); return false; } 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 3a0dfccfad4..5914ae725d4 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 @@ -471,11 +471,6 @@ public class LocalConnector extends AbstractConnector return false; } - @Override - public void badMessage(int status, String reason) - { - } - @Override public boolean startResponse(HttpVersion version, int status, String reason) { From d3120ee2122f4ed6984e0193552049b7a93810f0 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 12 Mar 2018 14:29:10 -0500 Subject: [PATCH 31/87] Issue #2307 - On sendError() the response character encoding is null + Added testcase to replicate + Making character encoding from unset during sendError Signed-off-by: Joakim Erdfelt --- .../org/eclipse/jetty/server/Response.java | 1 + .../jetty/server/ErrorHandlerTest.java | 62 +++++++++++++++---- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index 9f7f00aff17..c35dae1f609 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -621,6 +621,7 @@ public class Response implements HttpServletResponse _mimeType=null; _characterEncoding=null; + _encodingFrom = EncodingFrom.NOT_SET; _outputType = OutputType.NONE; setHeader(HttpHeader.EXPIRES,null); setHeader(HttpHeader.LAST_MODIFIED,null); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java index eff49a97385..64a3f9b8087 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java @@ -19,30 +19,34 @@ package org.eclipse.jetty.server; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; import java.io.IOException; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpTester; +import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ErrorHandler; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.junit.After; -import org.junit.Before; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runner.RunWith; -@RunWith(AdvancedRunner.class) public class ErrorHandlerTest { - Server server; - LocalConnector connector; + static Server server; + static LocalConnector connector; - @Before - public void before() throws Exception + @BeforeClass + public static void before() throws Exception { server = new Server(); connector = new LocalConnector(server); @@ -72,17 +76,36 @@ public class ErrorHandlerTest .append("}"); break; } + case "text/plain": + { + baseRequest.setHandled(true); + response.setContentType("text/plain"); + response.getOutputStream().print(response.getContentType()); + break; + } default: super.generateAcceptableResponse(baseRequest,request,response,code,message,mimeType); } } }); + server.setHandler(new AbstractHandler() + { + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + if(target.startsWith("/charencoding/")) + { + response.setCharacterEncoding("utf-8"); + response.sendError(404); + } + } + }); server.start(); } - @After - public void after() throws Exception + @AfterClass + public static void after() throws Exception { server.stop(); } @@ -260,4 +283,19 @@ public class ErrorHandlerTest assertThat(response,containsString("Content-Type: text/json")); } + @Test + public void testCharEncoding() throws Exception + { + String rawResponse = connector.getResponse( + "GET /charencoding/foo HTTP/1.1\r\n"+ + "Host: Localhost\r\n"+ + "Accept: text/plain\r\n"+ + "\r\n"); + HttpTester.Response response = HttpTester.parseResponse(rawResponse); + + assertThat("Response status code", response.getStatus(), is(404)); + HttpField contentType = response.getField(HttpHeader.CONTENT_TYPE); + assertThat("Response Content-Type", contentType, is(notNullValue())); + assertThat("Response Content-Type value", contentType.getValue(), not(containsString("null"))); + } } From 0361cf6cd36739f72425e0ff7ac9c0016ff4e27a Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 12 Mar 2018 16:33:39 -0500 Subject: [PATCH 32/87] Simplifying testcase, relying on flush not sleep. --- .../websocket/server/ab/TestABCase6.java | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java index f8eef39cc37..1dd84d3ca28 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.server.ab; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; @@ -278,20 +277,24 @@ public class TestABCase6 extends AbstractABCase byte part2[] = Hex.asByteArray("F4908080"); // invalid byte part3[] = StringUtil.getUtf8Bytes("edited"); + ByteBuffer b1 = ByteBuffer.wrap(part1); + ByteBuffer b2 = ByteBuffer.wrap(part2); + ByteBuffer b3 = ByteBuffer.wrap(part3); + + List send = new ArrayList<>(); + send.add(new TextFrame().setPayload(b1).setFin(false)); + send.add(new ContinuationFrame().setPayload(b2).setFin(true)); + send.add(new ContinuationFrame().setPayload(b3).setFin(true)); + send.add(new CloseInfo(StatusCode.NORMAL).asFrame()); + List expect = new ArrayList<>(); expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame()); try (Fuzzer fuzzer = new Fuzzer(this)) { fuzzer.connect(); - fuzzer.setSendMode(Fuzzer.SendMode.BULK); - - fuzzer.send(new TextFrame().setPayload(ByteBuffer.wrap(part1)).setFin(false)); - TimeUnit.SECONDS.sleep(1); - fuzzer.send(new ContinuationFrame().setPayload(ByteBuffer.wrap(part2)).setFin(false)); - TimeUnit.SECONDS.sleep(1); - fuzzer.send(new ContinuationFrame().setPayload(ByteBuffer.wrap(part3)).setFin(true)); - + fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME); + fuzzer.send(send); fuzzer.expect(expect); } } @@ -313,18 +316,24 @@ public class TestABCase6 extends AbstractABCase byte part2[] = Hex.asByteArray("90"); // continue code point & invalid byte part3[] = Hex.asByteArray("8080656469746564"); // continue code point & finish + ByteBuffer b1 = ByteBuffer.wrap(part1); + ByteBuffer b2 = ByteBuffer.wrap(part2); + ByteBuffer b3 = ByteBuffer.wrap(part3); + + List send = new ArrayList<>(); + send.add(new TextFrame().setPayload(b1).setFin(false)); + send.add(new ContinuationFrame().setPayload(b2).setFin(true)); + send.add(new ContinuationFrame().setPayload(b3).setFin(true)); + send.add(new CloseInfo(StatusCode.NORMAL).asFrame()); + List expect = new ArrayList<>(); expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame()); try (Fuzzer fuzzer = new Fuzzer(this)) { fuzzer.connect(); - fuzzer.setSendMode(Fuzzer.SendMode.BULK); - fuzzer.send(new TextFrame().setPayload(ByteBuffer.wrap(part1)).setFin(false)); - TimeUnit.SECONDS.sleep(1); - fuzzer.send(new ContinuationFrame().setPayload(ByteBuffer.wrap(part2)).setFin(false)); - TimeUnit.SECONDS.sleep(1); - fuzzer.send(new ContinuationFrame().setPayload(ByteBuffer.wrap(part3)).setFin(true)); + fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME); + fuzzer.send(send); fuzzer.expect(expect); } } @@ -371,9 +380,7 @@ public class TestABCase6 extends AbstractABCase part3.limit(splits[2]); fuzzer.send(part1); // the header + good utf - TimeUnit.MILLISECONDS.sleep(500); fuzzer.send(part2); // the bad UTF - TimeUnit.MILLISECONDS.sleep(500); fuzzer.send(part3); // the rest (shouldn't work) fuzzer.expect(expect); @@ -404,9 +411,7 @@ public class TestABCase6 extends AbstractABCase ByteBuffer net = fuzzer.asNetworkBuffer(send); fuzzer.send(net,6); fuzzer.send(net,11); - TimeUnit.SECONDS.sleep(1); fuzzer.send(net,1); - TimeUnit.SECONDS.sleep(1); fuzzer.send(net,100); // the rest fuzzer.expect(expect); From dcfa6f0f380f5545c4e48ae3f70bae4e0ee6b0a3 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 12 Mar 2018 17:33:58 -0500 Subject: [PATCH 33/87] Issue #2307 - applying changes from review Signed-off-by: Joakim Erdfelt --- .../src/main/java/org/eclipse/jetty/server/Response.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index c35dae1f609..301081e2d70 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -619,10 +619,9 @@ public class Response implements HttpServletResponse } - _mimeType=null; - _characterEncoding=null; - _encodingFrom = EncodingFrom.NOT_SET; _outputType = OutputType.NONE; + setContentType(null); + setCharacterEncoding(null); setHeader(HttpHeader.EXPIRES,null); setHeader(HttpHeader.LAST_MODIFIED,null); setHeader(HttpHeader.CACHE_CONTROL,null); From 915af401e1471242b5f3a087d906618145880e9d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 13 Mar 2018 13:22:01 +1100 Subject: [PATCH 34/87] HttpParser cleanup #2232 Signed-off-by: Greg Wilkins --- .../org/eclipse/jetty/http/HttpParser.java | 207 +++++++++--------- .../eclipse/jetty/http/HttpParserTest.java | 17 +- 2 files changed, 119 insertions(+), 105 deletions(-) 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 fdbab907d06..ddff6e12dba 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 @@ -36,6 +36,7 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN; +import static org.eclipse.jetty.http.HttpTokens.COLON; import static org.eclipse.jetty.http.HttpTokens.LINE_FEED; import static org.eclipse.jetty.http.HttpTokens.SPACE; import static org.eclipse.jetty.http.HttpTokens.TAB; @@ -1074,7 +1075,7 @@ public class HttpParser throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Header Folding"); // header value without name - continuation? - if (_valueString==null) + if (_valueString==null || _valueString.isEmpty()) { _string.setLength(0); _length=0; @@ -1166,10 +1167,6 @@ public class HttpParser default: { - // now handle the ch - if (bHttpTokens.SPACE && b!=HttpTokens.COLON) + switch(b) { - if (_header!=null) - { - setString(_header.asString()); - _header=null; - _headerString=null; - } - - _string.append((char)b); - _length=_string.length(); - break; - } - - // Fallthrough - - case WS_AFTER_NAME: - if (b==HttpTokens.COLON) - { - if (_headerString==null) - { + case SPACE: + case TAB: + //Ignore trailing whitespaces ? + if (!complianceViolation(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,null)) + { + _headerString=takeString(); + _header=HttpHeader.CACHE.get(_headerString); + _length=-1; + setState(FieldState.WS_AFTER_NAME); + break; + } + throw new IllegalCharacterException(_state,b,buffer); + + case COLON: _headerString=takeString(); _header=HttpHeader.CACHE.get(_headerString); - } - _length=-1; - - setState(FieldState.VALUE); - break; - } - - if (b==HttpTokens.LINE_FEED) - { - if (_headerString==null) - { - _headerString=takeString(); - _header=HttpHeader.CACHE.get(_headerString); - } - _string.setLength(0); - _valueString=""; - _length=-1; - - if (!complianceViolation(HttpComplianceSection.FIELD_COLON,_headerString)) - { - setState(FieldState.FIELD); + _length=-1; + setState(FieldState.VALUE); break; - } - } + + case LINE_FEED: + _headerString=takeString(); + _header=HttpHeader.CACHE.get(_headerString); + _string.setLength(0); + _valueString=""; + _length=-1; - //Ignore trailing whitespaces - if (b==HttpTokens.SPACE && !complianceViolation(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,null)) + if (!complianceViolation(HttpComplianceSection.FIELD_COLON,_headerString)) + { + setState(FieldState.FIELD); + break; + } + throw new IllegalCharacterException(_state,b,buffer); + + default: + if (b<0) + throw new IllegalCharacterException(_state,b,buffer); + + _string.append((char)b); + _length=_string.length(); + break; + } + break; + + case WS_AFTER_NAME: + + switch(b) { - setState(FieldState.WS_AFTER_NAME); - break; - } + case SPACE: + case TAB: + break; - throw new IllegalCharacterException(_state,b,buffer); + case COLON: + setState(FieldState.VALUE); + break; + + case LINE_FEED: + if (!complianceViolation(HttpComplianceSection.FIELD_COLON,_headerString)) + { + setState(FieldState.FIELD); + break; + } + throw new IllegalCharacterException(_state,b,buffer); + + default: + throw new IllegalCharacterException(_state,b,buffer); + } + break; case VALUE: - if (b>HttpTokens.SPACE || b<0) + switch(b) { - _string.append((char)(0xff&b)); - _length=_string.length(); - setState(FieldState.IN_VALUE); - break; - } - - if (b==HttpTokens.SPACE || b==HttpTokens.TAB) - break; - - if (b==HttpTokens.LINE_FEED) - { - _string.setLength(0); - _valueString=""; - _length=-1; - - setState(FieldState.FIELD); - break; - } - throw new IllegalCharacterException(_state,b,buffer); - - case IN_VALUE: - if (b>=HttpTokens.SPACE || b<0 || b==HttpTokens.TAB) - { - if (_valueString!=null) - { - setString(_valueString); - _valueString=null; - _field=null; - } - _string.append((char)(0xff&b)); - if (b>HttpTokens.SPACE || b<0) - _length=_string.length(); - break; - } - - if (b==HttpTokens.LINE_FEED) - { - if (_length > 0) - { - _valueString=takeString(); + case LINE_FEED: + _string.setLength(0); + _valueString=""; _length=-1; - } - setState(FieldState.FIELD); + + setState(FieldState.FIELD); + break; + + case SPACE: + case TAB: + break; + + default: + _string.append((char)(0xff&b)); + _length=_string.length(); + setState(FieldState.IN_VALUE); break; } - - throw new IllegalCharacterException(_state,b,buffer); - + break; + + case IN_VALUE: + switch(b) + { + case LINE_FEED: + if (_length > 0) + { + _valueString=takeString(); + _length=-1; + } + setState(FieldState.FIELD); + break; + + case SPACE: + case TAB: + _string.append((char)(0xff&b)); + break; + + default: + _string.append((char)(0xff&b)); + _length=_string.length(); + break; + } + break; + default: throw new IllegalStateException(_state.toString()); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index 98e1f9a9044..e4d95a2eb89 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.http; +import static org.eclipse.jetty.http.HttpComplianceSection.NO_FIELD_FOLDING; import static org.hamcrest.Matchers.contains; import java.nio.ByteBuffer; @@ -261,6 +262,8 @@ public class HttpParserTest "Host: localhost\r\n" + "Name: value\r\n" + " extra\r\n" + + "Name2: \r\n" + + "\tvalue2\r\n" + "\r\n"); HttpParser.RequestHandler handler = new Handler(); @@ -270,10 +273,12 @@ public class HttpParserTest Assert.assertThat(_bad, Matchers.nullValue()); Assert.assertEquals("Host", _hdr[0]); Assert.assertEquals("localhost", _val[0]); + Assert.assertEquals(2, _headers); Assert.assertEquals("Name", _hdr[1]); Assert.assertEquals("value extra", _val[1]); - Assert.assertEquals(1, _headers); - Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_FIELD_FOLDING)); + Assert.assertEquals("Name2", _hdr[2]); + Assert.assertEquals("value2", _val[2]); + Assert.assertThat(_complianceViolation, contains(NO_FIELD_FOLDING,NO_FIELD_FOLDING)); } @Test @@ -399,7 +404,7 @@ public class HttpParserTest ByteBuffer buffer = BufferUtil.toBuffer( "HTTP/1.1 204 No Content\r\n" + "Access-Control-Allow-Headers : Origin\r\n" + - "Other: value\r\n" + + "Other\t : value\r\n" + "\r\n"); HttpParser.ResponseHandler handler = new Handler(); @@ -422,7 +427,7 @@ public class HttpParserTest Assert.assertEquals("Other", _hdr[1]); Assert.assertEquals("value", _val[1]); - Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME)); + Assert.assertThat(_complianceViolation, contains(HttpComplianceSection.NO_WS_AFTER_FIELD_NAME,HttpComplianceSection.NO_WS_AFTER_FIELD_NAME)); } @Test @@ -709,7 +714,9 @@ public class HttpParserTest public void testBadHeaderEncoding() throws Exception { ByteBuffer buffer = BufferUtil.toBuffer( - "GET / HTTP/1.0\r\nH\u00e6der0: value0\r\n\n\n"); + "GET / HTTP/1.0\r\n" + + "H\u00e6der0: value0\r\n" + + "\n\n"); HttpParser.RequestHandler handler = new Handler(); HttpParser parser = new HttpParser(handler); From 74f5b9898fbb122867752a8bdb635a9e0e12a8f6 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 13 Mar 2018 13:42:35 +1100 Subject: [PATCH 35/87] simplified testSelectorWakeup #2219 Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/io/IOTest.java | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java index c43b13aa82c..21e96e4d3aa 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java @@ -514,40 +514,28 @@ public class IOTest assertThat(key,notNullValue()); assertThat(selector.selectNow(), is(0)); - client.write(BufferUtil.toBuffer("X")); - assertThat(selector.select(), is(1)); - assertThat(key.readyOps(), is(SelectionKey.OP_READ)); - assertThat(selector.selectedKeys(), Matchers.contains(key)); - - assertThat(selector.select(), is(0)); - assertThat(key.readyOps(), is(SelectionKey.OP_READ)); - assertThat(selector.selectedKeys(), Matchers.contains(key)); - - client.write(BufferUtil.toBuffer("X")); - selector.selectedKeys().clear(); - assertThat(selector.select(), is(1)); - assertThat(key.readyOps(), is(SelectionKey.OP_READ)); - assertThat(selector.selectedKeys(), Matchers.contains(key)); - - ByteBuffer buf = BufferUtil.allocate(1024); - int p = BufferUtil.flipToFill(buf); - assertThat(server.read(buf),is(2)); - BufferUtil.flipToFlush(buf,p); - + // Test wakeup before select selector.wakeup(); - selector.selectedKeys().clear(); assertThat(selector.select(), is(0)); - assertThat(selector.selectedKeys().size(),is(0)); - client.write(BufferUtil.toBuffer("X")); - selector.wakeup(); - selector.selectedKeys().clear(); - assertThat(selector.select(), is(1)); - assertThat(selector.selectedKeys().size(),is(1)); - - p = BufferUtil.flipToFill(buf); - assertThat(server.read(buf),is(1)); - BufferUtil.flipToFlush(buf,p); - + // Test wakeup after select + new Thread() + { + @Override + public void run() + { + try + { + Thread.sleep(100); + selector.wakeup(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + }.start(); + assertThat(selector.select(), is(0)); } } From a9334560890aa20c5456a2071b7fd2d9603f6955 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 13 Mar 2018 14:07:37 +1100 Subject: [PATCH 36/87] update etags for all methods #1416 Signed-off-by: Greg Wilkins --- .../server/handler/gzip/GzipHandler.java | 44 ++++++++-------- .../server/handler/gzip/GzipHandlerTest.java | 42 ---------------- .../jetty/servlet/GzipHandlerTest.java | 50 ++++++++++++++++++- 3 files changed, 71 insertions(+), 65 deletions(-) delete mode 100644 jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java index 62ca8ffb532..bf073a6188c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java @@ -448,6 +448,28 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory interceptor=interceptor.getNextInterceptor(); } + // Special handling for etags + for (ListIterator fields = baseRequest.getHttpFields().listIterator(); fields.hasNext();) + { + HttpField field = fields.next(); + if (field.getHeader()==HttpHeader.IF_NONE_MATCH || field.getHeader()==HttpHeader.IF_MATCH) + { + String etag = field.getValue(); + int i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote); + if (i>0) + { + baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag",etag); + while (i>=0) + { + etag=etag.substring(0,i)+etag.substring(i+CompressedContentFormat.GZIP._etag.length()); + i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote,i); + } + + fields.set(new HttpField(field.getHeader(),etag)); + } + } + } + // If not a supported method - no Vary because no matter what client, this URI is always excluded if (!_methods.test(baseRequest.getMethod())) { @@ -494,28 +516,6 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } } } - - // Special handling for etags - for (ListIterator fields = baseRequest.getHttpFields().listIterator(); fields.hasNext();) - { - HttpField field = fields.next(); - if (field.getHeader()==HttpHeader.IF_NONE_MATCH || field.getHeader()==HttpHeader.IF_MATCH) - { - String etag = field.getValue(); - int i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote); - if (i>0) - { - baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag",etag); - while (i>=0) - { - etag=etag.substring(0,i)+etag.substring(i+CompressedContentFormat.GZIP._etag.length()); - i=etag.indexOf(CompressedContentFormat.GZIP._etagQuote,i); - } - - fields.set(new HttpField(field.getHeader(),etag)); - } - } - } HttpOutput.Interceptor orig_interceptor = out.getInterceptor(); try diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java deleted file mode 100644 index 53b90198bf0..00000000000 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.handler.gzip; - -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import java.util.Arrays; - -import org.junit.Test; - -public class GzipHandlerTest -{ - @Test - public void testAddGetPaths() - { - GzipHandler gzip = new GzipHandler(); - gzip.addIncludedPaths("/foo"); - gzip.addIncludedPaths("^/bar.*$"); - - String[] includedPaths = gzip.getIncludedPaths(); - assertThat("Included Paths.size", includedPaths.length, is(2)); - assertThat("Included Paths", Arrays.asList(includedPaths), contains("/foo","^/bar.*$")); - } -} diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java index fdf20d9e8bc..fd67f91eaa3 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java @@ -47,13 +47,13 @@ import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.gzip.GzipHandler; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Before; import org.junit.Test; +@SuppressWarnings("serial") public class GzipHandlerTest { private static final String __content = @@ -151,6 +151,17 @@ public class GzipHandlerTest writer.write(__content); } } + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException + { + String ifm = req.getHeader("If-Match"); + if (ifm!=null && ifm.equals(__contentETag)) + response.sendError(HttpServletResponse.SC_NO_CONTENT); + else + response.sendError(HttpServletResponse.SC_NOT_MODIFIED); + } + } public static class EchoServlet extends HttpServlet @@ -347,6 +358,43 @@ public class GzipHandlerTest assertThat(response.get("ETag"),is(__contentETagGzip)); } + + @Test + public void testDeleteETagGzipHandler() throws Exception + { + HttpTester.Request request = HttpTester.newRequest(); + HttpTester.Response response; + + request.setMethod("DELETE"); + request.setURI("/ctx/content"); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setHeader("If-Match","WrongEtag--gzip"); + request.setHeader("accept-encoding","gzip"); + + response = HttpTester.parseResponse(_connector.getResponse(request.generate())); + + assertThat(response.getStatus(),is(HttpServletResponse.SC_NOT_MODIFIED)); + assertThat(response.get("Content-Encoding"),not(Matchers.equalToIgnoringCase("gzip"))); + + + request = HttpTester.newRequest(); + request.setMethod("DELETE"); + request.setURI("/ctx/content"); + request.setVersion("HTTP/1.0"); + request.setHeader("Host","tester"); + request.setHeader("If-Match",__contentETagGzip); + request.setHeader("accept-encoding","gzip"); + + response = HttpTester.parseResponse(_connector.getResponse(request.generate())); + + assertThat(response.getStatus(),is(HttpServletResponse.SC_NO_CONTENT)); + assertThat(response.get("Content-Encoding"),not(Matchers.equalToIgnoringCase("gzip"))); + } + + + + @Test public void testForwardGzipHandler() throws Exception { From be1a011120df75526b9c0f3a145628a3ea976071 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 13 Mar 2018 14:26:52 +1100 Subject: [PATCH 37/87] more robust test Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/io/IdleTimeoutTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java index 0780c0cad0d..c35ec08d144 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java @@ -120,17 +120,19 @@ public class IdleTimeoutTest @Test public void testShorten() throws Exception - { - for (int i=0;i<20;i++) + { + _timeout.setIdleTimeout(2000); + + for (int i=0;i<30;i++) { - Thread.sleep(200); + Thread.sleep(100); _timeout.notIdle(); } Assert.assertNull(_expired); _timeout.setIdleTimeout(100); long start = System.nanoTime(); - while (_expired==null && TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()-start)<4) + while (_expired==null && TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()-start)<5) Thread.sleep(200); Assert.assertNotNull(_expired); From f35bd038106448f30d7b46b6c4eda933f5e900e0 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 13 Mar 2018 16:15:28 +1100 Subject: [PATCH 38/87] Speculative fix for #2233 Signed-off-by: Greg Wilkins --- .../main/java/org/eclipse/jetty/io/ssl/SslConnection.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java index 67a5fc36439..1ac15fe0ce1 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java @@ -527,12 +527,10 @@ public class SslConnection extends AbstractConnection // don't bother writing, just notify of close getWriteFlusher().onClose(); } - // Else, else { - // try to flush what is pending - // execute to avoid recursion - getExecutor().execute(_runCompleteWrite); + // Try again + _runCompleteWrite.run(); } } } From aafda1a279573d07eb084185ff0dcc793c9d0b15 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 13 Mar 2018 14:24:37 -0500 Subject: [PATCH 39/87] Issue #2280 - adding default utf-8 encoding to application/json --- .../main/resources/org/eclipse/jetty/http/encoding.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties b/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties index e8b1d7bdc02..3f2d2dd358e 100644 --- a/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties +++ b/jetty-http/src/main/resources/org/eclipse/jetty/http/encoding.properties @@ -1,11 +1,12 @@ # Mapping of mime type to inferred or assumed charset # inferred charsets are used for encoding/decoding and explicitly set in associated metadata # assumed charsets are used for encoding/decoding, but are not set in associated metadata -# In this file, assumed charsets are indicatd with a leading '-' +# In this file, assumed charsets are indicated with a leading '-' text/html=utf-8 text/plain=iso-8859-1 text/xml=utf-8 application/xhtml+xml=utf-8 text/json=-utf-8 +application/json=-utf-8 application/vnd.api+json=-utf-8 \ No newline at end of file From f9658f06b5a1aecc2732ab3fbdd45f36138f5b16 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 13 Mar 2018 14:35:24 -0500 Subject: [PATCH 40/87] Issue #2139 - updating all DTD references to to configure_9_3.dtd Signed-off-by: Joakim Erdfelt --- .../modules/global-webapp-common.d/global-webapp-common.xml | 2 +- .../jetty-simple-webapp/src/base/etc/test-jetty.xml | 2 +- .../jetty-simple-webapp/src/config/jetty.xml | 2 +- .../jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml | 2 +- .../jetty-simple-webapp/src/config/jetty.xml | 2 +- .../jetty-simple-webapp/src/config/jetty.xml | 2 +- .../jetty-simple-webapp/src/config/jetty.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml b/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml index 5eee32ec2ac..aa3d308bbf7 100644 --- a/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml +++ b/jetty-deploy/src/main/config/modules/global-webapp-common.d/global-webapp-common.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml index fbdc1a01394..5062d20c4fc 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/etc/test-jetty.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml index 0b843c05a99..c38bcced0e1 100644 --- a/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-run-forked-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml index 0b843c05a99..c38bcced0e1 100644 --- a/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-run-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml index 0b843c05a99..c38bcced0e1 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-run-war-exploded-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml index 0b843c05a99..c38bcced0e1 100644 --- a/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-run-war-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -1,5 +1,5 @@ - + diff --git a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml index 0b843c05a99..c38bcced0e1 100644 --- a/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml +++ b/jetty-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -1,5 +1,5 @@ - + From a634b571b3f80c3ea5ee4c3e938cc5ef12874f8e Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2018 08:27:43 +1100 Subject: [PATCH 41/87] Improved include handling of trailing / #2275 Signed-off-by: Greg Wilkins --- .../main/java/org/eclipse/jetty/server/ResourceService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java index 6031375d5c5..f95402276ea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java @@ -225,7 +225,7 @@ public class ResourceService String pathInContext=URIUtil.addPaths(servletPath,pathInfo); - boolean endsWithSlash=(pathInfo==null?request.getServletPath():pathInfo).endsWith(URIUtil.SLASH); + boolean endsWithSlash=(pathInfo==null?servletPath:pathInfo).endsWith(URIUtil.SLASH); boolean checkPrecompressedVariants=_precompressedFormats.length > 0 && !endsWithSlash && !included && reqRanges==null; HttpContent content=null; @@ -254,7 +254,7 @@ public class ResourceService } // Strip slash? - if (endsWithSlash && pathInContext.length()>1) + if (!included && endsWithSlash && pathInContext.length()>1) { String q=request.getQueryString(); pathInContext=pathInContext.substring(0,pathInContext.length()-1); From 5524c7e67e85f78df7f78567712398667e1bbc03 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2018 09:42:22 +1100 Subject: [PATCH 42/87] removed unused jetty-monitor #2308 Signed-off-by: Greg Wilkins --- jetty-monitor/README.TXT | 13 - jetty-monitor/pom.xml | 84 --- .../src/main/config/etc/jetty-monitor.xml | 30 - .../src/main/config/modules/monitor.mod | 13 - .../org/eclipse/jetty/monitor/JMXMonitor.java | 193 ------ .../eclipse/jetty/monitor/ThreadMonitor.java | 610 ------------------ .../integration/JavaMonitorAction.java | 409 ------------ .../monitor/integration/JavaMonitorTools.java | 288 --------- .../integration/JavaMonitorTrigger.java | 74 --- .../monitor/integration/package-info.java | 23 - .../jetty/monitor/jmx/ConsoleNotifier.java | 61 -- .../jetty/monitor/jmx/EventNotifier.java | 40 -- .../eclipse/jetty/monitor/jmx/EventState.java | 209 ------ .../jetty/monitor/jmx/EventTrigger.java | 76 --- .../jetty/monitor/jmx/LoggingNotifier.java | 65 -- .../jetty/monitor/jmx/MonitorAction.java | 179 ----- .../jetty/monitor/jmx/MonitorTask.java | 119 ---- .../jetty/monitor/jmx/NotifierGroup.java | 119 ---- .../jetty/monitor/jmx/ServiceConnection.java | 172 ----- .../jetty/monitor/jmx/SimpleAction.java | 46 -- .../jetty/monitor/jmx/package-info.java | 23 - .../eclipse/jetty/monitor/package-info.java | 23 - .../thread/ThreadMonitorException.java | 34 - .../monitor/thread/ThreadMonitorInfo.java | 202 ------ .../jetty/monitor/thread/package-info.java | 23 - .../triggers/AggregateEventTrigger.java | 159 ----- .../monitor/triggers/AndEventTrigger.java | 134 ---- .../monitor/triggers/AttrEventTrigger.java | 240 ------- .../triggers/EqualToAttrEventTrigger.java | 89 --- .../triggers/GreaterThanAttrEventTrigger.java | 90 --- .../GreaterThanOrEqualToAttrEventTrigger.java | 90 --- .../triggers/LessThanAttrEventTrigger.java | 90 --- .../LessThanOrEqualToAttrEventTrigger.java | 91 --- .../monitor/triggers/OrEventTrigger.java | 138 ---- .../triggers/RangeAttrEventTrigger.java | 99 --- .../triggers/RangeInclAttrEventTrigger.java | 99 --- .../jetty/monitor/triggers/package-info.java | 23 - .../jetty/monitor/AttrEventTriggerTest.java | 526 --------------- .../eclipse/jetty/monitor/RequestCounter.java | 48 -- .../jetty/monitor/ThreadMonitorTest.java | 165 ----- .../test/resources/jetty-logging.properties | 3 - 41 files changed, 5212 deletions(-) delete mode 100644 jetty-monitor/README.TXT delete mode 100644 jetty-monitor/pom.xml delete mode 100644 jetty-monitor/src/main/config/etc/jetty-monitor.xml delete mode 100644 jetty-monitor/src/main/config/modules/monitor.mod delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java delete mode 100644 jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java delete mode 100644 jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java delete mode 100644 jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java delete mode 100644 jetty-monitor/src/test/resources/jetty-logging.properties diff --git a/jetty-monitor/README.TXT b/jetty-monitor/README.TXT deleted file mode 100644 index 72c7da114f9..00000000000 --- a/jetty-monitor/README.TXT +++ /dev/null @@ -1,13 +0,0 @@ -The ThreadMonitor is distributed as part of the jetty-monitor module. - -In order to start ThreadMonitor when server starts up, the following command line should be used. - - java -jar start.jar OPTIONS=monitor jetty-monitor.xml - -To run ThreadMonitor on a Jetty installation that doesn't include jetty-monitor module, the jetty-monitor-[version].jar file needs to be copied into ${jetty.home}/lib/ext directory, and jetty-monitor.xml configuration file needs to be copied into ${jetty.home}/etc directory. Subsequently, the following command line should be used. - - java -jar start.jar etc/jetty-monitor.xml - -If running Jetty on Java VM version 1.5, the -Dcom.sun.management.jmxremote option should be added to the command lines above in order to enable the JMX agent. - -In order to log CPU utilization for threads that are above specified threshold, you need to follow instructions inside jetty-monitor.xml configuration file. \ No newline at end of file diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml deleted file mode 100644 index 3374ec2e9e0..00000000000 --- a/jetty-monitor/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - org.eclipse.jetty - jetty-project - 9.4.0-SNAPSHOT - - 4.0.0 - jetty-monitor - Jetty :: Monitoring - http://www.eclipse.org/jetty - Performance monitoring artifact for jetty. - - ${project.groupId}.monitor - - - - - org.apache.maven.plugins - maven-surefire-plugin - - always - - - - org.codehaus.mojo - findbugs-maven-plugin - - org.eclipse.jetty.monitor.* - - - - - - - org.eclipse.jetty - jetty-util - ${project.version} - - - org.eclipse.jetty - jetty-io - ${project.version} - - - org.eclipse.jetty - jetty-http - ${project.version} - - - org.eclipse.jetty - jetty-xml - ${project.version} - - - org.eclipse.jetty - jetty-client - ${project.version} - - - org.eclipse.jetty - jetty-jmx - ${project.version} - test - - - - org.eclipse.jetty - jetty-server - ${project.version} - test - - - org.eclipse.jetty.toolchain - jetty-test-helper - test - - - diff --git a/jetty-monitor/src/main/config/etc/jetty-monitor.xml b/jetty-monitor/src/main/config/etc/jetty-monitor.xml deleted file mode 100644 index a8f663367e4..00000000000 --- a/jetty-monitor/src/main/config/etc/jetty-monitor.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - 2000 - 90 - 3 - 2 - - - - - - - - - - - - - diff --git a/jetty-monitor/src/main/config/modules/monitor.mod b/jetty-monitor/src/main/config/modules/monitor.mod deleted file mode 100644 index f1fa81f98c1..00000000000 --- a/jetty-monitor/src/main/config/modules/monitor.mod +++ /dev/null @@ -1,13 +0,0 @@ -[description] -Enables the Jetty Monitor Module to periodically -check/publish JMX parameters of the server. - -[depend] -server -client - -[lib] -lib/monitor/jetty-monitor-${jetty.version}.jar - -[xml] -etc/jetty-monitor.xml diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java deleted file mode 100644 index 36db34f45f1..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java +++ /dev/null @@ -1,193 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; - -import javax.management.MBeanServerConnection; - -import org.eclipse.jetty.monitor.jmx.MonitorAction; -import org.eclipse.jetty.monitor.jmx.MonitorTask; -import org.eclipse.jetty.monitor.jmx.ServiceConnection; -import org.eclipse.jetty.xml.XmlConfiguration; - -/** - * JMXMonitor - *

    - * Performs monitoring of the values of the attributes of MBeans - * and executes specified actions as well as sends notifications - * of the specified events that have occurred. - */ -public class JMXMonitor -{ - private static JMXMonitor __monitor = new JMXMonitor(); - - private String _serverUrl; - private ServiceConnection _serviceConnection; - - private Set _actions = new HashSet(); - - /* ------------------------------------------------------------ */ - /** - * Constructs a JMXMonitor instance. Used for XML Configuration. - * - * !! DO NOT INSTANTIATE EXPLICITLY !! - */ - public JMXMonitor() {} - - /* ------------------------------------------------------------ */ - /** - * Adds monitor actions to the monitor - * - * @param actions monitor actions to add - * @return true if successful - */ - public boolean addActions(MonitorAction... actions) - { - return getInstance().add(actions); - } - - /* ------------------------------------------------------------ */ - /** - * Removes monitor actions from the monitor - * - * @param actions monitor actions to remove - * @return true if successful - */ - public boolean removeActions(MonitorAction... actions) - { - return getInstance().remove(actions); - } - - /* ------------------------------------------------------------ */ - /** - * Sets the JMX server URL - * - * @param url URL of the JMX server - */ - public void setUrl(String url) - { - getInstance().set(url); - } - - public MBeanServerConnection getConnection() - throws IOException - { - return getInstance().get(); - } - - public static JMXMonitor getInstance() - { - return __monitor; - } - - public static boolean addMonitorActions(MonitorAction... actions) - { - return getInstance().add(actions); - } - - public static boolean removeMonitorActions(MonitorAction... actions) - { - return getInstance().remove(actions); - } - - public static void setServiceUrl(String url) - { - getInstance().set(url); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves a connection to JMX service - * - * @return server connection - * @throws IOException if unable to obtain server connection - */ - public static MBeanServerConnection getServiceConnection() - throws IOException - { - return getInstance().getConnection(); - } - - public static void main(final String args[]) throws Exception - { - XmlConfiguration.main(args); - } - - private synchronized boolean add(MonitorAction... actions) - { - boolean result = true; - - for (MonitorAction action : actions) - { - if (!_actions.add(action)) - { - result = false; - } - else - { - MonitorTask.schedule(action); - } - } - - return result; - } - - private synchronized boolean remove(MonitorAction... actions) - { - boolean result = true; - - for (MonitorAction action : actions) - { - if (!_actions.remove(action)) - { - result = false; - } - - MonitorTask.cancel(action); - } - - return result; - } - - private synchronized void set(String url) - { - _serverUrl = url; - - if (_serviceConnection != null) - { - _serviceConnection.disconnect(); - _serviceConnection = null; - } - } - - private synchronized MBeanServerConnection get() - throws IOException - { - if (_serviceConnection == null) - { - _serviceConnection = new ServiceConnection(_serverUrl); - _serviceConnection.connect(); - } - - return _serviceConnection.getConnection(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java deleted file mode 100644 index 02f77268962..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java +++ /dev/null @@ -1,610 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.jetty.monitor.thread.ThreadMonitorException; -import org.eclipse.jetty.monitor.thread.ThreadMonitorInfo; -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ManagedObject("Busy Thread Monitor") -public class ThreadMonitor extends AbstractLifeCycle implements Runnable -{ - private static final Logger LOG = Log.getLogger(ThreadMonitor.class); - - private int _scanInterval; - private int _logInterval; - private int _busyThreshold; - private int _logThreshold; - private int _stackDepth; - private int _trailLength; - - private ThreadMXBean _threadBean; - - private Thread _runner; - private Logger _logger; - private volatile boolean _done = true; - private Dumpable _dumpable; - - private Map _monitorInfo; - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor() throws Exception - { - this(5000); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs) throws Exception - { - this(intervalMs, 95); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @param threshold busy threshold - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs, int threshold) throws Exception - { - this(intervalMs, threshold, 3); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @param threshold busy threshold - * @param depth stack compare depth - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs, int threshold, int depth) throws Exception - { - this(intervalMs, threshold, depth, 3); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @param threshold busy threshold - * @param depth stack compare depth - * @param trail length of stack trail - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs, int threshold, int depth, int trail) throws Exception - { - _scanInterval = intervalMs; - _busyThreshold = threshold; - _stackDepth = depth; - _trailLength = trail; - - _logger = Log.getLogger(ThreadMonitor.class.getName()); - _monitorInfo = new HashMap(); - - init(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the scan interval. - * - * @return the scan interval - */ - public int getScanInterval() - { - return _scanInterval; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the scan interval. - * - * @param ms the new scan interval - */ - public void setScanInterval(int ms) - { - _scanInterval = ms; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the log interval. - * - * @return the log interval - */ - public int getLogInterval() - { - return _logInterval; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the log interval. - * - * @param ms the new log interval - */ - public void setLogInterval(int ms) - { - _logInterval = ms; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the busy threshold. - * - * @return the busy threshold - */ - public int getBusyThreshold() - { - return _busyThreshold; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the busy threshold. - * - * @param percent the new busy threshold - */ - public void setBusyThreshold(int percent) - { - _busyThreshold = percent; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the log threshold. - * - * @return the log threshold - */ - public int getLogThreshold() - { - return _logThreshold; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the log threshold. - * - * @param percent the new log threshold - */ - public void setLogThreshold(int percent) - { - _logThreshold = percent; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the stack depth. - * - * @return the stack depth - */ - public int getStackDepth() - { - return _stackDepth; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the stack depth. - * - * @param stackDepth the new stack depth - */ - public void setStackDepth(int stackDepth) - { - _stackDepth = stackDepth; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the stack trace trail length. - * - * @param trailLength the new trail length - */ - public void setTrailLength(int trailLength) - { - _trailLength = trailLength; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the stack trace trail length. - * - * @return the trail length - */ - public int getTrailLength() - { - return _trailLength; - } - - /* ------------------------------------------------------------ */ - /** - * Enable logging of CPU usage. - * - * @param frequencyMs the logging frequency - * @param thresholdPercent the logging threshold - */ - public void logCpuUsage(int frequencyMs, int thresholdPercent) - { - setLogInterval(frequencyMs); - setLogThreshold(thresholdPercent); - } - - /* ------------------------------------------------------------ */ - /** - * @return A {@link Dumpable} that is dumped whenever spinning threads are detected - */ - public Dumpable getDumpable() - { - return _dumpable; - } - - /* ------------------------------------------------------------ */ - /** - * @param dumpable A {@link Dumpable} that is dumped whenever spinning threads are detected - */ - public void setDumpable(Dumpable dumpable) - { - _dumpable = dumpable; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - public void doStart() - { - _done = false; - - _runner = new Thread(this); - _runner.setDaemon(true); - _runner.start(); - - LOG.info("Thread Monitor started successfully"); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ - public void doStop() - { - if (_runner != null) - { - _done = true; - try - { - _runner.join(); - } - catch (InterruptedException ex) {} - - _monitorInfo.clear(); - } - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve all avaliable thread ids - * - * @return array of thread ids - */ - protected long[] getAllThreadIds() - { - return _threadBean.getAllThreadIds(); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the cpu time for specified thread. - * - * @param id thread id - * @return cpu time of the thread - */ - protected long getThreadCpuTime(long id) - { - return _threadBean.getThreadCpuTime(id); - } - - /* ------------------------------------------------------------ */ - /** - * Initialize JMX objects. - */ - protected void init() - { - _threadBean = ManagementFactory.getThreadMXBean(); - if (_threadBean.isThreadCpuTimeSupported()) - { - _threadBean.setThreadCpuTimeEnabled(true); - } - } - - /* ------------------------------------------------------------ */ - /** - * @see java.lang.Runnable#run() - */ - public void run() - { - // Initialize repeat flag - boolean repeat = false; - boolean scanNow, logNow; - - // Set next scan time and log time - long nextScanTime = System.currentTimeMillis(); - long nextLogTime = nextScanTime + _logInterval; - - while (!_done) - { - long currTime = System.currentTimeMillis(); - scanNow = (currTime > nextScanTime); - logNow = (_logInterval > 0 && currTime > nextLogTime); - if (repeat || scanNow || logNow) - { - repeat = collectThreadInfo(); - logThreadInfo(logNow); - - if (scanNow) - { - nextScanTime = System.currentTimeMillis() + _scanInterval; - } - if (logNow) - { - nextLogTime = System.currentTimeMillis() + _logInterval; - } - } - - // Sleep only if not going to repeat scanning immediately - if (!repeat) - { - try - { - Thread.sleep(100); - } - catch (InterruptedException ex) - { - LOG.ignore(ex); - } - } - } - - } - - /* ------------------------------------------------------------ */ - /** - * Collect thread info. - */ - private boolean collectThreadInfo() - { - boolean repeat = false; - try - { - // Retrieve stack traces for all threads at once as it - // was proven to be an order of magnitude faster when - // retrieving a single thread stack trace. - Map all = Thread.getAllStackTraces(); - - Set newOrUpdatedIds = new HashSet(); - - for (Map.Entry entry : all.entrySet()) - { - Thread thread = entry.getKey(); - long threadId = thread.getId(); - - // Skip our own runner thread - if (threadId == _runner.getId()) - { - continue; - } - - ThreadMonitorInfo currMonitorInfo = _monitorInfo.get(Long.valueOf(threadId)); - if (currMonitorInfo == null) - { - // Create thread info object for a new thread - currMonitorInfo = new ThreadMonitorInfo(thread); - currMonitorInfo.setStackTrace(entry.getValue()); - currMonitorInfo.setCpuTime(getThreadCpuTime(threadId)); - currMonitorInfo.setSampleTime(System.nanoTime()); - _monitorInfo.put(Long.valueOf(threadId), currMonitorInfo); - } - else - { - // Update the existing thread info object - currMonitorInfo.setStackTrace(entry.getValue()); - currMonitorInfo.setCpuTime(getThreadCpuTime(threadId)); - currMonitorInfo.setSampleTime(System.nanoTime()); - - // Stack trace count holds logging state - int count = currMonitorInfo.getTraceCount(); - if (count >= 0 && currMonitorInfo.isSpinning()) - { - // Thread was spinning and was logged before - if (count < _trailLength) - { - // Log another stack trace - currMonitorInfo.setTraceCount(count+1); - repeat = true; - continue; - } - - // Reset spin flag and trace count - currMonitorInfo.setSpinning(false); - currMonitorInfo.setTraceCount(-1); - } - if (currMonitorInfo.getCpuUtilization() > _busyThreshold) - { - // Thread is busy - StackTraceElement[] lastStackTrace = currMonitorInfo.getStackTrace(); - - if (lastStackTrace != null - && matchStackTraces(lastStackTrace, entry.getValue())) - { - // Thread is spinning - currMonitorInfo.setSpinning(true); - if (count < 0) - { - // Enable logging of spin status and stack traces - // only if the incoming trace count is negative - // that indicates a new scan for this thread - currMonitorInfo.setTraceCount(0); - repeat = (_trailLength > 0); - } - } - } - } - newOrUpdatedIds.add(Long.valueOf(threadId)); - } - - //clean out threads that no longer exist - Iterator iter = _monitorInfo.keySet().iterator(); - while (iter.hasNext()) - { - Long id = iter.next(); - if (!newOrUpdatedIds.contains(id)) - iter.remove(); - } - newOrUpdatedIds.clear(); - } - catch (Exception ex) - { - LOG.debug(ex); - } - return repeat; - } - - /* ------------------------------------------------------------ */ - protected void logThreadInfo(boolean logAll) - { - if (_monitorInfo.size() > 0) - { - // Select thread objects for all live threads - long[] running = getAllThreadIds(); - List all = new ArrayList(); - for (int idx=0; idx() - { - /* ------------------------------------------------------------ */ - public int compare(ThreadMonitorInfo info1, ThreadMonitorInfo info2) - { - return (int)Math.signum(info2.getCpuUtilization()-info1.getCpuUtilization()); - } - }); - - String format = "Thread '%2$s'[%3$s,id:%1$d,cpu:%4$.2f%%]%5$s"; - - // Log thread information for threads that exceed logging threshold - // or log spinning threads if their trace count is zero - boolean spinning=false; - for (ThreadMonitorInfo info : all) - { - if (logAll && info.getCpuUtilization() > _logThreshold - || info.isSpinning() && info.getTraceCount() == 0) - { - String message = String.format(format, - info.getThreadId(), info.getThreadName(), - info.getThreadState(), info.getCpuUtilization(), - info.isSpinning() ? " SPINNING" : ""); - _logger.info(message); - spinning=true; - } - } - - // Dump info - if (spinning && _dumpable!=null) - { - System.err.println(_dumpable.dump()); - } - - // Log stack traces for spinning threads with positive trace count - for (ThreadMonitorInfo info : all) - { - if (info.isSpinning() && info.getTraceCount() >= 0) - { - String message = String.format(format, - info.getThreadId(), info.getThreadName(), - info.getThreadState(), info.getCpuUtilization(), - " STACK TRACE"); - _logger.warn(new ThreadMonitorException(message, info.getStackTrace())); - } - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Match stack traces. - * - * @param lastStackTrace last stack trace - * @param stackTrace current stack trace - * @return true, if successful - */ - private boolean matchStackTraces(StackTraceElement[] lastStackTrace, StackTraceElement[] stackTrace) - { - boolean match = true; - int count = Math.min(_stackDepth, Math.min(lastStackTrace.length, stackTrace.length)); - - for (int idx=0; idx < count; idx++) - { - if (!stackTrace[idx].equals(lastStackTrace[idx])) - { - match = false; - break; - } - } - return match; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java deleted file mode 100644 index 54267df40a4..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java +++ /dev/null @@ -1,409 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.integration; - -import static java.lang.Integer.parseInt; -import static java.lang.System.getProperty; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.net.URL; -import java.util.Collection; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.util.BytesContentProvider; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.monitor.JMXMonitor; -import org.eclipse.jetty.monitor.jmx.EventNotifier; -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventState.TriggerState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; -import org.eclipse.jetty.monitor.jmx.MonitorAction; -import org.eclipse.jetty.monitor.triggers.AggregateEventTrigger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.QueuedThreadPool; - -public class JavaMonitorAction extends MonitorAction -{ - private static final Logger LOG = Log.getLogger(JavaMonitorAction.class); - - private final HttpClient _client; - - private final String _url; - private final String _uuid; - private final String _appid; - - private String _srvip; - private String _session; - - /* ------------------------------------------------------------ */ - public JavaMonitorAction(EventNotifier notifier, String url, String uuid, String appid, long pollInterval) - throws Exception - { - super(new AggregateEventTrigger(),notifier,pollInterval); - - _url = url; - _uuid = uuid; - _appid = appid; - - QueuedThreadPool executor = new QueuedThreadPool(); - executor.setName(executor.getName() + "-monitor"); - _client = new HttpClient(); - _client.setExecutor(executor); - - try - { - _client.start(); - _srvip = getServerIP(); - } - catch (Exception ex) - { - LOG.debug(ex); - } - - sendData(new Properties()); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.MonitorAction#execute(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - @Override - public void execute(EventTrigger trigger, EventState state, long timestamp) - { - exec(trigger, state, timestamp); - } - - /* ------------------------------------------------------------ */ - /** - * @param trigger - * @param state - * @param timestamp - */ - private void exec(EventTrigger trigger, EventState state, long timestamp) - { - Collection> trs = state.values(); - - Properties data = new Properties(); - for (TriggerState ts : trs) - { - Object value = ts.getValue(); - - StringBuffer buffer = new StringBuffer(); - buffer.append(value == null ? "" : value.toString()); - buffer.append("|"); - buffer.append(getClassID(value)); - buffer.append("||"); - buffer.append(ts.getDescription()); - - data.setProperty(ts.getID(), buffer.toString()); - - try - { - sendData(data); - } - catch (Exception ex) - { - LOG.debug(ex); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @param data - * @throws Exception - */ - private void sendData(Properties data) - throws Exception - { - data.put("account", _uuid); - data.put("appserver", "Jetty"); - data.put("localIp", _srvip); - if (_appid == null) - data.put("lowestPort", getHttpPort()); - else - data.put("lowestPort", _appid); - if (_session != null) - data.put("session", _session); - - Properties response = sendRequest(data); - - parseResponse(response); - } - - /* ------------------------------------------------------------ */ - /** - * @param request - * @return - * @throws Exception - */ - private Properties sendRequest(Properties request) - throws Exception - { - ByteArrayOutputStream reqStream = null; - ByteArrayInputStream resStream = null; - Properties response = null; - - try { - reqStream = new ByteArrayOutputStream(); - request.storeToXML(reqStream,null); - - ContentResponse r3sponse = _client.POST(_url) - .header("Connection","close") - .content(new BytesContentProvider(reqStream.toByteArray())) - .send(); - - - if (r3sponse.getStatus() == HttpStatus.OK_200) - { - response = new Properties(); - resStream = new ByteArrayInputStream(r3sponse.getContent()); - response.loadFromXML(resStream); - } - } - finally - { - try - { - if (reqStream != null) - reqStream.close(); - } - catch (IOException ex) - { - LOG.ignore(ex); - } - - try - { - if (resStream != null) - resStream.close(); - } - catch (IOException ex) - { - LOG.ignore(ex); - } - } - - return response; - } - - /* ------------------------------------------------------------ */ - private void parseResponse(Properties response) - { - if (response.get("onhold") != null) - throw new Error("Suspended"); - - - if (response.get("session") != null) - { - _session = (String) response.remove("session"); - - AggregateEventTrigger trigger = (AggregateEventTrigger)getTrigger(); - - String queryString; - ObjectName[] queryResults; - for (Map.Entry entry : response.entrySet()) - { - String[] values = ((String) entry.getValue()).split("\\|"); - - queryString = values[0]; - if (queryString.startsWith("com.javamonitor.openfire")) - continue; - - if (queryString.startsWith("com.javamonitor")) - { - queryString = "org.eclipse.jetty.monitor.integration:type=javamonitortools,id=0"; - } - - queryResults = null; - try - { - queryResults = queryNames(queryString); - } - catch (IOException e) - { - LOG.debug(e); - } - catch (MalformedObjectNameException e) - { - LOG.debug(e); - } - - if (queryResults != null) - { - int idx = 0; - for(ObjectName objName : queryResults) - { - String id = entry.getKey().toString()+(idx == 0 ? "" : ":"+idx); - String name = queryString.equals(objName.toString()) ? "" : objName.toString(); - boolean repeat = Boolean.parseBoolean(values[2]); - trigger.add(new JavaMonitorTrigger(objName, values[1], id, name, repeat)); - } - } - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @param value - * @return - */ - private int getClassID(final Object value) - { - if (value == null) - return 0; - - if (value instanceof Byte || - value instanceof Short || - value instanceof Integer || - value instanceof Long) - return 1; - - if (value instanceof Float || - value instanceof Double) - return 2; - - if (value instanceof Boolean) - return 3; - - return 4; // String - } - - /* ------------------------------------------------------------ */ - /** - * @return - * @throws Exception - */ - private String getServerIP() - throws Exception - { - Socket s = null; - try { - if (getProperty("http.proxyHost") != null) - { - s = new Socket(getProperty("http.proxyHost"), - parseInt(getProperty("http.proxyPort", "80"))); - } - else - { - int port = 80; - - URL url = new URL(_url); - if (url.getPort() != -1) { - port = url.getPort(); - } - s = new Socket(url.getHost(), port); - } - return s.getLocalAddress().getHostAddress(); - } - finally - { - try - { - if (s != null) - s.close(); - } - catch (IOException ex) - { - LOG.ignore(ex); - } - } - } - - /* ------------------------------------------------------------ */ - public Integer getHttpPort() - { - Collection connectors = null; - MBeanServerConnection service; - try - { - service = JMXMonitor.getServiceConnection(); - - connectors = service.queryNames(new ObjectName("org.eclipse.jetty.nio:type=selectchannelconnector,*"), null); - if (connectors != null && connectors.size() > 0) - { - Integer lowest = Integer.MAX_VALUE; - for (final ObjectName connector : connectors) { - lowest = (Integer)service.getAttribute(connector, "port"); - } - - if (lowest < Integer.MAX_VALUE) - return lowest; - } - } - catch (Exception ex) - { - LOG.debug(ex); - } - - return 0; - } - - /* ------------------------------------------------------------ */ - /** - * @param param - * @return - * @throws IOException - * @throws NullPointerException - * @throws MalformedObjectNameException - */ - private ObjectName[] queryNames(ObjectName param) - throws IOException, MalformedObjectNameException - { - ObjectName[] result = null; - - MBeanServerConnection connection = JMXMonitor.getServiceConnection(); - Set names = connection.queryNames(param, null); - if (names != null && names.size() > 0) - { - result = new ObjectName[names.size()]; - - int idx = 0; - for(Object name : names) - { - if (name instanceof ObjectName) - result[idx++] = (ObjectName)name; - else - result[idx++] = new ObjectName(name.toString()); - } - } - - return result; - } - - private ObjectName[] queryNames(String param) - throws IOException, MalformedObjectNameException - { - return queryNames(new ObjectName(param)); - } - - } diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java deleted file mode 100644 index 090fb6d23a3..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java +++ /dev/null @@ -1,288 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.integration; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.lang.management.ThreadMXBean; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.security.Security; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.annotation.ManagedOperation; - -/** - * Derived from the JMX bean classes created by Kees Jan Koster for the java-monitor - * J2EE probe http://code.google.com/p/java-monitor-probes/source/browse/. - * - * @author Kees Jan Koster - */ -@ManagedObject("Java Monitoring Tools") -public class JavaMonitorTools -{ - private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - - private static Method findDeadlockMethod = null; - - static - { - try - { - findDeadlockMethod = ThreadMXBean.class.getMethod("findDeadlockedThreads"); - } - catch (Exception ignored) - { - // this is a 1.5 JVM - try - { - findDeadlockMethod = ThreadMXBean.class.getMethod("findMonitorDeadlockedThreads"); - } - catch (SecurityException e) - { - e.printStackTrace(); - } - catch (NoSuchMethodException e) - { - e.printStackTrace(); - } - } - } - - private ThreadInfo[] findDeadlock() - throws IllegalAccessException, InvocationTargetException - { - final long[] threadIds = (long[])findDeadlockMethod.invoke(threadMXBean,(Object[])null); - - if (threadIds == null || threadIds.length < 1) - { - // no deadlock, we're done - return null; - } - - final ThreadInfo[] threads = threadMXBean.getThreadInfo(threadIds,Integer.MAX_VALUE); - return threads; - } - @ManagedOperation(value="Detailed report on the deadlocked threads.", impact="ACTION_INFO") - public String getDeadlockStacktraces() - { - try - { - final ThreadInfo[] threads = findDeadlock(); - if (threads == null) - { - // no deadlock, we're done - return null; - } - - return stacktraces(threads,0); - } - catch (Exception e) - { - return e.getMessage(); - } - } - - private static final int MAX_STACK = 10; - - private String stacktraces(final ThreadInfo[] threads, final int i) - { - if (i >= threads.length) - { - return ""; - } - final ThreadInfo thread = threads[i]; - - final StringBuilder trace = new StringBuilder(); - for (int stack_i = 0; stack_i < Math.min(thread.getStackTrace().length,MAX_STACK); stack_i++) - { - if (stack_i == (MAX_STACK - 1)) - { - trace.append(" ..."); - } - else - { - trace.append(" at ").append(thread.getStackTrace()[stack_i]).append("\n"); - } - } - - return "\"" + thread.getThreadName() + "\", id " + thread.getThreadId() + " is " + thread.getThreadState() + " on " + thread.getLockName() - + ", owned by " + thread.getLockOwnerName() + ", id " + thread.getLockOwnerId() + "\n" + trace + "\n\n" + stacktraces(threads,i + 1); - } - - /** - * We keep track of the last time we sampled the thread states. - * It is a crude optimization to avoid having to query for the - * threads states very often. - */ - private long lastSampled = 0L; - - private final Map states = new HashMap(); - - @ManagedOperation(value="Number of Blocked Threads") - public int getThreadsBlocked() - { - sampleThreads(); - - return states.get(Thread.State.BLOCKED); - } - - @ManagedOperation(value="Number of New Threads", impact="ACTION_INFO") - public int getThreadsNew() - { - sampleThreads(); - - return states.get(Thread.State.NEW); - } - - @ManagedOperation(value="Number of Terminated Threads", impact="ACTION_INFO") - public int getThreadsTerminated() - { - sampleThreads(); - - return states.get(Thread.State.TERMINATED); - } - - @ManagedOperation(value="Number of Sleeping and Waiting threads") - public int getThreadsTimedWaiting() - { - sampleThreads(); - - return states.get(Thread.State.TIMED_WAITING); - } - - @ManagedOperation(value="Number of Waiting Threads", impact="ACTION_INFO") - public int getThreadsWaiting() - { - sampleThreads(); - - return states.get(Thread.State.WAITING); - } - - @ManagedOperation(value="Number of Runnable Threads", impact="ACTION_INFO") - public int getThreadsRunnable() - { - sampleThreads(); - - return states.get(Thread.State.RUNNABLE); - } - - private synchronized void sampleThreads() - { - if ((lastSampled + 50L) < System.currentTimeMillis()) - { - lastSampled = System.currentTimeMillis(); - for (final Thread.State state : Thread.State.values()) - { - states.put(state,0); - } - - for (final ThreadInfo thread : threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds())) - { - if (thread != null) - { - final Thread.State state = thread.getThreadState(); - states.put(state,states.get(state) + 1); - } - else - { - states.put(Thread.State.TERMINATED,states.get(Thread.State.TERMINATED) + 1); - } - } - } - } - - private static final String POLICY = "sun.net.InetAddressCachePolicy"; - - @ManagedOperation(value="Amount of time successful DNS queries are cached for.") - public int getCacheSeconds() throws ClassNotFoundException, - IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - final Class policy = Class.forName(POLICY); - final Object returnValue = policy.getMethod("get", (Class[]) null) - .invoke(null, (Object[]) null); - Integer seconds = (Integer) returnValue; - - return seconds.intValue(); - } - - @ManagedOperation(value="Amount of time failed DNS queries are cached for") - public int getCacheNegativeSeconds() throws ClassNotFoundException, - IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - final Class policy = Class.forName(POLICY); - final Object returnValue = policy.getMethod("getNegative", - (Class[]) null).invoke(null, (Object[]) null); - Integer seconds = (Integer) returnValue; - - return seconds.intValue(); - } - - private static final String DEFAULT = "default"; - - private static final String SECURITY = "security"; - - private static final String SYSTEM = "system"; - - private static final String BOTH = "both"; - - private static final String SECURITY_TTL = "networkaddress.cache.ttl"; - - private static final String SYSTEM_TTL = "sun.net.inetaddr.ttl"; - - private static final String SECURITY_NEGATIVE_TTL = "networkaddress.cache.negative.ttl"; - - private static final String SYSTEM_NEGATIVE_TTL = "sun.net.inetaddr.negative.ttl"; - - @ManagedOperation(value="Cache policy for successful DNS lookups was changed from the hard-coded default") - public String getCacheTweakedFrom() { - if (Security.getProperty(SECURITY_TTL) != null) { - if (System.getProperty(SYSTEM_TTL) != null) { - return BOTH; - } - - return SECURITY; - } - - if (System.getProperty(SYSTEM_TTL) != null) { - return SYSTEM; - } - - return DEFAULT; - } - - @ManagedOperation(value="Cache policy for failed DNS lookups was changed from the hard-coded default") - public String getCacheNegativeTweakedFrom() { - if (Security.getProperty(SECURITY_NEGATIVE_TTL) != null) { - if (System.getProperty(SYSTEM_NEGATIVE_TTL) != null) { - return BOTH; - } - - return SECURITY; - } - - if (System.getProperty(SYSTEM_NEGATIVE_TTL) != null) { - return SYSTEM; - } - - return DEFAULT; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java deleted file mode 100644 index 06a51d52641..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.integration; - -import javax.management.ObjectName; - -import org.eclipse.jetty.monitor.triggers.AttrEventTrigger; - - -/** - * @param the trigger type - */ -public class JavaMonitorTrigger > - extends AttrEventTrigger -{ - private final String _id; - private final String _name; - private final boolean _dynamic; - private int _count; - - /* ------------------------------------------------------------ */ - public JavaMonitorTrigger(ObjectName nameObject, String attributeName, String id, String name, boolean dynamic) - throws IllegalArgumentException - { - super(nameObject, attributeName); - - _id = id; - _name = name; - _dynamic = dynamic; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return _dynamic ? true : (_count++ < 1); - } - - protected boolean getSaveAll() - { - return false; - } - - @Override - public String getID() - { - return _id; - } - - @Override - public String getNameString() - { - return _name; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java deleted file mode 100644 index 257b8f0cee2..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Intregation with Java Monitor - */ -package org.eclipse.jetty.monitor.integration; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java deleted file mode 100644 index bdfa6d1291d..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - - -/* ------------------------------------------------------------ */ -/** - * ConsoleNotifier - * - * Provides a way to output notification messages to the server console - */ -public class ConsoleNotifier implements EventNotifier -{ - String _messageFormat; - - - /* ------------------------------------------------------------ */ - /** - * Constructs a new notifier with specified format string - * - * @param format the {@link java.util.Formatter format string} - * @throws IllegalArgumentException if format is invalid - */ - public ConsoleNotifier(String format) - throws IllegalArgumentException - { - if (format == null) - throw new IllegalArgumentException("Message format cannot be null"); - - _messageFormat = format; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.EventNotifier#notify(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - public void notify(EventTrigger trigger, EventState state, long timestamp) - { - String output = String.format("%1$tF %1$tT.%1$tL:NOTIFY::", timestamp); - - output += String.format(_messageFormat, state); - - System.out.println(output); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java deleted file mode 100644 index 7f28c2b5b4f..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - - -/* ------------------------------------------------------------ */ -/** - * EventNotifier - * - * Interface for classes used to send event notifications - */ -public interface EventNotifier -{ - - /* ------------------------------------------------------------ */ - /** - * This method is called when a notification event is received by the containing object - * - * @param trigger the event trigger - * @param state an {@link org.eclipse.jetty.monitor.jmx.EventState event state} - * @param timestamp time stamp of the event - */ - public void notify(EventTrigger trigger, EventState state, long timestamp); -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java deleted file mode 100644 index abaecbc5c87..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java +++ /dev/null @@ -1,209 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - - -/* ------------------------------------------------------------ */ -/** - * EventState - * - * Holds the state of one or more {@link org.eclipse.jetty.monitor.jmx.EventTrigger event trigger} - * instances to be used when sending notifications as well as executing the actions - * @param the event trigger type - */ -public class EventState -{ - - /* ------------------------------------------------------------ */ - /** - * State - * - * Holds the state of a single {@link org.eclipse.jetty.monitor.jmx.EventTrigger event trigger} - * @param the event trigger type - */ - public static class TriggerState - { - private final String _id; - private final String _desc; - private final TYPE _value; - - /* ------------------------------------------------------------ */ - /** - * Construct a trigger state - * - * @param id unique identification string of the associated event trigger - * @param desc description of the associated event trigger - * @param value effective value of the MXBean attribute (if applicable) - */ - public TriggerState(String id, String desc, TYPE value) - { - _id = id; - _desc = desc; - _value = value; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the identification string of associated event trigger - * - * @return unique identification string - */ - public String getID() - { - return _id; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the description string set by event trigger - * - * @return description string - */ - public String getDescription() - { - return _desc; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the effective value of the MXBean attribute (if applicable) - * - * @return attribute value - */ - public TYPE getValue() - { - return _value; - } - - /* ------------------------------------------------------------ */ - /** - * @return string representation of the state - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_desc); - result.append('='); - result.append(_value); - - return result.toString(); - } - } - - protected Map> _states; - - /* ------------------------------------------------------------ */ - /** - * Constructs an empty event state - */ - public EventState() - { - _states = new ConcurrentHashMap>(); - } - - - /* ------------------------------------------------------------ */ - /** - * Constructs an event state and adds a specified trigger state to it - * - * @param id unique identification string of the associated event trigger - * @param desc description of the associated event trigger - * @param value effective value of the MXBean attribute (if applicable) - */ - public EventState(String id, String desc, TYPE value) - { - this(); - - add(new TriggerState(id, desc, value)); - } - - /* ------------------------------------------------------------ */ - /** - * Adds a trigger state to the event state - * - * @param state trigger state to add - */ - public void add(TriggerState state) - { - _states.put(state.getID(), state); - } - - /* ------------------------------------------------------------ */ - /** - * Adds a collection of trigger states to the event state - * - * @param entries collection of trigger states to add - */ - public void addAll(Collection> entries) - { - for (TriggerState entry : entries) - { - add(entry); - } - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves a single trigger state - * - * @param id unique identification string of the event trigger - * @return requested trigger state or null if not found - */ - public TriggerState get(String id) - { - return _states.get(id); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves a collection of all trigger states of the event state - * - * @return collection of the trigger states - */ - public Collection> values() - { - return Collections.unmodifiableCollection(_states.values()); - } - - /* ------------------------------------------------------------ */ - /** - * Returns a string representation of the event state - * - * @return string representation of the event state - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - for (TriggerState value : _states.values()) - { - result.append(cnt++>0?"#":""); - result.append(value.toString()); - } - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java deleted file mode 100644 index fcc7cfb3cab..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import static java.util.UUID.randomUUID; - -/* ------------------------------------------------------------ */ -/** - * EventTrigger - * - * Abstract base class for all EventTrigger implementations. - * Used to determine whether the necessary conditions for - * triggering an event are present. - */ -public abstract class EventTrigger -{ - private final String _id; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger - */ - public EventTrigger() - { - _id = randomUUID().toString(); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the identification string of the event trigger - * - * @return unique identification string - */ - public String getID() - { - return _id; - } - - /* ------------------------------------------------------------ */ - /** - * Abstract method to verify if the event trigger conditions - * are in the appropriate state for an event to be triggered - * - * @param timestamp the timestamp to match - * @return true to trigger an event - * @throws Exception if unable to match - */ - public abstract boolean match(long timestamp) throws Exception; - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - */ - public abstract EventState getState(long timestamp); -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java deleted file mode 100644 index 0c102e554d2..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** - * ConsoleNotifier - * - * Provides a way to output notification messages to a log file - */ -public class LoggingNotifier implements EventNotifier -{ - private static final Logger LOG = Log.getLogger(LoggingNotifier.class); - - String _messageFormat; - - /* ------------------------------------------------------------ */ - /** - * Constructs a new notifier with specified format string - * - * @param format the {@link java.util.Formatter format string} - * @throws IllegalArgumentException if format is invalid - */ - public LoggingNotifier(String format) - throws IllegalArgumentException - { - if (format == null) - throw new IllegalArgumentException("Message format cannot be null"); - - _messageFormat = format; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.EventNotifier#notify(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - public void notify(EventTrigger trigger, EventState state, long timestamp) - { - String output = String.format(_messageFormat, state); - - LOG.info(output); - } - -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java deleted file mode 100644 index 08017dde02a..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java +++ /dev/null @@ -1,179 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import static java.util.UUID.randomUUID; - -import java.security.InvalidParameterException; - -/* ------------------------------------------------------------ */ -/** - * MonitorAction - * - * Abstract base class for all MonitorAction implementations. - * Receives notification when an associated EventTrigger is matched. - */ -public abstract class MonitorAction - extends NotifierGroup -{ - public static final int DEFAULT_POLL_INTERVAL = 5000; - - private final String _id; - private final EventTrigger _trigger; - private final EventNotifier _notifier; - private final long _pollInterval; - private final long _pollDelay; - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger) - throws InvalidParameterException - { - this(trigger, null, 0, 0); - } - - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @param notifier event notifier to be associated with this action - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger, EventNotifier notifier) - throws InvalidParameterException - { - this(trigger, notifier, 0); - } - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @param notifier event notifier to be associated with this action - * @param pollInterval interval for polling of the JMX server - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger, EventNotifier notifier, long pollInterval) - throws InvalidParameterException - { - this(trigger, notifier, pollInterval, 0); - } - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @param notifier event notifier to be associated with this action - * @param pollInterval interval for polling of the JMX server - * @param pollDelay delay before starting to poll the JMX server - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger, EventNotifier notifier, long pollInterval, long pollDelay) - throws InvalidParameterException - { - if (trigger == null) - throw new InvalidParameterException("Trigger cannot be null"); - - _id = randomUUID().toString(); - _trigger = trigger; - _notifier = notifier; - _pollInterval = pollInterval > 0 ? pollInterval : DEFAULT_POLL_INTERVAL; - _pollDelay = pollDelay > 0 ? pollDelay : _pollInterval; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the identification string of the monitor action - * - * @return unique identification string - */ - - public final String getID() - { - return _id; - } - - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event trigger of the monitor action - * - * @return associated event trigger - */ - public EventTrigger getTrigger() - { - return _trigger; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the poll interval - * - * @return interval value (in milliseconds) - */ - public long getPollInterval() - { - return _pollInterval; - } - - - /* ------------------------------------------------------------ */ - /** Retrieve the poll delay - * @return delay value (in milliseconds) - */ - public long getPollDelay() - { - return _pollDelay; - } - - /* ------------------------------------------------------------ */ - /** - * This method will be called when event trigger associated - * with this monitor action matches its conditions. - * - * @param timestamp time stamp of the event - */ - public final void doExecute(long timestamp) - { - EventState state =_trigger.getState(timestamp); - if (_notifier != null) - _notifier.notify(_trigger, state, timestamp); - execute(_trigger, state, timestamp); - } - - /* ------------------------------------------------------------ */ - /** - * This method will be called to allow subclass to execute - * the desired action in response to the event. - * - * @param trigger event trigger associated with this monitor action - * @param state event state associated with current invocation of event trigger - * @param timestamp time stamp of the current invocation of event trigger - */ - public abstract void execute(EventTrigger trigger, EventState state, long timestamp); - } diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java deleted file mode 100644 index 531fbf1d916..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java +++ /dev/null @@ -1,119 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.util.HashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.ExecutorThreadPool; -import org.eclipse.jetty.util.thread.ThreadPool; - -/* ------------------------------------------------------------ */ -/** - * MonitorTask - * - * Invokes polling of the JMX server for the MBean attribute values - * through executing timer task scheduled using java.util.Timer - * at specified poll interval following a specified delay. - */ -public class MonitorTask extends TimerTask -{ - private static final Logger LOG = Log.getLogger(MonitorTask.class); - - private static Timer __timer = new Timer(true); - private static ThreadPool _callback = new ExecutorThreadPool(4,64,60,TimeUnit.SECONDS);; - private static Map __tasks = new HashMap(); - - private final MonitorAction _action; - - /* ------------------------------------------------------------ */ - /** - * Creates new instance of MonitorTask - * - * @param action instance of MonitorAction to use - */ - private MonitorTask(MonitorAction action) - { - _action = action; - } - - /* ------------------------------------------------------------ */ - /** - * Schedule new timer task for specified monitor action - * - * @param action monitor action - */ - public static void schedule(MonitorAction action) - { - TimerTask task = new MonitorTask(action); - __timer.scheduleAtFixedRate(task, - action.getPollDelay(), - action.getPollInterval()); - - __tasks.put(action.getID(), task); - } - - /* ------------------------------------------------------------ */ - /** - * Cancel timer task for specified monitor action - * - * @param action monitor action - */ - public static void cancel(MonitorAction action) - { - TimerTask task = __tasks.remove(action.getID()); - if (task != null) - task.cancel(); - } - - /* ------------------------------------------------------------ */ - /** - * This method is invoked when poll interval has elapsed - * to check if the event trigger conditions are satisfied - * in order to fire event. - * - * @see java.util.TimerTask#run() - */ - @Override - public final void run() - { - final long timestamp = System.currentTimeMillis(); - final EventTrigger trigger = _action.getTrigger(); - - _callback.execute(new Runnable() { - public void run() - { - try - { - if(trigger.match(timestamp)) - _action.doExecute(timestamp); - } - catch (Exception ex) - { - LOG.debug(ex); - } - } - }); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java deleted file mode 100644 index d67489bc16d..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java +++ /dev/null @@ -1,119 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - - - -/* ------------------------------------------------------------ */ -/** - * NotifierGroup - * - * This class allows for grouping of the event notifiers - */ -public class NotifierGroup implements EventNotifier -{ - private Set _group; - - /* ------------------------------------------------------------ */ - /** - * Create a notifier group - */ - public NotifierGroup() - { - _group = new HashSet(); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve all event notifier associated with this group - * - * @return collection of event notifiers - */ - public Collection getNotifiers() - { - return Collections.unmodifiableSet(_group); - } - - /* ------------------------------------------------------------ */ - /** - * Add specified event notifier to event notifier group - * - * @param notifier event notifier to be added - * @return true if successful - */ - public boolean addNotifier(EventNotifier notifier) - { - return _group.add(notifier); - } - - /* ------------------------------------------------------------ */ - /** - * Add a collection of event notifiers to event notifier group - * - * @param notifiers collection of event notifiers to be added - * @return true if successful - */ - public boolean addNotifiers(Collection notifiers) - { - return _group.addAll(notifiers); - } - - /* ------------------------------------------------------------ */ - /** - * Remove event notifier from event notifier group - * - * @param notifier event notifier to be removed - * @return true if successful - */ - public boolean removeNotifier(EventNotifier notifier) - { - return _group.remove(notifier); - } - - /* ------------------------------------------------------------ */ - /** - * Remove a collection of event notifiers from event notifier group - * - * @param notifiers collection of event notifiers to be removed - * @return true if successful - */ - public boolean removeNotifiers(Collection notifiers) - { - return _group.removeAll(notifiers); - } - - /* ------------------------------------------------------------ */ - /** - * Invoke the notify() method of each of the notifiers in group - * - * @see org.eclipse.jetty.monitor.jmx.EventNotifier#notify(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - public void notify(EventTrigger trigger, EventState state, long timestamp) - { - for (EventNotifier notifier: _group) - { - notifier.notify(trigger, state, timestamp); - } - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java deleted file mode 100644 index 0088cccf05f..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java +++ /dev/null @@ -1,172 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.io.IOException; -import java.lang.management.ManagementFactory; - -import javax.management.MBeanServer; -import javax.management.MBeanServerConnection; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXConnectorServer; -import javax.management.remote.JMXConnectorServerFactory; -import javax.management.remote.JMXServiceURL; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** - * ServerConnection - * - * Provides ability to create a connection to either an external - * JMX server, or a loopback connection to the internal one. - */ -public class ServiceConnection -{ - private static final Logger LOG = Log.getLogger(ServiceConnection.class); - - private String _serviceUrl; - private MBeanServer _server; - private JMXConnectorServer _connectorServer; - private JMXConnector _serverConnector; - private MBeanServerConnection _serviceConnection; - - /* ------------------------------------------------------------ */ - /** - * Construct a loopback connection to an internal server - * - * @throws IOException if unable to construct service connection - */ - public ServiceConnection() - throws IOException - { - this(null); - } - - /* ------------------------------------------------------------ */ - /** - * Construct a connection to specified server - * - * @param url URL of JMX server - * @throws IOException if unable to construct service connection - */ - public ServiceConnection(String url) - throws IOException - { - _serviceUrl = url; - } - - /** - * Retrieve an external URL for the JMX server - * - * @return service URL - */ - public String getServiceUrl() - { - return _serviceUrl; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve a connection to MBean server - * - * @return connection to MBean server - */ - public MBeanServerConnection getConnection() - { - return _serviceConnection; - } - - public void connect() - throws IOException - { - if (_serviceConnection == null) - { - if (_serviceUrl == null) - openLoopbackConnection(); - else - openServerConnection(_serviceUrl); - } - } - /* ------------------------------------------------------------ */ - /** - * Open a loopback connection to local JMX server - * - * @throws IOException - */ - private void openLoopbackConnection() - throws IOException - { - _server = ManagementFactory.getPlatformMBeanServer(); - - JMXServiceURL serviceUrl = new JMXServiceURL("service:jmx:rmi://"); - _connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serviceUrl, null, _server); - _connectorServer.start(); - - _serviceUrl = _connectorServer.getAddress().toString(); - - _serverConnector = JMXConnectorFactory.connect(_connectorServer.getAddress()); - _serviceConnection = _serverConnector.getMBeanServerConnection(); - } - - /* ------------------------------------------------------------ */ - /** - * Open a connection to remote JMX server - * - * @param url - * @throws IOException - */ - private void openServerConnection(String url) - throws IOException - { - _serviceUrl = url; - - JMXServiceURL serviceUrl = new JMXServiceURL(_serviceUrl); - _serverConnector = JMXConnectorFactory.connect(serviceUrl); - _serviceConnection = _serverConnector.getMBeanServerConnection(); - } - - /* ------------------------------------------------------------ */ - /** - * Close the connections - */ - public void disconnect() - { - try - { - if (_serverConnector != null) - { - _serverConnector.close(); - _serviceConnection = null; - } - if (_connectorServer != null) - { - _connectorServer.stop(); - _connectorServer = null; - } - } - catch (Exception ex) - { - LOG.debug(ex); - } - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java deleted file mode 100644 index a4feb7b0b74..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.security.InvalidParameterException; - - - -/* ------------------------------------------------------------ */ -/** - */ -public class SimpleAction extends MonitorAction -{ - public SimpleAction(EventTrigger trigger, EventNotifier notifier, long pollInterval) - throws InvalidParameterException - { - super(trigger,notifier,pollInterval); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.MonitorAction#execute(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - - @Override - public void execute(EventTrigger trigger, EventState state, long timestamp) - { - System.out.printf("Action time: %tc%n", timestamp); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java deleted file mode 100644 index e3c71b53fd8..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : JMX Integration - */ -package org.eclipse.jetty.monitor.jmx; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java deleted file mode 100644 index c4cf607a7ec..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Tool for Monitoring Threads - */ -package org.eclipse.jetty.monitor; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java deleted file mode 100644 index a05ab0690d2..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.thread; - - -/* ------------------------------------------------------------ */ -/** - */ -public class ThreadMonitorException extends Exception -{ - private static final long serialVersionUID = -4345223166315716918L; - - public ThreadMonitorException(String message, StackTraceElement[] stackTrace) - { - super(message); - setStackTrace(stackTrace); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java deleted file mode 100644 index d8322d376f8..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java +++ /dev/null @@ -1,202 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.thread; - - -/* ------------------------------------------------------------ */ -/** - */ -public class ThreadMonitorInfo -{ - private Thread _thread; - private StackTraceElement[] _stackTrace; - - private boolean _threadSpinning = false; - private int _traceCount = -1; - - private long _prevCpuTime; - private long _prevSampleTime; - private long _currCpuTime; - private long _currSampleTime; - - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor info. - * - * @param thread the thread this object is created for - */ - public ThreadMonitorInfo(Thread thread) - { - _thread = thread; - } - - /* ------------------------------------------------------------ */ - /** - * @return Id of the thread - */ - public long getThreadId() - { - return _thread.getId(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the thread name. - * - * @return the thread name - */ - public String getThreadName() - { - return _thread.getName(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the thread state. - * - * @return the thread state - */ - public String getThreadState() - { - return _thread.getState().toString(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the stack trace. - * - * @return the stack trace - */ - public StackTraceElement[] getStackTrace() - { - return _stackTrace; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the stack trace. - * - * @param stackTrace the new stack trace - */ - public void setStackTrace(StackTraceElement[] stackTrace) - { - _stackTrace = stackTrace; - } - - /* ------------------------------------------------------------ */ - /** - * Checks if is spinning. - * - * @return true, if is spinning - */ - public boolean isSpinning() - { - return _threadSpinning; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the spinning flag. - * - * @param value the new value - */ - public void setSpinning(boolean value) - { - _threadSpinning = value; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the trace count. - * - * @param traceCount the new trace count - */ - public void setTraceCount(int traceCount) - { - _traceCount = traceCount; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the trace count. - * - * @return the trace count - */ - public int getTraceCount() - { - return _traceCount; - } - - /* ------------------------------------------------------------ */ - /** - * @return the CPU time of the thread - */ - public long getCpuTime() - { - return _currCpuTime; - } - - /* ------------------------------------------------------------ */ - /** - * Set the CPU time. - * - * @param ns new CPU time - */ - public void setCpuTime(long ns) - { - _prevCpuTime = _currCpuTime; - _currCpuTime = ns; - } - - /* ------------------------------------------------------------ */ - /** - * @return the time of sample - */ - public long getSampleTime() - { - return _currSampleTime; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the sample time. - * - * @param ns the time of sample - */ - public void setSampleTime(long ns) - { - _prevSampleTime = _currSampleTime; - _currSampleTime = ns; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the CPU utilization. - * - * @return the CPU utilization percentage - */ - public float getCpuUtilization() - { - long elapsedCpuTime = _currCpuTime - _prevCpuTime; - long elapsedNanoTime = _currSampleTime - _prevSampleTime; - - return elapsedNanoTime > 0 ? Math.min((elapsedCpuTime * 100.0f) / elapsedNanoTime, 100.0f) : 0; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java deleted file mode 100644 index 997ff01d1a3..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Thread Monitoring - */ -package org.eclipse.jetty.monitor.thread; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java deleted file mode 100644 index b8db4b92d85..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java +++ /dev/null @@ -1,159 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; - - -/* ------------------------------------------------------------ */ -/** - * AggregateEventTrigger - * - * EventTrigger aggregation that executes every aggregated event - * triggers in left to right order, and returns match if any one - * of them have returned match. - */ -public class AggregateEventTrigger extends EventTrigger -{ - protected final List _triggers; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger - */ - public AggregateEventTrigger() - { - _triggers = new ArrayList(); - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the list - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public AggregateEventTrigger(List triggers) - { - _triggers = new ArrayList(triggers); - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the array - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public AggregateEventTrigger(EventTrigger... triggers) - { - _triggers = Arrays.asList(triggers); - } - - /* ------------------------------------------------------------ */ - public void add(EventTrigger trigger) - { - _triggers.add(trigger); - } - - /* ------------------------------------------------------------ */ - public void addAll(List triggers) - { - _triggers.addAll(triggers); - } - - /* ------------------------------------------------------------ */ - public void addAll(EventTrigger... triggers) - { - _triggers.addAll(Arrays.asList(triggers)); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. This event trigger retrieves - * the combined event state of all aggregated event triggers. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - public EventState getState(long timestamp) - { - EventState state = new EventState(); - - for (EventTrigger trigger : _triggers) - { - EventState subState = trigger.getState(timestamp); - if (subState != null) - { - state.addAll(subState.values()); - } - } - - return state; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - @Override - public boolean match(long timestamp) throws Exception - { - boolean result = false; - for(EventTrigger trigger : _triggers) - { - result = trigger.match(timestamp) ? true : result; - } - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "AND(triger1,trigger2,...)". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - result.append("ANY("); - for (EventTrigger trigger : _triggers) - { - result.append(cnt++ > 0 ? "," : ""); - result.append(trigger); - } - result.append(')'); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java deleted file mode 100644 index 5f2cf982a2d..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java +++ /dev/null @@ -1,134 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; - - - -/* ------------------------------------------------------------ */ -/** - * AndEventTrigger - * - * EventTrigger aggregation using logical AND operation - * that executes matching of the aggregated event triggers - * in left to right order - */ -public class AndEventTrigger extends EventTrigger -{ - protected final List _triggers; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the list - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public AndEventTrigger(List triggers) - { - _triggers = triggers; - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the array - * of event triggers to be aggregated by this trigger - * - * @param triggers array of event triggers to add - */ - public AndEventTrigger(EventTrigger... triggers) - { - _triggers = Arrays.asList(triggers); - } - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * This event trigger will match if all aggregated - * event triggers would return a match. - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - public boolean match(long timestamp) - throws Exception - { - for(EventTrigger trigger : _triggers) - { - if (!trigger.match(timestamp)) - return false; - } - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. This event trigger retrieves - * the combined event state of all aggregated event triggers. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - public EventState getState(long timestamp) - { - EventState state = new EventState(); - - for (EventTrigger trigger : _triggers) - { - EventState subState = trigger.getState(timestamp); - state.addAll(subState.values()); - } - - return state; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "AND(triger1,trigger2,...)". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - result.append("AND("); - for (EventTrigger trigger : _triggers) - { - result.append(cnt++ > 0 ? "," : ""); - result.append(trigger); - } - result.append(')'); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java deleted file mode 100644 index 02169a68b12..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java +++ /dev/null @@ -1,240 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.openmbean.CompositeData; - -import org.eclipse.jetty.monitor.JMXMonitor; -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * AttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute - * and matches every invocation of this trigger. It can be - * used to send notifications of the value of an attribute - * of the MXBean being polled at a certain interval, or as - * a base class for the event triggers that match the - * value of an attribute of the MXBean being polled against - * some specified criteria. - * @param the event trigger type - */ -public class AttrEventTrigger> - extends EventTrigger -{ - private static final Logger LOG = Log.getLogger(AttrEventTrigger.class); - - private final ObjectName _nameObject; - - protected final String _objectName; - protected final String _attributeName; - protected Map> _states; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * - * @throws MalformedObjectNameException if unable to find object due to malformed name reference - * @throws IllegalArgumentException if parameters are invalid - */ - public AttrEventTrigger(String objectName, String attributeName) - throws MalformedObjectNameException, IllegalArgumentException - { - if (objectName == null) - throw new IllegalArgumentException("Object name cannot be null"); - if (attributeName == null) - throw new IllegalArgumentException("Attribute name cannot be null"); - - _states = new ConcurrentHashMap>(); - - _objectName = objectName; - _attributeName = attributeName; - - _nameObject = new ObjectName(_objectName); - } - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger. - * - * @param nameObject object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * - * @throws IllegalArgumentException if parameters are invalid - */ - public AttrEventTrigger(ObjectName nameObject, String attributeName) - throws IllegalArgumentException - { - if (nameObject == null) - throw new IllegalArgumentException("Object name cannot be null"); - if (attributeName == null) - throw new IllegalArgumentException("Attribute name cannot be null"); - - _states = new ConcurrentHashMap>(); - - _objectName = nameObject.toString(); - _attributeName = attributeName; - - _nameObject = nameObject; - } - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * This event trigger uses the match(Comparable<TYPE>) - * method to compare the value of the MXBean attribute - * to the conditions specified by the subclasses. - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - @SuppressWarnings("unchecked") - public final boolean match(long timestamp) - throws Exception - { - MBeanServerConnection serverConnection = JMXMonitor.getServiceConnection(); - - TYPE value = null; - try - { - int pos = _attributeName.indexOf('.'); - if (pos < 0) - value = (TYPE)serverConnection.getAttribute(_nameObject,_attributeName); - else - value = getValue((CompositeData)serverConnection.getAttribute(_nameObject, _attributeName.substring(0, pos)), - _attributeName.substring(pos+1)); - } - catch (Exception ex) - { - LOG.debug(ex); - } - - boolean result = false; - if (value != null) - { - result = match(value); - - if (result || getSaveAll()) - { - _states.put(timestamp, - new EventState(this.getID(), this.getNameString(), value)); - } - } - - return result; - } - - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * Allows subclasses to override the default behavior - * that matches every invocation of this trigger - * @param value the value to match - * @return always true - */ - public boolean match(Comparable value) - { - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - public final EventState getState(long timestamp) - { - return _states.get(timestamp); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "[object_name:attribute_name]". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - return getNameString(); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "[object_name:attribute_name]". Allows - * subclasses to override the name string used to identify - * this event trigger in the event state object as well as - * string representation of the subclasses. - * - * @return string representation of the event trigger - */ - protected String getNameString() - { - StringBuilder result = new StringBuilder(); - - result.append('['); - result.append(_objectName); - result.append(":"); - result.append(_attributeName); - result.append("]"); - - return result.toString(); - } - - protected boolean getSaveAll() - { - return true; - } - - protected TYPE getValue(CompositeData compValue, String fieldName) - { - int pos = fieldName.indexOf('.'); - if (pos < 0) - return (TYPE)compValue.get(fieldName); - else - return getValue((CompositeData)compValue.get(fieldName.substring(0, pos)), - fieldName.substring(pos+1)); - - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java deleted file mode 100644 index 48aca3c5743..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java +++ /dev/null @@ -1,89 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - - -/** - * EqualToAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is equal to specified value. - * @param the event trigger type - */ -public class EqualToAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _value; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as the - * target value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param value target value of the attribute - * - * @throws MalformedObjectNameException if unable to find object due to name issue - * @throws IllegalArgumentException on invalid parameters - */ - public EqualToAttrEventTrigger(String objectName, String attributeName, TYPE value) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (value == null) - throw new IllegalArgumentException("Value cannot be null"); - - _value = value; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is equal to the specified value. - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_value) == 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "name=value". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(getNameString()); - result.append("=="); - result.append(_value); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java deleted file mode 100644 index a091a660dfd..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * GreaterThanAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is greater than specified min value. - * @param event trigger type - */ -public class GreaterThanAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public GreaterThanAttrEventTrigger(String objectName, String attributeName, TYPE min) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is greater than the min value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) > 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<name". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<"); - result.append(getNameString()); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java deleted file mode 100644 index c6383633d79..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * GreaterThanOrEqualToAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is greater than or equal to specified min value. - * @param event trigger type - */ -public class GreaterThanOrEqualToAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public GreaterThanOrEqualToAttrEventTrigger(String objectName, String attributeName, TYPE min) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is greater than or equal to the min value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) >= 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<=name". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<="); - result.append(getNameString()); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java deleted file mode 100644 index 7457e628a75..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * LessThanAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is greater than specified max value. - * @param event trigger type - */ -public class LessThanAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as max - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public LessThanAttrEventTrigger(String objectName, String attributeName, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is less than the min value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_max) < 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "name<max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(getNameString()); - result.append("<"); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java deleted file mode 100644 index de35ee34d79..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - - -/** - * LessThanOrEqualToAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is less than or equal to specified max value. - * @param event trigger type - */ -public class LessThanOrEqualToAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as max - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public LessThanOrEqualToAttrEventTrigger(String objectName, String attributeName, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is less than or equal to the max value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_max) <= 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "name<=max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(getNameString()); - result.append("<="); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java deleted file mode 100644 index 31ac0496eb0..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java +++ /dev/null @@ -1,138 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; - - -/* ------------------------------------------------------------ */ -/** - * AndEventTrigger - * - * EventTrigger aggregation using logical OR operation - * that executes matching of the aggregated event triggers - * in left to right order - */ -public class OrEventTrigger - extends EventTrigger -{ - private final List _triggers; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the list - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public OrEventTrigger(List triggers) - { - _triggers = triggers; - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the array - * of event triggers to be aggregated by this trigger - * - * @param triggers array of event triggers to add - */ - public OrEventTrigger(EventTrigger... triggers) - { - _triggers = Arrays.asList(triggers); - } - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * This event trigger will match if any of aggregated - * event triggers would return a match. - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - public boolean match(long timestamp) - throws Exception - { - for(EventTrigger trigger : _triggers) - { - if (trigger.match(timestamp)) - return true; - } - return false; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. This event trigger retrieves - * the combined event state of all aggregated event triggers. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - @SuppressWarnings("unchecked") - public EventState getState(long timestamp) - { - EventState state = new EventState(); - - for (EventTrigger trigger : _triggers) - { - EventState subState = trigger.getState(timestamp); - if (subState!=null) - { - state.addAll(subState.values()); - } - } - - return state; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "OR(triger1,trigger2,...)". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - result.append("OR("); - for (EventTrigger trigger : _triggers) - { - result.append(cnt++ > 0 ? "," : ""); - result.append(trigger); - } - result.append(')'); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java deleted file mode 100644 index bb3953befa1..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * RangeAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is in a range from specified min value to - * specified max value. - * @param event trigger type - */ -public class RangeAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * and max value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public RangeAttrEventTrigger(String objectName, String attributeName,TYPE min, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is in a range from specified min value to - * specified max value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) > 0) &&(value.compareTo(_max) < 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<name<max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<"); - result.append(getNameString()); - result.append("<"); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java deleted file mode 100644 index 748fd7d4db0..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * RangeInclAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is in a range from specified min value to - * specified max value including the range bounds. - * @param event trigger type - */ -public class RangeInclAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * and max value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public RangeInclAttrEventTrigger(String objectName, String attributeName,TYPE min, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is in a range from specified min value to - * specified max value including the range bounds. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) >= 0) &&(value.compareTo(_max) <= 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<=name<=max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<="); - result.append(getNameString()); - result.append("<="); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java deleted file mode 100644 index 3f0ed871310..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Triggers for Monitor Events - */ -package org.eclipse.jetty.monitor.triggers; - diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java deleted file mode 100644 index bcb0fc2ea0c..00000000000 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java +++ /dev/null @@ -1,526 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.management.ManagementFactory; -import java.util.Collection; -import java.util.Iterator; -import java.util.TreeSet; - -import javax.management.MBeanServer; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.jmx.MBeanContainer; -import org.eclipse.jetty.monitor.jmx.ConsoleNotifier; -import org.eclipse.jetty.monitor.jmx.EventNotifier; -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventState.TriggerState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; -import org.eclipse.jetty.monitor.jmx.MonitorAction; -import org.eclipse.jetty.monitor.triggers.AndEventTrigger; -import org.eclipse.jetty.monitor.triggers.AttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.EqualToAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.GreaterThanAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.GreaterThanOrEqualToAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.LessThanAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.LessThanOrEqualToAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.OrEventTrigger; -import org.eclipse.jetty.monitor.triggers.RangeAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.RangeInclAttrEventTrigger; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - - -/* ------------------------------------------------------------ */ -/** - */ -public class AttrEventTriggerTest -{ - private static final Logger LOG = Log.getLogger(AttrEventTriggerTest.class); - - private Server _server; - private TestHandler _handler; - private RequestCounter _counter; - private JMXMonitor _monitor; - private HttpClient _client; - private String _requestUrl; - private MBeanContainer _mBeanContainer; - - @Before - public void setUp() - throws Exception - { - File docRoot = new File("target/test-output/docroot/"); - docRoot.mkdirs(); - docRoot.deleteOnExit(); - - System.setProperty("org.eclipse.jetty.util.log.DEBUG",""); - _server = new Server(); - - ServerConnector connector = new ServerConnector(_server); - connector.setPort(0); - _server.setConnectors(new Connector[] {connector}); - - _handler = new TestHandler(); - _server.setHandler(_handler); - - MBeanContainer.resetUnique(); - MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); - _mBeanContainer = new MBeanContainer(mBeanServer); - _server.addBean(_mBeanContainer,true); - _server.addBean(Log.getLog()); - - _counter = _handler.getRequestCounter(); - _server.addBean(_counter); - - _server.start(); - - startClient(); - - _monitor = new JMXMonitor(); - - int port = connector.getLocalPort(); - _requestUrl = "http://localhost:"+port+ "/"; - } - - @After - public void tearDown() - throws Exception - { - stopClient(); - - _mBeanContainer.destroy(); - - if (_server != null) - { - _server.stop(); - _server = null; - } - } - - @Test - public void testNoCondition() - throws Exception - { - long requestCount = 10; - - AttrEventTrigger trigger = - new AttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter"); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,requestCount); - assertEquals(result, action.getHits()); - } - - @Test - public void testEqual_TRUE() - throws Exception - { - long requestCount = 10; - long testValue = 5; - - EqualToAttrEventTrigger trigger = - new EqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",testValue); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testValue); - assertEquals(result, action.getHits()); - } - - @Test - public void testEqual_FALSE() - throws Exception - { - long requestCount = 10; - long testValue = 11; - - EqualToAttrEventTrigger trigger = - new EqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testValue); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(); - assertEquals(result, action.getHits()); - } - - @Test - public void testLowerLimit() - throws Exception - { - long requestCount = 10; - long testRangeLow = 5; - - GreaterThanAttrEventTrigger trigger = - new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(6,10); - assertEquals(result, action.getHits()); - } - - @Test - public void testLowerLimitIncl() - throws Exception - { - long requestCount = 10; - long testRangeLow = 5; - - GreaterThanOrEqualToAttrEventTrigger trigger = - new GreaterThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(5,10); - assertEquals(result, action.getHits()); - } - - @Test - public void testUpperLimit() - throws Exception - { - long requestCount = 10; - long testRangeHigh = 5; - - LessThanAttrEventTrigger trigger = - new LessThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,4); - assertEquals(result, action.getHits()); - } - - - @Test - public void testUpperLimitIncl() - throws Exception - { - long requestCount = 10; - long testRangeHigh = 5; - - LessThanOrEqualToAttrEventTrigger trigger = - new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,5); - assertEquals(result, action.getHits()); - } - - @Test - public void testRangeInclusive() - throws Exception - { - long requestCount = 10; - long testRangeLow = 3; - long testRangeHigh = 8; - - RangeInclAttrEventTrigger trigger = - new RangeInclAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow, testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testRangeLow,testRangeHigh); - assertEquals(result, action.getHits()); - } - - @Test - public void testInsideRangeExclusive() - throws Exception - { - long requestCount = 10; - long testRangeLow = 3; - long testRangeHigh = 8; - - RangeAttrEventTrigger trigger = - new RangeAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow, testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh-1); - assertEquals(result, action.getHits()); - } - - @Test - public void testRangeComposite() - throws Exception - { - long requestCount = 10; - long testRangeLow = 4; - long testRangeHigh = 7; - - GreaterThanAttrEventTrigger trigger1 = - new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - LessThanOrEqualToAttrEventTrigger trigger2 = - new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - AndEventTrigger trigger = new AndEventTrigger(trigger1, trigger2); - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh); - assertEquals(result, action.getHits()); - } - - @Test - public void testRangeOuter() - throws Exception - { - long requestCount = 10; - long testRangeLow = 4; - long testRangeHigh = 7; - - LessThanOrEqualToAttrEventTrigger trigger1 = - new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - GreaterThanAttrEventTrigger trigger2 = - new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - OrEventTrigger trigger = new OrEventTrigger(trigger1, trigger2); - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,testRangeLow,testRangeHigh+1, requestCount); - assertEquals(result, action.getHits()); - } - - protected void performTest(MonitorAction action, long count, long interval) - throws Exception - { - _monitor.addActions(action); - - for (long cnt=0; cnt < count; cnt++) - { - try - { - //LOG.debug("Request: %s", _requestUrl); - ContentResponse r3sponse = _client.GET(_requestUrl); - - //ContentExchange getExchange = new ContentExchange(); - //getExchange.setURL(_requestUrl); - //getExchange.setMethod(HttpMethods.GET); - - //_client.send(getExchange); - //int state = getExchange.waitForDone(); - - String content = ""; - //int responseStatus = getExchange.getResponseStatus(); - if (r3sponse.getStatus() == HttpStatus.OK_200) - { - content = r3sponse.getContentAsString(); - } - else - { - LOG.info("response status", r3sponse.getStatus()); - } - - assertEquals(HttpStatus.OK_200,r3sponse.getStatus()); - Thread.sleep(interval); - } - catch (InterruptedException ex) - { - break; - } - } - - Thread.sleep(interval); - - _monitor.removeActions(action); - } - - protected void startClient()//Realm realm) - throws Exception - { - _client = new HttpClient(); - //_client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); - //if (realm != null){ -// _client.setRealmResolver(new SimpleRealmResolver(realm)); - //} - _client.start(); - } - - protected void stopClient() - throws Exception - { - if (_client != null) - { - _client.stop(); - _client = null; - } - } - - protected static class TestHandler - extends AbstractHandler - { - private RequestCounter _counter = new RequestCounter(); - - public void handle(String target, Request baseRequest, - HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException - { - if (baseRequest.isHandled()) { - return; - } - _counter.increment(); - - response.setContentType("text/plain"); - response.setStatus(HttpServletResponse.SC_OK); - PrintWriter writer = response.getWriter(); - writer.println("===TEST RESPONSE==="); - baseRequest.setHandled(true); - } - - public RequestCounter getRequestCounter() - { - return _counter; - } - } - - protected static class ResultSet extends TreeSet - { - public ResultSet() {} - - public ResultSet(long value) - { - add(value); - } - - public ResultSet(long start, long end) - { - addEntries(start, end); - } - - public ResultSet(long start, long pause, long resume, long end) - { - addEntries(start, pause); - addEntries(resume, end); - } - - public void addEntries(long start, long stop) - { - if (start > 0 && stop > 0) - { - for(long idx=start; idx <= stop; idx++) - { - add(idx); - } - } - } - - public boolean equals(ResultSet set) - { - return (this.size() == set.size()) && containsAll(set); - } - } - - protected static class CounterAction - extends MonitorAction - { - private ResultSet _hits = new ResultSet(); - - public CounterAction(EventTrigger trigger, EventNotifier notifier, long interval, long delay) - { - super(trigger, notifier, interval, delay); - } - - public void execute(EventTrigger trigger, EventState state, long timestamp) - { - if (trigger != null && state != null) - { - Collection values = state.values(); - - Iterator it = values.iterator(); - while(it.hasNext()) - { - TriggerState entry = (TriggerState)it.next(); - Object value = entry.getValue(); - if (value != null) - { - _hits.add((Long)value); - } - } - } - } - - public ResultSet getHits() - { - return _hits; - } - } -} diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java deleted file mode 100644 index 934238f1604..00000000000 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import org.eclipse.jetty.util.annotation.ManagedAttribute; -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.annotation.ManagedOperation; - - -@ManagedObject("TEST: Request Counter") -public class RequestCounter -{ - public long _counter; - - @ManagedAttribute("Get the value of the counter") - public synchronized long getCounter() - { - return _counter; - } - - @ManagedOperation("Increment the value of the counter") - public synchronized void increment() - { - _counter++; - } - - @ManagedOperation("Reset the counter") - public synchronized void reset() - { - _counter = 0; - } -} diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java deleted file mode 100644 index 6072763179e..00000000000 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java +++ /dev/null @@ -1,165 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.StacklessLogging; -import org.junit.Ignore; -import org.junit.Test; - - -/* ------------------------------------------------------------ */ -/** - */ -public class ThreadMonitorTest -{ - public final static int DURATION=4000; - - @Ignore - @Test - public void monitorTest() throws Exception - { - try(StacklessLogging stackless=new StacklessLogging(ThreadMonitor.class)) - { - - final AtomicInteger countLogs=new AtomicInteger(0); - final AtomicInteger countSpin=new AtomicInteger(0); - - ThreadMonitor monitor = new ThreadMonitor(1000,50,1,1) - { - @Override - protected void logThreadInfo(boolean logAll) - { - if (logAll) - countLogs.incrementAndGet(); - else - countSpin.incrementAndGet(); - super.logThreadInfo(logAll); - } - }; - monitor.setDumpable(new Dumpable() - { - public void dump(Appendable out, String indent) throws IOException - { - out.append(dump()); - } - - public String dump() - { - return "Dump Spinning"; - } - }); - - monitor.logCpuUsage(2000,0); - monitor.start(); - - Random rnd = new Random(); - for (long cnt=0; cnt<100; cnt++) - { - long value = rnd.nextLong() % 50 + 50; - Sleeper sleeper = new Sleeper(value); - Thread runner = new Thread(sleeper); - runner.setDaemon(true); - runner.start(); - } - - Spinner spinner = new Spinner(); - Thread runner = new Thread(spinner); - runner.start(); - - Thread.sleep(DURATION); - - spinner.setDone(); - monitor.stop(); - - assertTrue(countLogs.get() >= 1); - assertTrue(countSpin.get() >= 2); - } - } - - - private class Spinner implements Runnable - { - private volatile boolean done = false; - - /* ------------------------------------------------------------ */ - public void setDone() - { - done = true; - } - - /* ------------------------------------------------------------ */ - public void run() - { - spin(); - } - - /* ------------------------------------------------------------ */ - public void spin() - { - long result=-1; - long end=TimeUnit.NANOSECONDS.toMillis(System.nanoTime())+DURATION+1000; - while (!done && TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) 1 ? fn(value-1) : 1; - - Thread.sleep(50); - - return result; - } - } -} diff --git a/jetty-monitor/src/test/resources/jetty-logging.properties b/jetty-monitor/src/test/resources/jetty-logging.properties deleted file mode 100644 index 2071498c3d6..00000000000 --- a/jetty-monitor/src/test/resources/jetty-logging.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -#org.eclipse.jetty.LEVEL=DEBUG -#org.eclipse.jetty.monitor.LEVEL=DEBUG From 01e8cf440ecc710dc0e2ab39e4570b690770ac50 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2018 10:12:44 +1100 Subject: [PATCH 43/87] Safer simpler version parsing #2284 For #2284 no longer parse the optional detail of the java version. Parse failures will result in a guessed JVM platform 8 Signed-off-by: Greg Wilkins --- .../org/eclipse/jetty/util/JavaVersion.java | 93 +++---------------- .../eclipse/jetty/util/JavaVersionTest.java | 35 +++---- 2 files changed, 25 insertions(+), 103 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java index ae9201906c3..69117e6ddae 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java @@ -34,23 +34,20 @@ public class JavaVersion public static final String JAVA_TARGET_PLATFORM = "org.eclipse.jetty.javaTargetPlatform"; /** Regex for Java version numbers */ - private static final String VNUM = "(?[1-9][0-9]*(?:(?:\\.0)*\\.[0-9]+)*)"; - private static final String UPDATE = "(?:(?_)(?[0-9]+))?"; - private static final String PRE = "(?:-(?

    [a-zA-Z0-9]+))?";
    -    private static final String BUILD = "(?:(?\\+)(?[0-9]+))?";
    -    private static final String OPT = "(?:-(?[-a-zA-Z0-9.~]+))?";
    -
    -    private static final String VSTR_FORMAT = VNUM + UPDATE + PRE + BUILD + OPT;
    +    private static final String VSTR_FORMAT = "(?[1-9][0-9]*(?:(?:\\.0)*\\.[0-9]+)*).*";
     
         static final Pattern VSTR_PATTERN = Pattern.compile(VSTR_FORMAT);
         
    -    public static final JavaVersion VERSION = parse(System.getProperty("java.runtime.version",System.getProperty("java.version")));
    -
    +    public static final JavaVersion VERSION = parse(System.getProperty("java.runtime.version",System.getProperty("java.version","1.8")));
    +    
         public static JavaVersion parse(String v) 
         {
             Matcher m = VSTR_PATTERN.matcher(v);
    -        if (!m.matches())
    -            throw new IllegalArgumentException("Invalid version string: '" + v + "'");
    +        if (!m.matches() || m.group("VNUM")==null)
    +        {
    +            System.err.println("ERROR: Invalid version string: '" + v + "'");
    +            return new JavaVersion(v+"-UNKNOWN",8,1,8,0);
    +        }
             
             // $VNUM is a dot-separated list of integers of arbitrary length
             String[] split = m.group("VNUM").split("\\.");
    @@ -58,72 +55,12 @@ public class JavaVersion
             for (int i = 0; i < split.length; i++)
                 version[i] = Integer.parseInt(split[i]);
     
    -        if (m.group("UNDERSCORE")!=null)
    -        {
    -            return new JavaVersion(
    -                    v,
    -                    (version[0]>=9 || version.length==1)?version[0]:version[1],
    -                    version[0],
    -                    version.length>1?version[1]:0,
    -                    version.length>2?version[2]:0,
    -                    Integer.parseInt(m.group("UPDATE")),
    -                    suffix(version,m.group("PRE"),m.group("OPT"))
    -                    );
    -        }
    -        
    -        if (m.group("PLUS")!=null)
    -        {
    -            return new JavaVersion(
    -                    v,
    -                    (version[0]>=9 || version.length==1)?version[0]:version[1],
    -                    version[0],
    -                    version.length>1?version[1]:0,
    -                    version.length>2?version[2]:0,
    -                    Integer.parseInt(m.group("BUILD")),
    -                    suffix(version,m.group("PRE"),m.group("OPT"))
    -                    );
    -        }
    -
             return new JavaVersion(
                     v,
                     (version[0]>=9 || version.length==1)?version[0]:version[1],
                     version[0],
                     version.length>1?version[1]:0,
    -                version.length>2?version[2]:0,
    -                0,
    -                suffix(version,m.group("PRE"),m.group("OPT"))
    -                );
    -        
    -    }
    -
    -    private static String suffix(int[] version, String pre, String opt)
    -    {
    -        StringBuilder buf = new StringBuilder();
    -        for (int i=3;i3)
    -                buf.append(".");
    -            buf.append(version[i]);
    -        }
    -               
    -        if (pre!=null)
    -        {
    -            if (buf.length()>0)
    -                buf.append('-');
    -            buf.append(pre);
    -        }
    -        
    -        if (opt!=null)
    -        {
    -            if (buf.length()>0)
    -                buf.append('-');
    -            buf.append(opt);
    -        }
    -        
    -        if (buf.length()==0)
    -            return null;
    -        
    -        return buf.toString();
    +                version.length>2?version[2]:0);
         }
         
         private final String version;
    @@ -131,18 +68,14 @@ public class JavaVersion
         private final int major;
         private final int minor;
         private final int micro;
    -    private final int update;
    -    private final String suffix;
     
    -    private JavaVersion(String version, int platform, int major, int minor, int micro, int update, String suffix)
    +    private JavaVersion(String version, int platform, int major, int minor, int micro)
         {
             this.version = version;
             this.platform = platform;
             this.major = major;
             this.minor = minor;
             this.micro = micro;
    -        this.update = update;
    -        this.suffix = suffix;
         }
     
         /**
    @@ -198,9 +131,10 @@ public class JavaVersion
          *
          * @return the update number version
          */
    +    @Deprecated
         public int getUpdate()
         {
    -        return update;
    +        return 0;
         }
     
         /**
    @@ -209,9 +143,10 @@ public class JavaVersion
          *
          * @return the remaining string after the version numbers
          */
    +    @Deprecated
         public String getSuffix()
         {
    -        return suffix;
    +        return null;
         }
     
         @Override
    diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java
    index 3c47bf4a353..bf1640c812e 100644
    --- a/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java
    +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java
    @@ -19,7 +19,6 @@
     package org.eclipse.jetty.util;
     
     import static org.hamcrest.Matchers.is;
    -import static org.hamcrest.Matchers.nullValue;
     import static org.junit.Assert.assertThat;
     
     import org.junit.Test;
    @@ -33,132 +32,120 @@ public class JavaVersionTest
         public void test9()
         {
             JavaVersion version = JavaVersion.parse("9.0.1");
    +        assertThat(version.toString(),is("9.0.1"));
             assertThat(version.getPlatform(),is(9));
             assertThat(version.getMajor(),is(9));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(0));
    -        assertThat(version.getSuffix(),nullValue());
         }
         
         @Test
         public void test9nano()
         {
             JavaVersion version = JavaVersion.parse("9.0.1.3");
    +        assertThat(version.toString(),is("9.0.1.3"));
             assertThat(version.getPlatform(),is(9));
             assertThat(version.getMajor(),is(9));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(0));
    -        assertThat(version.getSuffix(),is("3"));
         }
         
         @Test
         public void test9build()
         {
             JavaVersion version = JavaVersion.parse("9.0.1+11");
    +        assertThat(version.toString(),is("9.0.1+11"));
             assertThat(version.getPlatform(),is(9));
             assertThat(version.getMajor(),is(9));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(11));
    -        assertThat(version.getSuffix(),nullValue());
         }
         
         @Test
         public void test9all()
         {
             JavaVersion version = JavaVersion.parse("9.0.1-ea+11-b01");
    +        assertThat(version.toString(),is("9.0.1-ea+11-b01"));
             assertThat(version.getPlatform(),is(9));
             assertThat(version.getMajor(),is(9));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(11));
    -        assertThat(version.getSuffix(),is("ea-b01"));
         }
         
         @Test
         public void test9yuck()
         {
             JavaVersion version = JavaVersion.parse("9.0.1.2.3-ea+11-b01");
    +        assertThat(version.toString(),is("9.0.1.2.3-ea+11-b01"));
             assertThat(version.getPlatform(),is(9));
             assertThat(version.getMajor(),is(9));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(11));
    -        assertThat(version.getSuffix(),is("2.3-ea-b01"));
         }
         
         @Test
         public void test10ea()
         {
             JavaVersion version = JavaVersion.parse("10-ea");
    +        assertThat(version.toString(),is("10-ea"));
             assertThat(version.getPlatform(),is(10));
             assertThat(version.getMajor(),is(10));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(0));
    -        assertThat(version.getUpdate(),is(0));
    -        assertThat(version.getSuffix(),is("ea"));
         }
         
         @Test
         public void test8()
         {
             JavaVersion version = JavaVersion.parse("1.8.0_152");
    +        assertThat(version.toString(),is("1.8.0_152"));
             assertThat(version.getPlatform(),is(8));
             assertThat(version.getMajor(),is(1));
             assertThat(version.getMinor(),is(8));
             assertThat(version.getMicro(),is(0));
    -        assertThat(version.getUpdate(),is(152));
    -        assertThat(version.getSuffix(),nullValue()); 
         }
     
         @Test
         public void test8ea()
         {
             JavaVersion version = JavaVersion.parse("1.8.1_03-ea");
    +        assertThat(version.toString(),is("1.8.1_03-ea"));
             assertThat(version.getPlatform(),is(8));
             assertThat(version.getMajor(),is(1));
             assertThat(version.getMinor(),is(8));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(3));
    -        assertThat(version.getSuffix(),is("ea")); 
         }
         
         @Test
         public void test3eaBuild()
         {
             JavaVersion version = JavaVersion.parse("1.3.1_05-ea-b01");
    +        assertThat(version.toString(),is("1.3.1_05-ea-b01"));
             assertThat(version.getPlatform(),is(3));
             assertThat(version.getMajor(),is(1));
             assertThat(version.getMinor(),is(3));
             assertThat(version.getMicro(),is(1));
    -        assertThat(version.getUpdate(),is(5));
    -        assertThat(version.getSuffix(),is("ea-b01")); 
         }
         
         @Test
         public void testUbuntu()
         {
             JavaVersion version = JavaVersion.parse("9-Ubuntu+0-9b181-4");
    +        assertThat(version.toString(),is("9-Ubuntu+0-9b181-4"));
             assertThat(version.getPlatform(),is(9));
             assertThat(version.getMajor(),is(9));
             assertThat(version.getMinor(),is(0));
             assertThat(version.getMicro(),is(0));
    -        assertThat(version.getUpdate(),is(0));
    -        assertThat(version.getSuffix(),is("Ubuntu-9b181-4")); 
         }
         
         @Test
         public void testUbuntu8()
         {
    -        JavaVersion version = JavaVersion.parse("1.8.0_151-8u151-b12-1~deb9u1-b12");
    +        JavaVersion version = JavaVersion.parse("1.8.0_151-8u151-b12-1~deb9u1-b12");assertThat(version.toString(),is("1.8.0_151-8u151-b12-1~deb9u1-b12"));
             assertThat(version.getPlatform(),is(8));
             assertThat(version.getMajor(),is(1));
             assertThat(version.getMinor(),is(8));
             assertThat(version.getMicro(),is(0));
    -        assertThat(version.getUpdate(),is(151));
    -        assertThat(version.getSuffix(),is("8u151-b12-1~deb9u1-b12")); 
         }
         
     }
    
    From faf5a54ca6a4c00d6574373ee5193ac46f5bbffd Mon Sep 17 00:00:00 2001
    From: Greg Wilkins 
    Date: Wed, 14 Mar 2018 10:23:19 +1100
    Subject: [PATCH 44/87] removed unused jetty-monitor #2308
    
    Signed-off-by: Greg Wilkins 
    ---
     jetty-monitor/README.TXT                      |  13 -
     jetty-monitor/pom.xml                         |  84 ---
     .../src/main/config/etc/jetty-monitor.xml     |  30 -
     .../src/main/config/modules/monitor.mod       |  13 -
     .../org/eclipse/jetty/monitor/JMXMonitor.java | 193 ------
     .../eclipse/jetty/monitor/ThreadMonitor.java  | 610 ------------------
     .../integration/JavaMonitorAction.java        | 409 ------------
     .../monitor/integration/JavaMonitorTools.java | 288 ---------
     .../integration/JavaMonitorTrigger.java       |  74 ---
     .../monitor/integration/package-info.java     |  23 -
     .../jetty/monitor/jmx/ConsoleNotifier.java    |  61 --
     .../jetty/monitor/jmx/EventNotifier.java      |  40 --
     .../eclipse/jetty/monitor/jmx/EventState.java | 209 ------
     .../jetty/monitor/jmx/EventTrigger.java       |  76 ---
     .../jetty/monitor/jmx/LoggingNotifier.java    |  65 --
     .../jetty/monitor/jmx/MonitorAction.java      | 179 -----
     .../jetty/monitor/jmx/MonitorTask.java        | 119 ----
     .../jetty/monitor/jmx/NotifierGroup.java      | 119 ----
     .../jetty/monitor/jmx/ServiceConnection.java  | 172 -----
     .../jetty/monitor/jmx/SimpleAction.java       |  46 --
     .../jetty/monitor/jmx/package-info.java       |  23 -
     .../eclipse/jetty/monitor/package-info.java   |  23 -
     .../thread/ThreadMonitorException.java        |  34 -
     .../monitor/thread/ThreadMonitorInfo.java     | 202 ------
     .../jetty/monitor/thread/package-info.java    |  23 -
     .../triggers/AggregateEventTrigger.java       | 159 -----
     .../monitor/triggers/AndEventTrigger.java     | 134 ----
     .../monitor/triggers/AttrEventTrigger.java    | 240 -------
     .../triggers/EqualToAttrEventTrigger.java     |  89 ---
     .../triggers/GreaterThanAttrEventTrigger.java |  90 ---
     .../GreaterThanOrEqualToAttrEventTrigger.java |  90 ---
     .../triggers/LessThanAttrEventTrigger.java    |  90 ---
     .../LessThanOrEqualToAttrEventTrigger.java    |  91 ---
     .../monitor/triggers/OrEventTrigger.java      | 138 ----
     .../triggers/RangeAttrEventTrigger.java       |  99 ---
     .../triggers/RangeInclAttrEventTrigger.java   |  99 ---
     .../jetty/monitor/triggers/package-info.java  |  23 -
     .../jetty/monitor/AttrEventTriggerTest.java   | 526 ---------------
     .../eclipse/jetty/monitor/RequestCounter.java |  48 --
     .../jetty/monitor/ThreadMonitorTest.java      | 165 -----
     .../test/resources/jetty-logging.properties   |   3 -
     41 files changed, 5212 deletions(-)
     delete mode 100644 jetty-monitor/README.TXT
     delete mode 100644 jetty-monitor/pom.xml
     delete mode 100644 jetty-monitor/src/main/config/etc/jetty-monitor.xml
     delete mode 100644 jetty-monitor/src/main/config/modules/monitor.mod
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java
     delete mode 100644 jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java
     delete mode 100644 jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java
     delete mode 100644 jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java
     delete mode 100644 jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java
     delete mode 100644 jetty-monitor/src/test/resources/jetty-logging.properties
    
    diff --git a/jetty-monitor/README.TXT b/jetty-monitor/README.TXT
    deleted file mode 100644
    index 72c7da114f9..00000000000
    --- a/jetty-monitor/README.TXT
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -The ThreadMonitor is distributed as part of the jetty-monitor module. 
    -
    -In order to start ThreadMonitor when server starts up, the following command line should be used.
    -
    -    java -jar start.jar OPTIONS=monitor jetty-monitor.xml
    -
    -To run ThreadMonitor on a Jetty installation that doesn't include jetty-monitor module, the jetty-monitor-[version].jar file needs to be copied into ${jetty.home}/lib/ext directory, and jetty-monitor.xml configuration file needs to be copied into ${jetty.home}/etc directory. Subsequently, the following command line should be used.
    -
    -    java -jar start.jar etc/jetty-monitor.xml
    -
    -If running Jetty on Java VM version 1.5, the -Dcom.sun.management.jmxremote option should be added to the command lines above in order to enable the JMX agent.
    -
    -In order to log CPU utilization for threads that are above specified threshold, you need to follow instructions inside jetty-monitor.xml configuration file.
    \ No newline at end of file
    diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml
    deleted file mode 100644
    index 3374ec2e9e0..00000000000
    --- a/jetty-monitor/pom.xml
    +++ /dev/null
    @@ -1,84 +0,0 @@
    -
    -
    -  
    -    org.eclipse.jetty
    -    jetty-project
    -    9.4.0-SNAPSHOT
    -  
    -  4.0.0
    -  jetty-monitor
    -  Jetty :: Monitoring
    -  http://www.eclipse.org/jetty
    -  Performance monitoring artifact for jetty.
    -  
    -    ${project.groupId}.monitor
    -  
    -  
    -    
    -      
    -        org.apache.maven.plugins
    -        maven-surefire-plugin
    -        
    -          always
    -        
    -      
    -      
    -        org.codehaus.mojo
    -        findbugs-maven-plugin
    -        
    -          org.eclipse.jetty.monitor.*
    -        
    -      
    -    
    -  
    -  
    -    
    -      org.eclipse.jetty
    -      jetty-util
    -      ${project.version}
    -    
    -    
    -      org.eclipse.jetty
    -      jetty-io
    -      ${project.version}
    -    
    -    
    -      org.eclipse.jetty
    -      jetty-http
    -      ${project.version}
    -    
    -    
    -      org.eclipse.jetty
    -      jetty-xml
    -      ${project.version}
    -    
    -    
    -      org.eclipse.jetty
    -      jetty-client
    -      ${project.version}
    -    
    -    
    -      org.eclipse.jetty
    -      jetty-jmx
    -      ${project.version}
    -      test
    -    
    -    
    -    
    -      org.eclipse.jetty
    -      jetty-server
    -      ${project.version}
    -      test
    -    
    -    
    -      org.eclipse.jetty.toolchain
    -      jetty-test-helper
    -      test
    -    
    -  
    -
    diff --git a/jetty-monitor/src/main/config/etc/jetty-monitor.xml b/jetty-monitor/src/main/config/etc/jetty-monitor.xml
    deleted file mode 100644
    index a8f663367e4..00000000000
    --- a/jetty-monitor/src/main/config/etc/jetty-monitor.xml
    +++ /dev/null
    @@ -1,30 +0,0 @@
    -
    -
    -
    -
    -  
    -  
    -    
    -      
    -        2000
    -        90
    -        3
    -        2
    -        
    -        
    -        
    -        
    -
    -        
    -        
    -        
    -      
    -    
    -  
    -
    -
    diff --git a/jetty-monitor/src/main/config/modules/monitor.mod b/jetty-monitor/src/main/config/modules/monitor.mod
    deleted file mode 100644
    index f1fa81f98c1..00000000000
    --- a/jetty-monitor/src/main/config/modules/monitor.mod
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -[description]
    -Enables the Jetty Monitor Module to periodically
    -check/publish JMX parameters of the server.
    -
    -[depend]
    -server
    -client
    -
    -[lib]
    -lib/monitor/jetty-monitor-${jetty.version}.jar
    -
    -[xml]
    -etc/jetty-monitor.xml
    diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java
    deleted file mode 100644
    index 36db34f45f1..00000000000
    --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/JMXMonitor.java
    +++ /dev/null
    @@ -1,193 +0,0 @@
    -//
    -//  ========================================================================
    -//  Copyright (c) 1995-2018 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.monitor;
    -
    -import java.io.IOException;
    -import java.util.HashSet;
    -import java.util.Set;
    -
    -import javax.management.MBeanServerConnection;
    -
    -import org.eclipse.jetty.monitor.jmx.MonitorAction;
    -import org.eclipse.jetty.monitor.jmx.MonitorTask;
    -import org.eclipse.jetty.monitor.jmx.ServiceConnection;
    -import org.eclipse.jetty.xml.XmlConfiguration;
    -
    -/**
    - * JMXMonitor
    - * 

    - * Performs monitoring of the values of the attributes of MBeans - * and executes specified actions as well as sends notifications - * of the specified events that have occurred. - */ -public class JMXMonitor -{ - private static JMXMonitor __monitor = new JMXMonitor(); - - private String _serverUrl; - private ServiceConnection _serviceConnection; - - private Set _actions = new HashSet(); - - /* ------------------------------------------------------------ */ - /** - * Constructs a JMXMonitor instance. Used for XML Configuration. - * - * !! DO NOT INSTANTIATE EXPLICITLY !! - */ - public JMXMonitor() {} - - /* ------------------------------------------------------------ */ - /** - * Adds monitor actions to the monitor - * - * @param actions monitor actions to add - * @return true if successful - */ - public boolean addActions(MonitorAction... actions) - { - return getInstance().add(actions); - } - - /* ------------------------------------------------------------ */ - /** - * Removes monitor actions from the monitor - * - * @param actions monitor actions to remove - * @return true if successful - */ - public boolean removeActions(MonitorAction... actions) - { - return getInstance().remove(actions); - } - - /* ------------------------------------------------------------ */ - /** - * Sets the JMX server URL - * - * @param url URL of the JMX server - */ - public void setUrl(String url) - { - getInstance().set(url); - } - - public MBeanServerConnection getConnection() - throws IOException - { - return getInstance().get(); - } - - public static JMXMonitor getInstance() - { - return __monitor; - } - - public static boolean addMonitorActions(MonitorAction... actions) - { - return getInstance().add(actions); - } - - public static boolean removeMonitorActions(MonitorAction... actions) - { - return getInstance().remove(actions); - } - - public static void setServiceUrl(String url) - { - getInstance().set(url); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves a connection to JMX service - * - * @return server connection - * @throws IOException if unable to obtain server connection - */ - public static MBeanServerConnection getServiceConnection() - throws IOException - { - return getInstance().getConnection(); - } - - public static void main(final String args[]) throws Exception - { - XmlConfiguration.main(args); - } - - private synchronized boolean add(MonitorAction... actions) - { - boolean result = true; - - for (MonitorAction action : actions) - { - if (!_actions.add(action)) - { - result = false; - } - else - { - MonitorTask.schedule(action); - } - } - - return result; - } - - private synchronized boolean remove(MonitorAction... actions) - { - boolean result = true; - - for (MonitorAction action : actions) - { - if (!_actions.remove(action)) - { - result = false; - } - - MonitorTask.cancel(action); - } - - return result; - } - - private synchronized void set(String url) - { - _serverUrl = url; - - if (_serviceConnection != null) - { - _serviceConnection.disconnect(); - _serviceConnection = null; - } - } - - private synchronized MBeanServerConnection get() - throws IOException - { - if (_serviceConnection == null) - { - _serviceConnection = new ServiceConnection(_serverUrl); - _serviceConnection.connect(); - } - - return _serviceConnection.getConnection(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java deleted file mode 100644 index 02f77268962..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/ThreadMonitor.java +++ /dev/null @@ -1,610 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.jetty.monitor.thread.ThreadMonitorException; -import org.eclipse.jetty.monitor.thread.ThreadMonitorInfo; -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -@ManagedObject("Busy Thread Monitor") -public class ThreadMonitor extends AbstractLifeCycle implements Runnable -{ - private static final Logger LOG = Log.getLogger(ThreadMonitor.class); - - private int _scanInterval; - private int _logInterval; - private int _busyThreshold; - private int _logThreshold; - private int _stackDepth; - private int _trailLength; - - private ThreadMXBean _threadBean; - - private Thread _runner; - private Logger _logger; - private volatile boolean _done = true; - private Dumpable _dumpable; - - private Map _monitorInfo; - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor() throws Exception - { - this(5000); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs) throws Exception - { - this(intervalMs, 95); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @param threshold busy threshold - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs, int threshold) throws Exception - { - this(intervalMs, threshold, 3); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @param threshold busy threshold - * @param depth stack compare depth - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs, int threshold, int depth) throws Exception - { - this(intervalMs, threshold, depth, 3); - } - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor. - * - * @param intervalMs scan interval - * @param threshold busy threshold - * @param depth stack compare depth - * @param trail length of stack trail - * @throws Exception if unable to instantiate thread monitor - */ - public ThreadMonitor(int intervalMs, int threshold, int depth, int trail) throws Exception - { - _scanInterval = intervalMs; - _busyThreshold = threshold; - _stackDepth = depth; - _trailLength = trail; - - _logger = Log.getLogger(ThreadMonitor.class.getName()); - _monitorInfo = new HashMap(); - - init(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the scan interval. - * - * @return the scan interval - */ - public int getScanInterval() - { - return _scanInterval; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the scan interval. - * - * @param ms the new scan interval - */ - public void setScanInterval(int ms) - { - _scanInterval = ms; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the log interval. - * - * @return the log interval - */ - public int getLogInterval() - { - return _logInterval; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the log interval. - * - * @param ms the new log interval - */ - public void setLogInterval(int ms) - { - _logInterval = ms; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the busy threshold. - * - * @return the busy threshold - */ - public int getBusyThreshold() - { - return _busyThreshold; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the busy threshold. - * - * @param percent the new busy threshold - */ - public void setBusyThreshold(int percent) - { - _busyThreshold = percent; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the log threshold. - * - * @return the log threshold - */ - public int getLogThreshold() - { - return _logThreshold; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the log threshold. - * - * @param percent the new log threshold - */ - public void setLogThreshold(int percent) - { - _logThreshold = percent; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the stack depth. - * - * @return the stack depth - */ - public int getStackDepth() - { - return _stackDepth; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the stack depth. - * - * @param stackDepth the new stack depth - */ - public void setStackDepth(int stackDepth) - { - _stackDepth = stackDepth; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the stack trace trail length. - * - * @param trailLength the new trail length - */ - public void setTrailLength(int trailLength) - { - _trailLength = trailLength; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the stack trace trail length. - * - * @return the trail length - */ - public int getTrailLength() - { - return _trailLength; - } - - /* ------------------------------------------------------------ */ - /** - * Enable logging of CPU usage. - * - * @param frequencyMs the logging frequency - * @param thresholdPercent the logging threshold - */ - public void logCpuUsage(int frequencyMs, int thresholdPercent) - { - setLogInterval(frequencyMs); - setLogThreshold(thresholdPercent); - } - - /* ------------------------------------------------------------ */ - /** - * @return A {@link Dumpable} that is dumped whenever spinning threads are detected - */ - public Dumpable getDumpable() - { - return _dumpable; - } - - /* ------------------------------------------------------------ */ - /** - * @param dumpable A {@link Dumpable} that is dumped whenever spinning threads are detected - */ - public void setDumpable(Dumpable dumpable) - { - _dumpable = dumpable; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - public void doStart() - { - _done = false; - - _runner = new Thread(this); - _runner.setDaemon(true); - _runner.start(); - - LOG.info("Thread Monitor started successfully"); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() - */ - public void doStop() - { - if (_runner != null) - { - _done = true; - try - { - _runner.join(); - } - catch (InterruptedException ex) {} - - _monitorInfo.clear(); - } - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve all avaliable thread ids - * - * @return array of thread ids - */ - protected long[] getAllThreadIds() - { - return _threadBean.getAllThreadIds(); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the cpu time for specified thread. - * - * @param id thread id - * @return cpu time of the thread - */ - protected long getThreadCpuTime(long id) - { - return _threadBean.getThreadCpuTime(id); - } - - /* ------------------------------------------------------------ */ - /** - * Initialize JMX objects. - */ - protected void init() - { - _threadBean = ManagementFactory.getThreadMXBean(); - if (_threadBean.isThreadCpuTimeSupported()) - { - _threadBean.setThreadCpuTimeEnabled(true); - } - } - - /* ------------------------------------------------------------ */ - /** - * @see java.lang.Runnable#run() - */ - public void run() - { - // Initialize repeat flag - boolean repeat = false; - boolean scanNow, logNow; - - // Set next scan time and log time - long nextScanTime = System.currentTimeMillis(); - long nextLogTime = nextScanTime + _logInterval; - - while (!_done) - { - long currTime = System.currentTimeMillis(); - scanNow = (currTime > nextScanTime); - logNow = (_logInterval > 0 && currTime > nextLogTime); - if (repeat || scanNow || logNow) - { - repeat = collectThreadInfo(); - logThreadInfo(logNow); - - if (scanNow) - { - nextScanTime = System.currentTimeMillis() + _scanInterval; - } - if (logNow) - { - nextLogTime = System.currentTimeMillis() + _logInterval; - } - } - - // Sleep only if not going to repeat scanning immediately - if (!repeat) - { - try - { - Thread.sleep(100); - } - catch (InterruptedException ex) - { - LOG.ignore(ex); - } - } - } - - } - - /* ------------------------------------------------------------ */ - /** - * Collect thread info. - */ - private boolean collectThreadInfo() - { - boolean repeat = false; - try - { - // Retrieve stack traces for all threads at once as it - // was proven to be an order of magnitude faster when - // retrieving a single thread stack trace. - Map all = Thread.getAllStackTraces(); - - Set newOrUpdatedIds = new HashSet(); - - for (Map.Entry entry : all.entrySet()) - { - Thread thread = entry.getKey(); - long threadId = thread.getId(); - - // Skip our own runner thread - if (threadId == _runner.getId()) - { - continue; - } - - ThreadMonitorInfo currMonitorInfo = _monitorInfo.get(Long.valueOf(threadId)); - if (currMonitorInfo == null) - { - // Create thread info object for a new thread - currMonitorInfo = new ThreadMonitorInfo(thread); - currMonitorInfo.setStackTrace(entry.getValue()); - currMonitorInfo.setCpuTime(getThreadCpuTime(threadId)); - currMonitorInfo.setSampleTime(System.nanoTime()); - _monitorInfo.put(Long.valueOf(threadId), currMonitorInfo); - } - else - { - // Update the existing thread info object - currMonitorInfo.setStackTrace(entry.getValue()); - currMonitorInfo.setCpuTime(getThreadCpuTime(threadId)); - currMonitorInfo.setSampleTime(System.nanoTime()); - - // Stack trace count holds logging state - int count = currMonitorInfo.getTraceCount(); - if (count >= 0 && currMonitorInfo.isSpinning()) - { - // Thread was spinning and was logged before - if (count < _trailLength) - { - // Log another stack trace - currMonitorInfo.setTraceCount(count+1); - repeat = true; - continue; - } - - // Reset spin flag and trace count - currMonitorInfo.setSpinning(false); - currMonitorInfo.setTraceCount(-1); - } - if (currMonitorInfo.getCpuUtilization() > _busyThreshold) - { - // Thread is busy - StackTraceElement[] lastStackTrace = currMonitorInfo.getStackTrace(); - - if (lastStackTrace != null - && matchStackTraces(lastStackTrace, entry.getValue())) - { - // Thread is spinning - currMonitorInfo.setSpinning(true); - if (count < 0) - { - // Enable logging of spin status and stack traces - // only if the incoming trace count is negative - // that indicates a new scan for this thread - currMonitorInfo.setTraceCount(0); - repeat = (_trailLength > 0); - } - } - } - } - newOrUpdatedIds.add(Long.valueOf(threadId)); - } - - //clean out threads that no longer exist - Iterator iter = _monitorInfo.keySet().iterator(); - while (iter.hasNext()) - { - Long id = iter.next(); - if (!newOrUpdatedIds.contains(id)) - iter.remove(); - } - newOrUpdatedIds.clear(); - } - catch (Exception ex) - { - LOG.debug(ex); - } - return repeat; - } - - /* ------------------------------------------------------------ */ - protected void logThreadInfo(boolean logAll) - { - if (_monitorInfo.size() > 0) - { - // Select thread objects for all live threads - long[] running = getAllThreadIds(); - List all = new ArrayList(); - for (int idx=0; idx() - { - /* ------------------------------------------------------------ */ - public int compare(ThreadMonitorInfo info1, ThreadMonitorInfo info2) - { - return (int)Math.signum(info2.getCpuUtilization()-info1.getCpuUtilization()); - } - }); - - String format = "Thread '%2$s'[%3$s,id:%1$d,cpu:%4$.2f%%]%5$s"; - - // Log thread information for threads that exceed logging threshold - // or log spinning threads if their trace count is zero - boolean spinning=false; - for (ThreadMonitorInfo info : all) - { - if (logAll && info.getCpuUtilization() > _logThreshold - || info.isSpinning() && info.getTraceCount() == 0) - { - String message = String.format(format, - info.getThreadId(), info.getThreadName(), - info.getThreadState(), info.getCpuUtilization(), - info.isSpinning() ? " SPINNING" : ""); - _logger.info(message); - spinning=true; - } - } - - // Dump info - if (spinning && _dumpable!=null) - { - System.err.println(_dumpable.dump()); - } - - // Log stack traces for spinning threads with positive trace count - for (ThreadMonitorInfo info : all) - { - if (info.isSpinning() && info.getTraceCount() >= 0) - { - String message = String.format(format, - info.getThreadId(), info.getThreadName(), - info.getThreadState(), info.getCpuUtilization(), - " STACK TRACE"); - _logger.warn(new ThreadMonitorException(message, info.getStackTrace())); - } - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Match stack traces. - * - * @param lastStackTrace last stack trace - * @param stackTrace current stack trace - * @return true, if successful - */ - private boolean matchStackTraces(StackTraceElement[] lastStackTrace, StackTraceElement[] stackTrace) - { - boolean match = true; - int count = Math.min(_stackDepth, Math.min(lastStackTrace.length, stackTrace.length)); - - for (int idx=0; idx < count; idx++) - { - if (!stackTrace[idx].equals(lastStackTrace[idx])) - { - match = false; - break; - } - } - return match; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java deleted file mode 100644 index 54267df40a4..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorAction.java +++ /dev/null @@ -1,409 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.integration; - -import static java.lang.Integer.parseInt; -import static java.lang.System.getProperty; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.net.URL; -import java.util.Collection; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.util.BytesContentProvider; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.monitor.JMXMonitor; -import org.eclipse.jetty.monitor.jmx.EventNotifier; -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventState.TriggerState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; -import org.eclipse.jetty.monitor.jmx.MonitorAction; -import org.eclipse.jetty.monitor.triggers.AggregateEventTrigger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.QueuedThreadPool; - -public class JavaMonitorAction extends MonitorAction -{ - private static final Logger LOG = Log.getLogger(JavaMonitorAction.class); - - private final HttpClient _client; - - private final String _url; - private final String _uuid; - private final String _appid; - - private String _srvip; - private String _session; - - /* ------------------------------------------------------------ */ - public JavaMonitorAction(EventNotifier notifier, String url, String uuid, String appid, long pollInterval) - throws Exception - { - super(new AggregateEventTrigger(),notifier,pollInterval); - - _url = url; - _uuid = uuid; - _appid = appid; - - QueuedThreadPool executor = new QueuedThreadPool(); - executor.setName(executor.getName() + "-monitor"); - _client = new HttpClient(); - _client.setExecutor(executor); - - try - { - _client.start(); - _srvip = getServerIP(); - } - catch (Exception ex) - { - LOG.debug(ex); - } - - sendData(new Properties()); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.MonitorAction#execute(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - @Override - public void execute(EventTrigger trigger, EventState state, long timestamp) - { - exec(trigger, state, timestamp); - } - - /* ------------------------------------------------------------ */ - /** - * @param trigger - * @param state - * @param timestamp - */ - private void exec(EventTrigger trigger, EventState state, long timestamp) - { - Collection> trs = state.values(); - - Properties data = new Properties(); - for (TriggerState ts : trs) - { - Object value = ts.getValue(); - - StringBuffer buffer = new StringBuffer(); - buffer.append(value == null ? "" : value.toString()); - buffer.append("|"); - buffer.append(getClassID(value)); - buffer.append("||"); - buffer.append(ts.getDescription()); - - data.setProperty(ts.getID(), buffer.toString()); - - try - { - sendData(data); - } - catch (Exception ex) - { - LOG.debug(ex); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @param data - * @throws Exception - */ - private void sendData(Properties data) - throws Exception - { - data.put("account", _uuid); - data.put("appserver", "Jetty"); - data.put("localIp", _srvip); - if (_appid == null) - data.put("lowestPort", getHttpPort()); - else - data.put("lowestPort", _appid); - if (_session != null) - data.put("session", _session); - - Properties response = sendRequest(data); - - parseResponse(response); - } - - /* ------------------------------------------------------------ */ - /** - * @param request - * @return - * @throws Exception - */ - private Properties sendRequest(Properties request) - throws Exception - { - ByteArrayOutputStream reqStream = null; - ByteArrayInputStream resStream = null; - Properties response = null; - - try { - reqStream = new ByteArrayOutputStream(); - request.storeToXML(reqStream,null); - - ContentResponse r3sponse = _client.POST(_url) - .header("Connection","close") - .content(new BytesContentProvider(reqStream.toByteArray())) - .send(); - - - if (r3sponse.getStatus() == HttpStatus.OK_200) - { - response = new Properties(); - resStream = new ByteArrayInputStream(r3sponse.getContent()); - response.loadFromXML(resStream); - } - } - finally - { - try - { - if (reqStream != null) - reqStream.close(); - } - catch (IOException ex) - { - LOG.ignore(ex); - } - - try - { - if (resStream != null) - resStream.close(); - } - catch (IOException ex) - { - LOG.ignore(ex); - } - } - - return response; - } - - /* ------------------------------------------------------------ */ - private void parseResponse(Properties response) - { - if (response.get("onhold") != null) - throw new Error("Suspended"); - - - if (response.get("session") != null) - { - _session = (String) response.remove("session"); - - AggregateEventTrigger trigger = (AggregateEventTrigger)getTrigger(); - - String queryString; - ObjectName[] queryResults; - for (Map.Entry entry : response.entrySet()) - { - String[] values = ((String) entry.getValue()).split("\\|"); - - queryString = values[0]; - if (queryString.startsWith("com.javamonitor.openfire")) - continue; - - if (queryString.startsWith("com.javamonitor")) - { - queryString = "org.eclipse.jetty.monitor.integration:type=javamonitortools,id=0"; - } - - queryResults = null; - try - { - queryResults = queryNames(queryString); - } - catch (IOException e) - { - LOG.debug(e); - } - catch (MalformedObjectNameException e) - { - LOG.debug(e); - } - - if (queryResults != null) - { - int idx = 0; - for(ObjectName objName : queryResults) - { - String id = entry.getKey().toString()+(idx == 0 ? "" : ":"+idx); - String name = queryString.equals(objName.toString()) ? "" : objName.toString(); - boolean repeat = Boolean.parseBoolean(values[2]); - trigger.add(new JavaMonitorTrigger(objName, values[1], id, name, repeat)); - } - } - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @param value - * @return - */ - private int getClassID(final Object value) - { - if (value == null) - return 0; - - if (value instanceof Byte || - value instanceof Short || - value instanceof Integer || - value instanceof Long) - return 1; - - if (value instanceof Float || - value instanceof Double) - return 2; - - if (value instanceof Boolean) - return 3; - - return 4; // String - } - - /* ------------------------------------------------------------ */ - /** - * @return - * @throws Exception - */ - private String getServerIP() - throws Exception - { - Socket s = null; - try { - if (getProperty("http.proxyHost") != null) - { - s = new Socket(getProperty("http.proxyHost"), - parseInt(getProperty("http.proxyPort", "80"))); - } - else - { - int port = 80; - - URL url = new URL(_url); - if (url.getPort() != -1) { - port = url.getPort(); - } - s = new Socket(url.getHost(), port); - } - return s.getLocalAddress().getHostAddress(); - } - finally - { - try - { - if (s != null) - s.close(); - } - catch (IOException ex) - { - LOG.ignore(ex); - } - } - } - - /* ------------------------------------------------------------ */ - public Integer getHttpPort() - { - Collection connectors = null; - MBeanServerConnection service; - try - { - service = JMXMonitor.getServiceConnection(); - - connectors = service.queryNames(new ObjectName("org.eclipse.jetty.nio:type=selectchannelconnector,*"), null); - if (connectors != null && connectors.size() > 0) - { - Integer lowest = Integer.MAX_VALUE; - for (final ObjectName connector : connectors) { - lowest = (Integer)service.getAttribute(connector, "port"); - } - - if (lowest < Integer.MAX_VALUE) - return lowest; - } - } - catch (Exception ex) - { - LOG.debug(ex); - } - - return 0; - } - - /* ------------------------------------------------------------ */ - /** - * @param param - * @return - * @throws IOException - * @throws NullPointerException - * @throws MalformedObjectNameException - */ - private ObjectName[] queryNames(ObjectName param) - throws IOException, MalformedObjectNameException - { - ObjectName[] result = null; - - MBeanServerConnection connection = JMXMonitor.getServiceConnection(); - Set names = connection.queryNames(param, null); - if (names != null && names.size() > 0) - { - result = new ObjectName[names.size()]; - - int idx = 0; - for(Object name : names) - { - if (name instanceof ObjectName) - result[idx++] = (ObjectName)name; - else - result[idx++] = new ObjectName(name.toString()); - } - } - - return result; - } - - private ObjectName[] queryNames(String param) - throws IOException, MalformedObjectNameException - { - return queryNames(new ObjectName(param)); - } - - } diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java deleted file mode 100644 index 090fb6d23a3..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTools.java +++ /dev/null @@ -1,288 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.integration; - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.lang.management.ThreadMXBean; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.security.Security; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.annotation.ManagedOperation; - -/** - * Derived from the JMX bean classes created by Kees Jan Koster for the java-monitor - * J2EE probe http://code.google.com/p/java-monitor-probes/source/browse/. - * - * @author Kees Jan Koster - */ -@ManagedObject("Java Monitoring Tools") -public class JavaMonitorTools -{ - private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - - private static Method findDeadlockMethod = null; - - static - { - try - { - findDeadlockMethod = ThreadMXBean.class.getMethod("findDeadlockedThreads"); - } - catch (Exception ignored) - { - // this is a 1.5 JVM - try - { - findDeadlockMethod = ThreadMXBean.class.getMethod("findMonitorDeadlockedThreads"); - } - catch (SecurityException e) - { - e.printStackTrace(); - } - catch (NoSuchMethodException e) - { - e.printStackTrace(); - } - } - } - - private ThreadInfo[] findDeadlock() - throws IllegalAccessException, InvocationTargetException - { - final long[] threadIds = (long[])findDeadlockMethod.invoke(threadMXBean,(Object[])null); - - if (threadIds == null || threadIds.length < 1) - { - // no deadlock, we're done - return null; - } - - final ThreadInfo[] threads = threadMXBean.getThreadInfo(threadIds,Integer.MAX_VALUE); - return threads; - } - @ManagedOperation(value="Detailed report on the deadlocked threads.", impact="ACTION_INFO") - public String getDeadlockStacktraces() - { - try - { - final ThreadInfo[] threads = findDeadlock(); - if (threads == null) - { - // no deadlock, we're done - return null; - } - - return stacktraces(threads,0); - } - catch (Exception e) - { - return e.getMessage(); - } - } - - private static final int MAX_STACK = 10; - - private String stacktraces(final ThreadInfo[] threads, final int i) - { - if (i >= threads.length) - { - return ""; - } - final ThreadInfo thread = threads[i]; - - final StringBuilder trace = new StringBuilder(); - for (int stack_i = 0; stack_i < Math.min(thread.getStackTrace().length,MAX_STACK); stack_i++) - { - if (stack_i == (MAX_STACK - 1)) - { - trace.append(" ..."); - } - else - { - trace.append(" at ").append(thread.getStackTrace()[stack_i]).append("\n"); - } - } - - return "\"" + thread.getThreadName() + "\", id " + thread.getThreadId() + " is " + thread.getThreadState() + " on " + thread.getLockName() - + ", owned by " + thread.getLockOwnerName() + ", id " + thread.getLockOwnerId() + "\n" + trace + "\n\n" + stacktraces(threads,i + 1); - } - - /** - * We keep track of the last time we sampled the thread states. - * It is a crude optimization to avoid having to query for the - * threads states very often. - */ - private long lastSampled = 0L; - - private final Map states = new HashMap(); - - @ManagedOperation(value="Number of Blocked Threads") - public int getThreadsBlocked() - { - sampleThreads(); - - return states.get(Thread.State.BLOCKED); - } - - @ManagedOperation(value="Number of New Threads", impact="ACTION_INFO") - public int getThreadsNew() - { - sampleThreads(); - - return states.get(Thread.State.NEW); - } - - @ManagedOperation(value="Number of Terminated Threads", impact="ACTION_INFO") - public int getThreadsTerminated() - { - sampleThreads(); - - return states.get(Thread.State.TERMINATED); - } - - @ManagedOperation(value="Number of Sleeping and Waiting threads") - public int getThreadsTimedWaiting() - { - sampleThreads(); - - return states.get(Thread.State.TIMED_WAITING); - } - - @ManagedOperation(value="Number of Waiting Threads", impact="ACTION_INFO") - public int getThreadsWaiting() - { - sampleThreads(); - - return states.get(Thread.State.WAITING); - } - - @ManagedOperation(value="Number of Runnable Threads", impact="ACTION_INFO") - public int getThreadsRunnable() - { - sampleThreads(); - - return states.get(Thread.State.RUNNABLE); - } - - private synchronized void sampleThreads() - { - if ((lastSampled + 50L) < System.currentTimeMillis()) - { - lastSampled = System.currentTimeMillis(); - for (final Thread.State state : Thread.State.values()) - { - states.put(state,0); - } - - for (final ThreadInfo thread : threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds())) - { - if (thread != null) - { - final Thread.State state = thread.getThreadState(); - states.put(state,states.get(state) + 1); - } - else - { - states.put(Thread.State.TERMINATED,states.get(Thread.State.TERMINATED) + 1); - } - } - } - } - - private static final String POLICY = "sun.net.InetAddressCachePolicy"; - - @ManagedOperation(value="Amount of time successful DNS queries are cached for.") - public int getCacheSeconds() throws ClassNotFoundException, - IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - final Class policy = Class.forName(POLICY); - final Object returnValue = policy.getMethod("get", (Class[]) null) - .invoke(null, (Object[]) null); - Integer seconds = (Integer) returnValue; - - return seconds.intValue(); - } - - @ManagedOperation(value="Amount of time failed DNS queries are cached for") - public int getCacheNegativeSeconds() throws ClassNotFoundException, - IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - final Class policy = Class.forName(POLICY); - final Object returnValue = policy.getMethod("getNegative", - (Class[]) null).invoke(null, (Object[]) null); - Integer seconds = (Integer) returnValue; - - return seconds.intValue(); - } - - private static final String DEFAULT = "default"; - - private static final String SECURITY = "security"; - - private static final String SYSTEM = "system"; - - private static final String BOTH = "both"; - - private static final String SECURITY_TTL = "networkaddress.cache.ttl"; - - private static final String SYSTEM_TTL = "sun.net.inetaddr.ttl"; - - private static final String SECURITY_NEGATIVE_TTL = "networkaddress.cache.negative.ttl"; - - private static final String SYSTEM_NEGATIVE_TTL = "sun.net.inetaddr.negative.ttl"; - - @ManagedOperation(value="Cache policy for successful DNS lookups was changed from the hard-coded default") - public String getCacheTweakedFrom() { - if (Security.getProperty(SECURITY_TTL) != null) { - if (System.getProperty(SYSTEM_TTL) != null) { - return BOTH; - } - - return SECURITY; - } - - if (System.getProperty(SYSTEM_TTL) != null) { - return SYSTEM; - } - - return DEFAULT; - } - - @ManagedOperation(value="Cache policy for failed DNS lookups was changed from the hard-coded default") - public String getCacheNegativeTweakedFrom() { - if (Security.getProperty(SECURITY_NEGATIVE_TTL) != null) { - if (System.getProperty(SYSTEM_NEGATIVE_TTL) != null) { - return BOTH; - } - - return SECURITY; - } - - if (System.getProperty(SYSTEM_NEGATIVE_TTL) != null) { - return SYSTEM; - } - - return DEFAULT; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java deleted file mode 100644 index 06a51d52641..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/JavaMonitorTrigger.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.integration; - -import javax.management.ObjectName; - -import org.eclipse.jetty.monitor.triggers.AttrEventTrigger; - - -/** - * @param the trigger type - */ -public class JavaMonitorTrigger > - extends AttrEventTrigger -{ - private final String _id; - private final String _name; - private final boolean _dynamic; - private int _count; - - /* ------------------------------------------------------------ */ - public JavaMonitorTrigger(ObjectName nameObject, String attributeName, String id, String name, boolean dynamic) - throws IllegalArgumentException - { - super(nameObject, attributeName); - - _id = id; - _name = name; - _dynamic = dynamic; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return _dynamic ? true : (_count++ < 1); - } - - protected boolean getSaveAll() - { - return false; - } - - @Override - public String getID() - { - return _id; - } - - @Override - public String getNameString() - { - return _name; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java deleted file mode 100644 index 257b8f0cee2..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/integration/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Intregation with Java Monitor - */ -package org.eclipse.jetty.monitor.integration; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java deleted file mode 100644 index bdfa6d1291d..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ConsoleNotifier.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - - -/* ------------------------------------------------------------ */ -/** - * ConsoleNotifier - * - * Provides a way to output notification messages to the server console - */ -public class ConsoleNotifier implements EventNotifier -{ - String _messageFormat; - - - /* ------------------------------------------------------------ */ - /** - * Constructs a new notifier with specified format string - * - * @param format the {@link java.util.Formatter format string} - * @throws IllegalArgumentException if format is invalid - */ - public ConsoleNotifier(String format) - throws IllegalArgumentException - { - if (format == null) - throw new IllegalArgumentException("Message format cannot be null"); - - _messageFormat = format; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.EventNotifier#notify(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - public void notify(EventTrigger trigger, EventState state, long timestamp) - { - String output = String.format("%1$tF %1$tT.%1$tL:NOTIFY::", timestamp); - - output += String.format(_messageFormat, state); - - System.out.println(output); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java deleted file mode 100644 index 7f28c2b5b4f..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventNotifier.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - - -/* ------------------------------------------------------------ */ -/** - * EventNotifier - * - * Interface for classes used to send event notifications - */ -public interface EventNotifier -{ - - /* ------------------------------------------------------------ */ - /** - * This method is called when a notification event is received by the containing object - * - * @param trigger the event trigger - * @param state an {@link org.eclipse.jetty.monitor.jmx.EventState event state} - * @param timestamp time stamp of the event - */ - public void notify(EventTrigger trigger, EventState state, long timestamp); -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java deleted file mode 100644 index abaecbc5c87..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventState.java +++ /dev/null @@ -1,209 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - - -/* ------------------------------------------------------------ */ -/** - * EventState - * - * Holds the state of one or more {@link org.eclipse.jetty.monitor.jmx.EventTrigger event trigger} - * instances to be used when sending notifications as well as executing the actions - * @param the event trigger type - */ -public class EventState -{ - - /* ------------------------------------------------------------ */ - /** - * State - * - * Holds the state of a single {@link org.eclipse.jetty.monitor.jmx.EventTrigger event trigger} - * @param the event trigger type - */ - public static class TriggerState - { - private final String _id; - private final String _desc; - private final TYPE _value; - - /* ------------------------------------------------------------ */ - /** - * Construct a trigger state - * - * @param id unique identification string of the associated event trigger - * @param desc description of the associated event trigger - * @param value effective value of the MXBean attribute (if applicable) - */ - public TriggerState(String id, String desc, TYPE value) - { - _id = id; - _desc = desc; - _value = value; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the identification string of associated event trigger - * - * @return unique identification string - */ - public String getID() - { - return _id; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the description string set by event trigger - * - * @return description string - */ - public String getDescription() - { - return _desc; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the effective value of the MXBean attribute (if applicable) - * - * @return attribute value - */ - public TYPE getValue() - { - return _value; - } - - /* ------------------------------------------------------------ */ - /** - * @return string representation of the state - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_desc); - result.append('='); - result.append(_value); - - return result.toString(); - } - } - - protected Map> _states; - - /* ------------------------------------------------------------ */ - /** - * Constructs an empty event state - */ - public EventState() - { - _states = new ConcurrentHashMap>(); - } - - - /* ------------------------------------------------------------ */ - /** - * Constructs an event state and adds a specified trigger state to it - * - * @param id unique identification string of the associated event trigger - * @param desc description of the associated event trigger - * @param value effective value of the MXBean attribute (if applicable) - */ - public EventState(String id, String desc, TYPE value) - { - this(); - - add(new TriggerState(id, desc, value)); - } - - /* ------------------------------------------------------------ */ - /** - * Adds a trigger state to the event state - * - * @param state trigger state to add - */ - public void add(TriggerState state) - { - _states.put(state.getID(), state); - } - - /* ------------------------------------------------------------ */ - /** - * Adds a collection of trigger states to the event state - * - * @param entries collection of trigger states to add - */ - public void addAll(Collection> entries) - { - for (TriggerState entry : entries) - { - add(entry); - } - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves a single trigger state - * - * @param id unique identification string of the event trigger - * @return requested trigger state or null if not found - */ - public TriggerState get(String id) - { - return _states.get(id); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves a collection of all trigger states of the event state - * - * @return collection of the trigger states - */ - public Collection> values() - { - return Collections.unmodifiableCollection(_states.values()); - } - - /* ------------------------------------------------------------ */ - /** - * Returns a string representation of the event state - * - * @return string representation of the event state - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - for (TriggerState value : _states.values()) - { - result.append(cnt++>0?"#":""); - result.append(value.toString()); - } - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java deleted file mode 100644 index fcc7cfb3cab..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/EventTrigger.java +++ /dev/null @@ -1,76 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import static java.util.UUID.randomUUID; - -/* ------------------------------------------------------------ */ -/** - * EventTrigger - * - * Abstract base class for all EventTrigger implementations. - * Used to determine whether the necessary conditions for - * triggering an event are present. - */ -public abstract class EventTrigger -{ - private final String _id; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger - */ - public EventTrigger() - { - _id = randomUUID().toString(); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the identification string of the event trigger - * - * @return unique identification string - */ - public String getID() - { - return _id; - } - - /* ------------------------------------------------------------ */ - /** - * Abstract method to verify if the event trigger conditions - * are in the appropriate state for an event to be triggered - * - * @param timestamp the timestamp to match - * @return true to trigger an event - * @throws Exception if unable to match - */ - public abstract boolean match(long timestamp) throws Exception; - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - */ - public abstract EventState getState(long timestamp); -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java deleted file mode 100644 index 0c102e554d2..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/LoggingNotifier.java +++ /dev/null @@ -1,65 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** - * ConsoleNotifier - * - * Provides a way to output notification messages to a log file - */ -public class LoggingNotifier implements EventNotifier -{ - private static final Logger LOG = Log.getLogger(LoggingNotifier.class); - - String _messageFormat; - - /* ------------------------------------------------------------ */ - /** - * Constructs a new notifier with specified format string - * - * @param format the {@link java.util.Formatter format string} - * @throws IllegalArgumentException if format is invalid - */ - public LoggingNotifier(String format) - throws IllegalArgumentException - { - if (format == null) - throw new IllegalArgumentException("Message format cannot be null"); - - _messageFormat = format; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.EventNotifier#notify(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - public void notify(EventTrigger trigger, EventState state, long timestamp) - { - String output = String.format(_messageFormat, state); - - LOG.info(output); - } - -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java deleted file mode 100644 index 08017dde02a..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorAction.java +++ /dev/null @@ -1,179 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import static java.util.UUID.randomUUID; - -import java.security.InvalidParameterException; - -/* ------------------------------------------------------------ */ -/** - * MonitorAction - * - * Abstract base class for all MonitorAction implementations. - * Receives notification when an associated EventTrigger is matched. - */ -public abstract class MonitorAction - extends NotifierGroup -{ - public static final int DEFAULT_POLL_INTERVAL = 5000; - - private final String _id; - private final EventTrigger _trigger; - private final EventNotifier _notifier; - private final long _pollInterval; - private final long _pollDelay; - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger) - throws InvalidParameterException - { - this(trigger, null, 0, 0); - } - - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @param notifier event notifier to be associated with this action - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger, EventNotifier notifier) - throws InvalidParameterException - { - this(trigger, notifier, 0); - } - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @param notifier event notifier to be associated with this action - * @param pollInterval interval for polling of the JMX server - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger, EventNotifier notifier, long pollInterval) - throws InvalidParameterException - { - this(trigger, notifier, pollInterval, 0); - } - - /* ------------------------------------------------------------ */ - /** - * Creates a new monitor action - * - * @param trigger event trigger to be associated with this action - * @param notifier event notifier to be associated with this action - * @param pollInterval interval for polling of the JMX server - * @param pollDelay delay before starting to poll the JMX server - * @throws InvalidParameterException if trigger is invalid - */ - public MonitorAction(EventTrigger trigger, EventNotifier notifier, long pollInterval, long pollDelay) - throws InvalidParameterException - { - if (trigger == null) - throw new InvalidParameterException("Trigger cannot be null"); - - _id = randomUUID().toString(); - _trigger = trigger; - _notifier = notifier; - _pollInterval = pollInterval > 0 ? pollInterval : DEFAULT_POLL_INTERVAL; - _pollDelay = pollDelay > 0 ? pollDelay : _pollInterval; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the identification string of the monitor action - * - * @return unique identification string - */ - - public final String getID() - { - return _id; - } - - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event trigger of the monitor action - * - * @return associated event trigger - */ - public EventTrigger getTrigger() - { - return _trigger; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the poll interval - * - * @return interval value (in milliseconds) - */ - public long getPollInterval() - { - return _pollInterval; - } - - - /* ------------------------------------------------------------ */ - /** Retrieve the poll delay - * @return delay value (in milliseconds) - */ - public long getPollDelay() - { - return _pollDelay; - } - - /* ------------------------------------------------------------ */ - /** - * This method will be called when event trigger associated - * with this monitor action matches its conditions. - * - * @param timestamp time stamp of the event - */ - public final void doExecute(long timestamp) - { - EventState state =_trigger.getState(timestamp); - if (_notifier != null) - _notifier.notify(_trigger, state, timestamp); - execute(_trigger, state, timestamp); - } - - /* ------------------------------------------------------------ */ - /** - * This method will be called to allow subclass to execute - * the desired action in response to the event. - * - * @param trigger event trigger associated with this monitor action - * @param state event state associated with current invocation of event trigger - * @param timestamp time stamp of the current invocation of event trigger - */ - public abstract void execute(EventTrigger trigger, EventState state, long timestamp); - } diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java deleted file mode 100644 index 531fbf1d916..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/MonitorTask.java +++ /dev/null @@ -1,119 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.util.HashMap; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.ExecutorThreadPool; -import org.eclipse.jetty.util.thread.ThreadPool; - -/* ------------------------------------------------------------ */ -/** - * MonitorTask - * - * Invokes polling of the JMX server for the MBean attribute values - * through executing timer task scheduled using java.util.Timer - * at specified poll interval following a specified delay. - */ -public class MonitorTask extends TimerTask -{ - private static final Logger LOG = Log.getLogger(MonitorTask.class); - - private static Timer __timer = new Timer(true); - private static ThreadPool _callback = new ExecutorThreadPool(4,64,60,TimeUnit.SECONDS);; - private static Map __tasks = new HashMap(); - - private final MonitorAction _action; - - /* ------------------------------------------------------------ */ - /** - * Creates new instance of MonitorTask - * - * @param action instance of MonitorAction to use - */ - private MonitorTask(MonitorAction action) - { - _action = action; - } - - /* ------------------------------------------------------------ */ - /** - * Schedule new timer task for specified monitor action - * - * @param action monitor action - */ - public static void schedule(MonitorAction action) - { - TimerTask task = new MonitorTask(action); - __timer.scheduleAtFixedRate(task, - action.getPollDelay(), - action.getPollInterval()); - - __tasks.put(action.getID(), task); - } - - /* ------------------------------------------------------------ */ - /** - * Cancel timer task for specified monitor action - * - * @param action monitor action - */ - public static void cancel(MonitorAction action) - { - TimerTask task = __tasks.remove(action.getID()); - if (task != null) - task.cancel(); - } - - /* ------------------------------------------------------------ */ - /** - * This method is invoked when poll interval has elapsed - * to check if the event trigger conditions are satisfied - * in order to fire event. - * - * @see java.util.TimerTask#run() - */ - @Override - public final void run() - { - final long timestamp = System.currentTimeMillis(); - final EventTrigger trigger = _action.getTrigger(); - - _callback.execute(new Runnable() { - public void run() - { - try - { - if(trigger.match(timestamp)) - _action.doExecute(timestamp); - } - catch (Exception ex) - { - LOG.debug(ex); - } - } - }); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java deleted file mode 100644 index d67489bc16d..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/NotifierGroup.java +++ /dev/null @@ -1,119 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - - - -/* ------------------------------------------------------------ */ -/** - * NotifierGroup - * - * This class allows for grouping of the event notifiers - */ -public class NotifierGroup implements EventNotifier -{ - private Set _group; - - /* ------------------------------------------------------------ */ - /** - * Create a notifier group - */ - public NotifierGroup() - { - _group = new HashSet(); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve all event notifier associated with this group - * - * @return collection of event notifiers - */ - public Collection getNotifiers() - { - return Collections.unmodifiableSet(_group); - } - - /* ------------------------------------------------------------ */ - /** - * Add specified event notifier to event notifier group - * - * @param notifier event notifier to be added - * @return true if successful - */ - public boolean addNotifier(EventNotifier notifier) - { - return _group.add(notifier); - } - - /* ------------------------------------------------------------ */ - /** - * Add a collection of event notifiers to event notifier group - * - * @param notifiers collection of event notifiers to be added - * @return true if successful - */ - public boolean addNotifiers(Collection notifiers) - { - return _group.addAll(notifiers); - } - - /* ------------------------------------------------------------ */ - /** - * Remove event notifier from event notifier group - * - * @param notifier event notifier to be removed - * @return true if successful - */ - public boolean removeNotifier(EventNotifier notifier) - { - return _group.remove(notifier); - } - - /* ------------------------------------------------------------ */ - /** - * Remove a collection of event notifiers from event notifier group - * - * @param notifiers collection of event notifiers to be removed - * @return true if successful - */ - public boolean removeNotifiers(Collection notifiers) - { - return _group.removeAll(notifiers); - } - - /* ------------------------------------------------------------ */ - /** - * Invoke the notify() method of each of the notifiers in group - * - * @see org.eclipse.jetty.monitor.jmx.EventNotifier#notify(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - public void notify(EventTrigger trigger, EventState state, long timestamp) - { - for (EventNotifier notifier: _group) - { - notifier.notify(trigger, state, timestamp); - } - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java deleted file mode 100644 index 0088cccf05f..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/ServiceConnection.java +++ /dev/null @@ -1,172 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.io.IOException; -import java.lang.management.ManagementFactory; - -import javax.management.MBeanServer; -import javax.management.MBeanServerConnection; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXConnectorServer; -import javax.management.remote.JMXConnectorServerFactory; -import javax.management.remote.JMXServiceURL; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** - * ServerConnection - * - * Provides ability to create a connection to either an external - * JMX server, or a loopback connection to the internal one. - */ -public class ServiceConnection -{ - private static final Logger LOG = Log.getLogger(ServiceConnection.class); - - private String _serviceUrl; - private MBeanServer _server; - private JMXConnectorServer _connectorServer; - private JMXConnector _serverConnector; - private MBeanServerConnection _serviceConnection; - - /* ------------------------------------------------------------ */ - /** - * Construct a loopback connection to an internal server - * - * @throws IOException if unable to construct service connection - */ - public ServiceConnection() - throws IOException - { - this(null); - } - - /* ------------------------------------------------------------ */ - /** - * Construct a connection to specified server - * - * @param url URL of JMX server - * @throws IOException if unable to construct service connection - */ - public ServiceConnection(String url) - throws IOException - { - _serviceUrl = url; - } - - /** - * Retrieve an external URL for the JMX server - * - * @return service URL - */ - public String getServiceUrl() - { - return _serviceUrl; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve a connection to MBean server - * - * @return connection to MBean server - */ - public MBeanServerConnection getConnection() - { - return _serviceConnection; - } - - public void connect() - throws IOException - { - if (_serviceConnection == null) - { - if (_serviceUrl == null) - openLoopbackConnection(); - else - openServerConnection(_serviceUrl); - } - } - /* ------------------------------------------------------------ */ - /** - * Open a loopback connection to local JMX server - * - * @throws IOException - */ - private void openLoopbackConnection() - throws IOException - { - _server = ManagementFactory.getPlatformMBeanServer(); - - JMXServiceURL serviceUrl = new JMXServiceURL("service:jmx:rmi://"); - _connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serviceUrl, null, _server); - _connectorServer.start(); - - _serviceUrl = _connectorServer.getAddress().toString(); - - _serverConnector = JMXConnectorFactory.connect(_connectorServer.getAddress()); - _serviceConnection = _serverConnector.getMBeanServerConnection(); - } - - /* ------------------------------------------------------------ */ - /** - * Open a connection to remote JMX server - * - * @param url - * @throws IOException - */ - private void openServerConnection(String url) - throws IOException - { - _serviceUrl = url; - - JMXServiceURL serviceUrl = new JMXServiceURL(_serviceUrl); - _serverConnector = JMXConnectorFactory.connect(serviceUrl); - _serviceConnection = _serverConnector.getMBeanServerConnection(); - } - - /* ------------------------------------------------------------ */ - /** - * Close the connections - */ - public void disconnect() - { - try - { - if (_serverConnector != null) - { - _serverConnector.close(); - _serviceConnection = null; - } - if (_connectorServer != null) - { - _connectorServer.stop(); - _connectorServer = null; - } - } - catch (Exception ex) - { - LOG.debug(ex); - } - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java deleted file mode 100644 index a4feb7b0b74..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/SimpleAction.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.jmx; - -import java.security.InvalidParameterException; - - - -/* ------------------------------------------------------------ */ -/** - */ -public class SimpleAction extends MonitorAction -{ - public SimpleAction(EventTrigger trigger, EventNotifier notifier, long pollInterval) - throws InvalidParameterException - { - super(trigger,notifier,pollInterval); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.MonitorAction#execute(org.eclipse.jetty.monitor.jmx.EventTrigger, org.eclipse.jetty.monitor.jmx.EventState, long) - */ - - @Override - public void execute(EventTrigger trigger, EventState state, long timestamp) - { - System.out.printf("Action time: %tc%n", timestamp); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java deleted file mode 100644 index e3c71b53fd8..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/jmx/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : JMX Integration - */ -package org.eclipse.jetty.monitor.jmx; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java deleted file mode 100644 index c4cf607a7ec..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Tool for Monitoring Threads - */ -package org.eclipse.jetty.monitor; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java deleted file mode 100644 index a05ab0690d2..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorException.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.thread; - - -/* ------------------------------------------------------------ */ -/** - */ -public class ThreadMonitorException extends Exception -{ - private static final long serialVersionUID = -4345223166315716918L; - - public ThreadMonitorException(String message, StackTraceElement[] stackTrace) - { - super(message); - setStackTrace(stackTrace); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java deleted file mode 100644 index d8322d376f8..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/ThreadMonitorInfo.java +++ /dev/null @@ -1,202 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.thread; - - -/* ------------------------------------------------------------ */ -/** - */ -public class ThreadMonitorInfo -{ - private Thread _thread; - private StackTraceElement[] _stackTrace; - - private boolean _threadSpinning = false; - private int _traceCount = -1; - - private long _prevCpuTime; - private long _prevSampleTime; - private long _currCpuTime; - private long _currSampleTime; - - - /* ------------------------------------------------------------ */ - /** - * Instantiates a new thread monitor info. - * - * @param thread the thread this object is created for - */ - public ThreadMonitorInfo(Thread thread) - { - _thread = thread; - } - - /* ------------------------------------------------------------ */ - /** - * @return Id of the thread - */ - public long getThreadId() - { - return _thread.getId(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the thread name. - * - * @return the thread name - */ - public String getThreadName() - { - return _thread.getName(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the thread state. - * - * @return the thread state - */ - public String getThreadState() - { - return _thread.getState().toString(); - } - - /* ------------------------------------------------------------ */ - /** - * Gets the stack trace. - * - * @return the stack trace - */ - public StackTraceElement[] getStackTrace() - { - return _stackTrace; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the stack trace. - * - * @param stackTrace the new stack trace - */ - public void setStackTrace(StackTraceElement[] stackTrace) - { - _stackTrace = stackTrace; - } - - /* ------------------------------------------------------------ */ - /** - * Checks if is spinning. - * - * @return true, if is spinning - */ - public boolean isSpinning() - { - return _threadSpinning; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the spinning flag. - * - * @param value the new value - */ - public void setSpinning(boolean value) - { - _threadSpinning = value; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the trace count. - * - * @param traceCount the new trace count - */ - public void setTraceCount(int traceCount) - { - _traceCount = traceCount; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the trace count. - * - * @return the trace count - */ - public int getTraceCount() - { - return _traceCount; - } - - /* ------------------------------------------------------------ */ - /** - * @return the CPU time of the thread - */ - public long getCpuTime() - { - return _currCpuTime; - } - - /* ------------------------------------------------------------ */ - /** - * Set the CPU time. - * - * @param ns new CPU time - */ - public void setCpuTime(long ns) - { - _prevCpuTime = _currCpuTime; - _currCpuTime = ns; - } - - /* ------------------------------------------------------------ */ - /** - * @return the time of sample - */ - public long getSampleTime() - { - return _currSampleTime; - } - - /* ------------------------------------------------------------ */ - /** - * Sets the sample time. - * - * @param ns the time of sample - */ - public void setSampleTime(long ns) - { - _prevSampleTime = _currSampleTime; - _currSampleTime = ns; - } - - /* ------------------------------------------------------------ */ - /** - * Gets the CPU utilization. - * - * @return the CPU utilization percentage - */ - public float getCpuUtilization() - { - long elapsedCpuTime = _currCpuTime - _prevCpuTime; - long elapsedNanoTime = _currSampleTime - _prevSampleTime; - - return elapsedNanoTime > 0 ? Math.min((elapsedCpuTime * 100.0f) / elapsedNanoTime, 100.0f) : 0; - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java deleted file mode 100644 index 997ff01d1a3..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/thread/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Thread Monitoring - */ -package org.eclipse.jetty.monitor.thread; - diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java deleted file mode 100644 index b8db4b92d85..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AggregateEventTrigger.java +++ /dev/null @@ -1,159 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; - - -/* ------------------------------------------------------------ */ -/** - * AggregateEventTrigger - * - * EventTrigger aggregation that executes every aggregated event - * triggers in left to right order, and returns match if any one - * of them have returned match. - */ -public class AggregateEventTrigger extends EventTrigger -{ - protected final List _triggers; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger - */ - public AggregateEventTrigger() - { - _triggers = new ArrayList(); - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the list - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public AggregateEventTrigger(List triggers) - { - _triggers = new ArrayList(triggers); - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the array - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public AggregateEventTrigger(EventTrigger... triggers) - { - _triggers = Arrays.asList(triggers); - } - - /* ------------------------------------------------------------ */ - public void add(EventTrigger trigger) - { - _triggers.add(trigger); - } - - /* ------------------------------------------------------------ */ - public void addAll(List triggers) - { - _triggers.addAll(triggers); - } - - /* ------------------------------------------------------------ */ - public void addAll(EventTrigger... triggers) - { - _triggers.addAll(Arrays.asList(triggers)); - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. This event trigger retrieves - * the combined event state of all aggregated event triggers. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - public EventState getState(long timestamp) - { - EventState state = new EventState(); - - for (EventTrigger trigger : _triggers) - { - EventState subState = trigger.getState(timestamp); - if (subState != null) - { - state.addAll(subState.values()); - } - } - - return state; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - @Override - public boolean match(long timestamp) throws Exception - { - boolean result = false; - for(EventTrigger trigger : _triggers) - { - result = trigger.match(timestamp) ? true : result; - } - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "AND(triger1,trigger2,...)". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - result.append("ANY("); - for (EventTrigger trigger : _triggers) - { - result.append(cnt++ > 0 ? "," : ""); - result.append(trigger); - } - result.append(')'); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java deleted file mode 100644 index 5f2cf982a2d..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AndEventTrigger.java +++ /dev/null @@ -1,134 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; - - - -/* ------------------------------------------------------------ */ -/** - * AndEventTrigger - * - * EventTrigger aggregation using logical AND operation - * that executes matching of the aggregated event triggers - * in left to right order - */ -public class AndEventTrigger extends EventTrigger -{ - protected final List _triggers; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the list - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public AndEventTrigger(List triggers) - { - _triggers = triggers; - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the array - * of event triggers to be aggregated by this trigger - * - * @param triggers array of event triggers to add - */ - public AndEventTrigger(EventTrigger... triggers) - { - _triggers = Arrays.asList(triggers); - } - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * This event trigger will match if all aggregated - * event triggers would return a match. - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - public boolean match(long timestamp) - throws Exception - { - for(EventTrigger trigger : _triggers) - { - if (!trigger.match(timestamp)) - return false; - } - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. This event trigger retrieves - * the combined event state of all aggregated event triggers. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - public EventState getState(long timestamp) - { - EventState state = new EventState(); - - for (EventTrigger trigger : _triggers) - { - EventState subState = trigger.getState(timestamp); - state.addAll(subState.values()); - } - - return state; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "AND(triger1,trigger2,...)". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - result.append("AND("); - for (EventTrigger trigger : _triggers) - { - result.append(cnt++ > 0 ? "," : ""); - result.append(trigger); - } - result.append(')'); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java deleted file mode 100644 index 02169a68b12..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/AttrEventTrigger.java +++ /dev/null @@ -1,240 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.management.MBeanServerConnection; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.openmbean.CompositeData; - -import org.eclipse.jetty.monitor.JMXMonitor; -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * AttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute - * and matches every invocation of this trigger. It can be - * used to send notifications of the value of an attribute - * of the MXBean being polled at a certain interval, or as - * a base class for the event triggers that match the - * value of an attribute of the MXBean being polled against - * some specified criteria. - * @param the event trigger type - */ -public class AttrEventTrigger> - extends EventTrigger -{ - private static final Logger LOG = Log.getLogger(AttrEventTrigger.class); - - private final ObjectName _nameObject; - - protected final String _objectName; - protected final String _attributeName; - protected Map> _states; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * - * @throws MalformedObjectNameException if unable to find object due to malformed name reference - * @throws IllegalArgumentException if parameters are invalid - */ - public AttrEventTrigger(String objectName, String attributeName) - throws MalformedObjectNameException, IllegalArgumentException - { - if (objectName == null) - throw new IllegalArgumentException("Object name cannot be null"); - if (attributeName == null) - throw new IllegalArgumentException("Attribute name cannot be null"); - - _states = new ConcurrentHashMap>(); - - _objectName = objectName; - _attributeName = attributeName; - - _nameObject = new ObjectName(_objectName); - } - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger. - * - * @param nameObject object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * - * @throws IllegalArgumentException if parameters are invalid - */ - public AttrEventTrigger(ObjectName nameObject, String attributeName) - throws IllegalArgumentException - { - if (nameObject == null) - throw new IllegalArgumentException("Object name cannot be null"); - if (attributeName == null) - throw new IllegalArgumentException("Attribute name cannot be null"); - - _states = new ConcurrentHashMap>(); - - _objectName = nameObject.toString(); - _attributeName = attributeName; - - _nameObject = nameObject; - } - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * This event trigger uses the match(Comparable<TYPE>) - * method to compare the value of the MXBean attribute - * to the conditions specified by the subclasses. - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - @SuppressWarnings("unchecked") - public final boolean match(long timestamp) - throws Exception - { - MBeanServerConnection serverConnection = JMXMonitor.getServiceConnection(); - - TYPE value = null; - try - { - int pos = _attributeName.indexOf('.'); - if (pos < 0) - value = (TYPE)serverConnection.getAttribute(_nameObject,_attributeName); - else - value = getValue((CompositeData)serverConnection.getAttribute(_nameObject, _attributeName.substring(0, pos)), - _attributeName.substring(pos+1)); - } - catch (Exception ex) - { - LOG.debug(ex); - } - - boolean result = false; - if (value != null) - { - result = match(value); - - if (result || getSaveAll()) - { - _states.put(timestamp, - new EventState(this.getID(), this.getNameString(), value)); - } - } - - return result; - } - - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * Allows subclasses to override the default behavior - * that matches every invocation of this trigger - * @param value the value to match - * @return always true - */ - public boolean match(Comparable value) - { - return true; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - public final EventState getState(long timestamp) - { - return _states.get(timestamp); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "[object_name:attribute_name]". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - return getNameString(); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "[object_name:attribute_name]". Allows - * subclasses to override the name string used to identify - * this event trigger in the event state object as well as - * string representation of the subclasses. - * - * @return string representation of the event trigger - */ - protected String getNameString() - { - StringBuilder result = new StringBuilder(); - - result.append('['); - result.append(_objectName); - result.append(":"); - result.append(_attributeName); - result.append("]"); - - return result.toString(); - } - - protected boolean getSaveAll() - { - return true; - } - - protected TYPE getValue(CompositeData compValue, String fieldName) - { - int pos = fieldName.indexOf('.'); - if (pos < 0) - return (TYPE)compValue.get(fieldName); - else - return getValue((CompositeData)compValue.get(fieldName.substring(0, pos)), - fieldName.substring(pos+1)); - - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java deleted file mode 100644 index 48aca3c5743..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/EqualToAttrEventTrigger.java +++ /dev/null @@ -1,89 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - - -/** - * EqualToAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is equal to specified value. - * @param the event trigger type - */ -public class EqualToAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _value; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as the - * target value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param value target value of the attribute - * - * @throws MalformedObjectNameException if unable to find object due to name issue - * @throws IllegalArgumentException on invalid parameters - */ - public EqualToAttrEventTrigger(String objectName, String attributeName, TYPE value) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (value == null) - throw new IllegalArgumentException("Value cannot be null"); - - _value = value; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is equal to the specified value. - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_value) == 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "name=value". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(getNameString()); - result.append("=="); - result.append(_value); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java deleted file mode 100644 index a091a660dfd..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanAttrEventTrigger.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * GreaterThanAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is greater than specified min value. - * @param event trigger type - */ -public class GreaterThanAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public GreaterThanAttrEventTrigger(String objectName, String attributeName, TYPE min) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is greater than the min value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) > 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<name". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<"); - result.append(getNameString()); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java deleted file mode 100644 index c6383633d79..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/GreaterThanOrEqualToAttrEventTrigger.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * GreaterThanOrEqualToAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is greater than or equal to specified min value. - * @param event trigger type - */ -public class GreaterThanOrEqualToAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public GreaterThanOrEqualToAttrEventTrigger(String objectName, String attributeName, TYPE min) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is greater than or equal to the min value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) >= 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<=name". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<="); - result.append(getNameString()); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java deleted file mode 100644 index 7457e628a75..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanAttrEventTrigger.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * LessThanAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is greater than specified max value. - * @param event trigger type - */ -public class LessThanAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as max - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public LessThanAttrEventTrigger(String objectName, String attributeName, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is less than the min value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_max) < 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "name<max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(getNameString()); - result.append("<"); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java deleted file mode 100644 index de35ee34d79..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/LessThanOrEqualToAttrEventTrigger.java +++ /dev/null @@ -1,91 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - - -/** - * LessThanOrEqualToAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is less than or equal to specified max value. - * @param event trigger type - */ -public class LessThanOrEqualToAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as max - * value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public LessThanOrEqualToAttrEventTrigger(String objectName, String attributeName, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is less than or equal to the max value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_max) <= 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "name<=max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(getNameString()); - result.append("<="); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java deleted file mode 100644 index 31ac0496eb0..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/OrEventTrigger.java +++ /dev/null @@ -1,138 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; - - -/* ------------------------------------------------------------ */ -/** - * AndEventTrigger - * - * EventTrigger aggregation using logical OR operation - * that executes matching of the aggregated event triggers - * in left to right order - */ -public class OrEventTrigger - extends EventTrigger -{ - private final List _triggers; - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the list - * of event triggers to be aggregated by this trigger - * - * @param triggers list of event triggers to add - */ - public OrEventTrigger(List triggers) - { - _triggers = triggers; - } - - /* ------------------------------------------------------------ */ - /** - * Construct an event trigger and associate the array - * of event triggers to be aggregated by this trigger - * - * @param triggers array of event triggers to add - */ - public OrEventTrigger(EventTrigger... triggers) - { - _triggers = Arrays.asList(triggers); - } - - /* ------------------------------------------------------------ */ - /** - * Verify if the event trigger conditions are in the - * appropriate state for an event to be triggered. - * This event trigger will match if any of aggregated - * event triggers would return a match. - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#match(long) - */ - public boolean match(long timestamp) - throws Exception - { - for(EventTrigger trigger : _triggers) - { - if (trigger.match(timestamp)) - return true; - } - return false; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieve the event state associated with specified invocation - * of the event trigger match method. This event trigger retrieves - * the combined event state of all aggregated event triggers. - * - * @param timestamp time stamp associated with invocation - * @return event state or null if not found - * - * @see org.eclipse.jetty.monitor.jmx.EventTrigger#getState(long) - */ - @Override - @SuppressWarnings("unchecked") - public EventState getState(long timestamp) - { - EventState state = new EventState(); - - for (EventTrigger trigger : _triggers) - { - EventState subState = trigger.getState(timestamp); - if (subState!=null) - { - state.addAll(subState.values()); - } - } - - return state; - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "OR(triger1,trigger2,...)". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - int cnt = 0; - StringBuilder result = new StringBuilder(); - - result.append("OR("); - for (EventTrigger trigger : _triggers) - { - result.append(cnt++ > 0 ? "," : ""); - result.append(trigger); - } - result.append(')'); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java deleted file mode 100644 index bb3953befa1..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeAttrEventTrigger.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * RangeAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is in a range from specified min value to - * specified max value. - * @param event trigger type - */ -public class RangeAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * and max value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public RangeAttrEventTrigger(String objectName, String attributeName,TYPE min, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is in a range from specified min value to - * specified max value. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) > 0) &&(value.compareTo(_max) < 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<name<max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<"); - result.append(getNameString()); - result.append("<"); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java deleted file mode 100644 index 748fd7d4db0..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/RangeInclAttrEventTrigger.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor.triggers; - -import javax.management.MalformedObjectNameException; - -/** - * RangeInclAttrEventTrigger - *

    - * Event trigger that polls a value of an MXBean attribute and - * checks if it is in a range from specified min value to - * specified max value including the range bounds. - * @param event trigger type - */ -public class RangeInclAttrEventTrigger> extends AttrEventTrigger -{ - protected final TYPE _min; - protected final TYPE _max; - - /* ------------------------------------------------------------ */ - /** - * Construct event trigger and specify the MXBean attribute - * that will be polled by this event trigger as well as min - * and max value of the attribute. - * - * @param objectName object name of an MBean to be polled - * @param attributeName name of an MBean attribute to be polled - * @param min minimum value of the attribute - * @param max maximum value of the attribute - * - * @throws MalformedObjectNameException on bad object name - * @throws IllegalArgumentException on bad parameters - */ - public RangeInclAttrEventTrigger(String objectName, String attributeName,TYPE min, TYPE max) - throws MalformedObjectNameException, IllegalArgumentException - { - super(objectName,attributeName); - - if (min == null) - throw new IllegalArgumentException("Value cannot be null"); - if (max == null) - throw new IllegalArgumentException("Value cannot be null"); - - _min = min; - _max = max; - } - - /* ------------------------------------------------------------ */ - /** - * Compare the value of the MXBean attribute being polling - * to check if it is in a range from specified min value to - * specified max value including the range bounds. - * - * @see org.eclipse.jetty.monitor.triggers.AttrEventTrigger#match(java.lang.Comparable) - */ - @Override - public boolean match(Comparable value) - { - return (value.compareTo(_min) >= 0) &&(value.compareTo(_max) <= 0); - } - - /* ------------------------------------------------------------ */ - /** - * Returns the string representation of this event trigger - * in the format "min<=name<=max". - * - * @return string representation of the event trigger - * - * @see java.lang.Object#toString() - */ - public String toString() - { - StringBuilder result = new StringBuilder(); - - result.append(_min); - result.append("<="); - result.append(getNameString()); - result.append("<="); - result.append(_max); - - return result.toString(); - } -} diff --git a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java b/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java deleted file mode 100644 index 3f0ed871310..00000000000 --- a/jetty-monitor/src/main/java/org/eclipse/jetty/monitor/triggers/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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. -// ======================================================================== -// - -/** - * Jetty Monitor : Triggers for Monitor Events - */ -package org.eclipse.jetty.monitor.triggers; - diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java deleted file mode 100644 index bcb0fc2ea0c..00000000000 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java +++ /dev/null @@ -1,526 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.lang.management.ManagementFactory; -import java.util.Collection; -import java.util.Iterator; -import java.util.TreeSet; - -import javax.management.MBeanServer; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.jmx.MBeanContainer; -import org.eclipse.jetty.monitor.jmx.ConsoleNotifier; -import org.eclipse.jetty.monitor.jmx.EventNotifier; -import org.eclipse.jetty.monitor.jmx.EventState; -import org.eclipse.jetty.monitor.jmx.EventState.TriggerState; -import org.eclipse.jetty.monitor.jmx.EventTrigger; -import org.eclipse.jetty.monitor.jmx.MonitorAction; -import org.eclipse.jetty.monitor.triggers.AndEventTrigger; -import org.eclipse.jetty.monitor.triggers.AttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.EqualToAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.GreaterThanAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.GreaterThanOrEqualToAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.LessThanAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.LessThanOrEqualToAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.OrEventTrigger; -import org.eclipse.jetty.monitor.triggers.RangeAttrEventTrigger; -import org.eclipse.jetty.monitor.triggers.RangeInclAttrEventTrigger; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - - -/* ------------------------------------------------------------ */ -/** - */ -public class AttrEventTriggerTest -{ - private static final Logger LOG = Log.getLogger(AttrEventTriggerTest.class); - - private Server _server; - private TestHandler _handler; - private RequestCounter _counter; - private JMXMonitor _monitor; - private HttpClient _client; - private String _requestUrl; - private MBeanContainer _mBeanContainer; - - @Before - public void setUp() - throws Exception - { - File docRoot = new File("target/test-output/docroot/"); - docRoot.mkdirs(); - docRoot.deleteOnExit(); - - System.setProperty("org.eclipse.jetty.util.log.DEBUG",""); - _server = new Server(); - - ServerConnector connector = new ServerConnector(_server); - connector.setPort(0); - _server.setConnectors(new Connector[] {connector}); - - _handler = new TestHandler(); - _server.setHandler(_handler); - - MBeanContainer.resetUnique(); - MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); - _mBeanContainer = new MBeanContainer(mBeanServer); - _server.addBean(_mBeanContainer,true); - _server.addBean(Log.getLog()); - - _counter = _handler.getRequestCounter(); - _server.addBean(_counter); - - _server.start(); - - startClient(); - - _monitor = new JMXMonitor(); - - int port = connector.getLocalPort(); - _requestUrl = "http://localhost:"+port+ "/"; - } - - @After - public void tearDown() - throws Exception - { - stopClient(); - - _mBeanContainer.destroy(); - - if (_server != null) - { - _server.stop(); - _server = null; - } - } - - @Test - public void testNoCondition() - throws Exception - { - long requestCount = 10; - - AttrEventTrigger trigger = - new AttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter"); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,requestCount); - assertEquals(result, action.getHits()); - } - - @Test - public void testEqual_TRUE() - throws Exception - { - long requestCount = 10; - long testValue = 5; - - EqualToAttrEventTrigger trigger = - new EqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",testValue); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testValue); - assertEquals(result, action.getHits()); - } - - @Test - public void testEqual_FALSE() - throws Exception - { - long requestCount = 10; - long testValue = 11; - - EqualToAttrEventTrigger trigger = - new EqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testValue); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(); - assertEquals(result, action.getHits()); - } - - @Test - public void testLowerLimit() - throws Exception - { - long requestCount = 10; - long testRangeLow = 5; - - GreaterThanAttrEventTrigger trigger = - new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(6,10); - assertEquals(result, action.getHits()); - } - - @Test - public void testLowerLimitIncl() - throws Exception - { - long requestCount = 10; - long testRangeLow = 5; - - GreaterThanOrEqualToAttrEventTrigger trigger = - new GreaterThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(5,10); - assertEquals(result, action.getHits()); - } - - @Test - public void testUpperLimit() - throws Exception - { - long requestCount = 10; - long testRangeHigh = 5; - - LessThanAttrEventTrigger trigger = - new LessThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,4); - assertEquals(result, action.getHits()); - } - - - @Test - public void testUpperLimitIncl() - throws Exception - { - long requestCount = 10; - long testRangeHigh = 5; - - LessThanOrEqualToAttrEventTrigger trigger = - new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,5); - assertEquals(result, action.getHits()); - } - - @Test - public void testRangeInclusive() - throws Exception - { - long requestCount = 10; - long testRangeLow = 3; - long testRangeHigh = 8; - - RangeInclAttrEventTrigger trigger = - new RangeInclAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow, testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testRangeLow,testRangeHigh); - assertEquals(result, action.getHits()); - } - - @Test - public void testInsideRangeExclusive() - throws Exception - { - long requestCount = 10; - long testRangeLow = 3; - long testRangeHigh = 8; - - RangeAttrEventTrigger trigger = - new RangeAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow, testRangeHigh); - - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh-1); - assertEquals(result, action.getHits()); - } - - @Test - public void testRangeComposite() - throws Exception - { - long requestCount = 10; - long testRangeLow = 4; - long testRangeHigh = 7; - - GreaterThanAttrEventTrigger trigger1 = - new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - LessThanOrEqualToAttrEventTrigger trigger2 = - new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - AndEventTrigger trigger = new AndEventTrigger(trigger1, trigger2); - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh); - assertEquals(result, action.getHits()); - } - - @Test - public void testRangeOuter() - throws Exception - { - long requestCount = 10; - long testRangeLow = 4; - long testRangeHigh = 7; - - LessThanOrEqualToAttrEventTrigger trigger1 = - new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeLow); - GreaterThanAttrEventTrigger trigger2 = - new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", - testRangeHigh); - OrEventTrigger trigger = new OrEventTrigger(trigger1, trigger2); - EventNotifier notifier = new ConsoleNotifier("%s"); - CounterAction action = new CounterAction(trigger, notifier, 500, 100); - - performTest(action, requestCount, 1000); - - ResultSet result = new ResultSet(1,testRangeLow,testRangeHigh+1, requestCount); - assertEquals(result, action.getHits()); - } - - protected void performTest(MonitorAction action, long count, long interval) - throws Exception - { - _monitor.addActions(action); - - for (long cnt=0; cnt < count; cnt++) - { - try - { - //LOG.debug("Request: %s", _requestUrl); - ContentResponse r3sponse = _client.GET(_requestUrl); - - //ContentExchange getExchange = new ContentExchange(); - //getExchange.setURL(_requestUrl); - //getExchange.setMethod(HttpMethods.GET); - - //_client.send(getExchange); - //int state = getExchange.waitForDone(); - - String content = ""; - //int responseStatus = getExchange.getResponseStatus(); - if (r3sponse.getStatus() == HttpStatus.OK_200) - { - content = r3sponse.getContentAsString(); - } - else - { - LOG.info("response status", r3sponse.getStatus()); - } - - assertEquals(HttpStatus.OK_200,r3sponse.getStatus()); - Thread.sleep(interval); - } - catch (InterruptedException ex) - { - break; - } - } - - Thread.sleep(interval); - - _monitor.removeActions(action); - } - - protected void startClient()//Realm realm) - throws Exception - { - _client = new HttpClient(); - //_client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); - //if (realm != null){ -// _client.setRealmResolver(new SimpleRealmResolver(realm)); - //} - _client.start(); - } - - protected void stopClient() - throws Exception - { - if (_client != null) - { - _client.stop(); - _client = null; - } - } - - protected static class TestHandler - extends AbstractHandler - { - private RequestCounter _counter = new RequestCounter(); - - public void handle(String target, Request baseRequest, - HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException - { - if (baseRequest.isHandled()) { - return; - } - _counter.increment(); - - response.setContentType("text/plain"); - response.setStatus(HttpServletResponse.SC_OK); - PrintWriter writer = response.getWriter(); - writer.println("===TEST RESPONSE==="); - baseRequest.setHandled(true); - } - - public RequestCounter getRequestCounter() - { - return _counter; - } - } - - protected static class ResultSet extends TreeSet - { - public ResultSet() {} - - public ResultSet(long value) - { - add(value); - } - - public ResultSet(long start, long end) - { - addEntries(start, end); - } - - public ResultSet(long start, long pause, long resume, long end) - { - addEntries(start, pause); - addEntries(resume, end); - } - - public void addEntries(long start, long stop) - { - if (start > 0 && stop > 0) - { - for(long idx=start; idx <= stop; idx++) - { - add(idx); - } - } - } - - public boolean equals(ResultSet set) - { - return (this.size() == set.size()) && containsAll(set); - } - } - - protected static class CounterAction - extends MonitorAction - { - private ResultSet _hits = new ResultSet(); - - public CounterAction(EventTrigger trigger, EventNotifier notifier, long interval, long delay) - { - super(trigger, notifier, interval, delay); - } - - public void execute(EventTrigger trigger, EventState state, long timestamp) - { - if (trigger != null && state != null) - { - Collection values = state.values(); - - Iterator it = values.iterator(); - while(it.hasNext()) - { - TriggerState entry = (TriggerState)it.next(); - Object value = entry.getValue(); - if (value != null) - { - _hits.add((Long)value); - } - } - } - } - - public ResultSet getHits() - { - return _hits; - } - } -} diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java deleted file mode 100644 index 934238f1604..00000000000 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/RequestCounter.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import org.eclipse.jetty.util.annotation.ManagedAttribute; -import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.annotation.ManagedOperation; - - -@ManagedObject("TEST: Request Counter") -public class RequestCounter -{ - public long _counter; - - @ManagedAttribute("Get the value of the counter") - public synchronized long getCounter() - { - return _counter; - } - - @ManagedOperation("Increment the value of the counter") - public synchronized void increment() - { - _counter++; - } - - @ManagedOperation("Reset the counter") - public synchronized void reset() - { - _counter = 0; - } -} diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java deleted file mode 100644 index 6072763179e..00000000000 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/ThreadMonitorTest.java +++ /dev/null @@ -1,165 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.monitor; - -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.StacklessLogging; -import org.junit.Ignore; -import org.junit.Test; - - -/* ------------------------------------------------------------ */ -/** - */ -public class ThreadMonitorTest -{ - public final static int DURATION=4000; - - @Ignore - @Test - public void monitorTest() throws Exception - { - try(StacklessLogging stackless=new StacklessLogging(ThreadMonitor.class)) - { - - final AtomicInteger countLogs=new AtomicInteger(0); - final AtomicInteger countSpin=new AtomicInteger(0); - - ThreadMonitor monitor = new ThreadMonitor(1000,50,1,1) - { - @Override - protected void logThreadInfo(boolean logAll) - { - if (logAll) - countLogs.incrementAndGet(); - else - countSpin.incrementAndGet(); - super.logThreadInfo(logAll); - } - }; - monitor.setDumpable(new Dumpable() - { - public void dump(Appendable out, String indent) throws IOException - { - out.append(dump()); - } - - public String dump() - { - return "Dump Spinning"; - } - }); - - monitor.logCpuUsage(2000,0); - monitor.start(); - - Random rnd = new Random(); - for (long cnt=0; cnt<100; cnt++) - { - long value = rnd.nextLong() % 50 + 50; - Sleeper sleeper = new Sleeper(value); - Thread runner = new Thread(sleeper); - runner.setDaemon(true); - runner.start(); - } - - Spinner spinner = new Spinner(); - Thread runner = new Thread(spinner); - runner.start(); - - Thread.sleep(DURATION); - - spinner.setDone(); - monitor.stop(); - - assertTrue(countLogs.get() >= 1); - assertTrue(countSpin.get() >= 2); - } - } - - - private class Spinner implements Runnable - { - private volatile boolean done = false; - - /* ------------------------------------------------------------ */ - public void setDone() - { - done = true; - } - - /* ------------------------------------------------------------ */ - public void run() - { - spin(); - } - - /* ------------------------------------------------------------ */ - public void spin() - { - long result=-1; - long end=TimeUnit.NANOSECONDS.toMillis(System.nanoTime())+DURATION+1000; - while (!done && TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) 1 ? fn(value-1) : 1; - - Thread.sleep(50); - - return result; - } - } -} diff --git a/jetty-monitor/src/test/resources/jetty-logging.properties b/jetty-monitor/src/test/resources/jetty-logging.properties deleted file mode 100644 index 2071498c3d6..00000000000 --- a/jetty-monitor/src/test/resources/jetty-logging.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -#org.eclipse.jetty.LEVEL=DEBUG -#org.eclipse.jetty.monitor.LEVEL=DEBUG From a810ecf67e272d17b55bdb9500b2fb8f54cbf7bf Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2018 15:59:37 +1100 Subject: [PATCH 45/87] Fixed test with atomic the --task was not protected with a memory barrier, so different producing threads could contend on the field. Signed-off-by: Greg Wilkins --- .../jetty/util/thread/strategy/ExecutionStrategyTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java index 1e4cb87cd19..93b0a21779e 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java @@ -156,11 +156,11 @@ public class ExecutionStrategyTest Producer producer = new TestProducer() { - int tasks=TASKS; + AtomicInteger tasks = new AtomicInteger(TASKS); @Override public Runnable produce() { - final int id = --tasks; + final int id = tasks.decrementAndGet(); if (id>=0) { while(_threads.isRunning()) From ed907f8ed9ff1d87406e2343e600e8f9775ad7f3 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2018 16:05:16 +1100 Subject: [PATCH 46/87] more generous test times Signed-off-by: Greg Wilkins --- .../eclipse/jetty/server/LowResourcesMonitorTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java index ddf14534eff..121ef30d5cf 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java @@ -218,28 +218,28 @@ public class LowResourcesMonitorTest @Test public void testMaxLowResourceTime() throws Exception { - _lowResourcesMonitor.setMaxLowResourcesTime(2000); + _lowResourcesMonitor.setMaxLowResourcesTime(5000); Assert.assertFalse(_lowResourcesMonitor.isLowOnResources()); try(Socket socket0 = new Socket("localhost",_connector.getLocalPort())) { _lowResourcesMonitor.setMaxMemory(1); - Thread.sleep(1200); + Thread.sleep(2400); Assert.assertTrue(_lowResourcesMonitor.isLowOnResources()); try(Socket socket1 = new Socket("localhost",_connector.getLocalPort())) { - Thread.sleep(1200); + Thread.sleep(2400); Assert.assertTrue(_lowResourcesMonitor.isLowOnResources()); Assert.assertEquals(-1,socket0.getInputStream().read()); socket1.getOutputStream().write("G".getBytes(StandardCharsets.UTF_8)); - Thread.sleep(1200); + Thread.sleep(2400); Assert.assertTrue(_lowResourcesMonitor.isLowOnResources()); socket1.getOutputStream().write("E".getBytes(StandardCharsets.UTF_8)); - Thread.sleep(1200); + Thread.sleep(2400); Assert.assertTrue(_lowResourcesMonitor.isLowOnResources()); Assert.assertEquals(-1,socket1.getInputStream().read()); } From a41f7bd927862a35d62deff2b34d68cfe35ac3b2 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 14 Mar 2018 16:57:15 +1100 Subject: [PATCH 47/87] More debug in test Signed-off-by: Greg Wilkins --- .../strategy/ExecutionStrategyTest.java | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java index 93b0a21779e..31fa6245e87 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java @@ -29,6 +29,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jetty.util.component.LifeCycle; @@ -153,6 +154,9 @@ public class ExecutionStrategyTest { final int TASKS = 3*_threads.getMaxThreads(); final BlockingQueue q = new ArrayBlockingQueue<>(_threads.getMaxThreads()); + final AtomicInteger taken = new AtomicInteger(0); + final AtomicInteger run = new AtomicInteger(0); + final AtomicBoolean producing = new AtomicBoolean(false); Producer producer = new TestProducer() { @@ -161,29 +165,42 @@ public class ExecutionStrategyTest public Runnable produce() { final int id = tasks.decrementAndGet(); - if (id>=0) + try { - while(_threads.isRunning()) + if (!producing.compareAndSet(false,true)) + System.err.println("MULTIPLE PRODUCERS "+id); + + if (id>=0) { - try + while(_threads.isRunning()) { - final CountDownLatch latch = q.take(); - return new Runnable() + try { - @Override - public void run() + final CountDownLatch latch = q.take(); + taken.incrementAndGet(); + return new Runnable() { - // System.err.println("RUN "+id); - latch.countDown(); - } - }; - } - catch(InterruptedException e) - { - e.printStackTrace(); + @Override + public void run() + { + run.incrementAndGet(); + // System.err.println("RUN "+id); + latch.countDown(); + } + }; + } + catch(InterruptedException e) + { + e.printStackTrace(); + } } } } + finally + { + if (!producing.compareAndSet(true,false)) + System.err.println("Multiple produced "+id); + } return null; } @@ -218,6 +235,7 @@ public class ExecutionStrategyTest if (!latch.await(30,TimeUnit.SECONDS)) { System.err.println(_strategy); + System.err.printf("tasks=%d latch=%d taken=%d run=%d q=%d%n",TASKS,latch.getCount(),taken.get(),run.get(), q.size()); _threads.dumpStdErr(); Assert.fail(); } From 932295651262ddbd2db8ac0864b2d23421d11db3 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 14 Mar 2018 10:28:56 -0500 Subject: [PATCH 48/87] Issue #2210 - adding httpclient safety checks. + ISE on non started HttpClient + ISE on use of wss:// URI with HttpClient without an SSL config --- .../websocket/client/WebSocketClient.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index 1b5bd96a083..c12ee710f9c 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -25,6 +25,7 @@ import java.net.URI; import java.util.Collections; import java.util.HashSet; import java.util.Locale; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.Future; @@ -368,6 +369,15 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont throw new IllegalArgumentException("WebSocket URI scheme only supports [ws] and [wss], not [" + scheme + "]"); } + if ("wss".equals(scheme)) + { + // test for ssl context + if (httpClient.getSslContextFactory() == null) + { + throw new IllegalStateException("HttpClient has no SslContextFactory, wss:// URI's are not supported in this configuration"); + } + } + request.setRequestURI(toUri); request.setLocalEndpoint(websocket); @@ -391,6 +401,17 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont return wsReq.sendAsync(); } + @Override + protected void doStart() throws Exception + { + Objects.requireNonNull(httpClient, "Provided HttpClient is null"); + + if (!httpClient.isRunning()) + throw new IllegalStateException("HttpClient is not running (did you forget to start it?): " + httpClient); + + super.doStart(); + } + @Override protected void doStop() throws Exception { From 93b6877d724cbec52cc427e168144d539ea8e38b Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 14 Mar 2018 16:18:19 -0500 Subject: [PATCH 49/87] Issue #2210 - fixing flaw in safety checks with JSR356 ClientContainer --- .../org/eclipse/jetty/websocket/jsr356/ClientContainer.java | 5 +++-- .../org/eclipse/jetty/websocket/client/WebSocketClient.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java index 44090bc36af..17bedc87b06 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/ClientContainer.java @@ -98,6 +98,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont // This constructor is used with Standalone JSR Client usage. this(new SimpleContainerScope(WebSocketPolicy.newClientPolicy())); client.setDaemon(true); + client.addManaged(client.getHttpClient()); } /** @@ -108,6 +109,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont public ClientContainer(final WebSocketContainerScope scope) { this(scope, null); + client.addManaged(client.getHttpClient()); } /** @@ -136,8 +138,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont new JsrEventDriverFactory(scopeDelegate), new JsrSessionFactory(this), httpClient); - this.client.addBean(httpClient); - + if(jsr356TrustAll != null) { boolean trustAll = Boolean.parseBoolean(jsr356TrustAll); diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index c12ee710f9c..331eb7f8fd3 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -406,10 +406,10 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont { Objects.requireNonNull(httpClient, "Provided HttpClient is null"); + super.doStart(); + if (!httpClient.isRunning()) throw new IllegalStateException("HttpClient is not running (did you forget to start it?): " + httpClient); - - super.doStart(); } @Override From 484280bac6956f9db0d98db60739f5368dec3691 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 14 Mar 2018 13:23:02 -0500 Subject: [PATCH 50/87] Issue #2218 - Windows Selector Bug Signed-off-by: Joakim Erdfelt --- .../eclipse/jetty/client/LivelockTest.java | 86 +++++++++++++------ .../test/resources/jetty-logging.properties | 4 +- .../org/eclipse/jetty/io/ManagedSelector.java | 7 +- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java index 448dd426d16..aa359c69b80 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java @@ -19,6 +19,8 @@ package org.eclipse.jetty.client; import java.nio.channels.Selector; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -30,14 +32,37 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.SocketAddressResolver; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(Parameterized.class) public class LivelockTest { + @Parameterized.Parameters(name = "server={0}, client={1}") + public static List data() + { + List data = new ArrayList<>(); + // Server-live-lock, Client-live-lock + data.add(new Object[] { true, true }); + data.add(new Object[] { true, false }); + data.add(new Object[] { false, true }); + data.add(new Object[] { false, false }); + return data; + } + + @Parameterized.Parameter(0) + public boolean serverLiveLock; + + @Parameterized.Parameter(1) + public boolean clientLiveLock; + private Server server; private ServerConnector connector; private HttpClient client; @@ -73,7 +98,7 @@ public class LivelockTest // ManagedSelectors that submit themselves in an attempt to cause a live lock // as there will always be an action available to run. - int count = 25; + int count = 5; HttpClientTransport transport = new HttpClientTransportOverHTTP(1); client = new HttpClient(transport, null); client.setMaxConnectionsPerDestination(2 * count); @@ -88,34 +113,21 @@ public class LivelockTest AtomicBoolean busy = new AtomicBoolean(true); - ManagedSelector clientSelector = client.getContainedBeans(ManagedSelector.class).stream().findAny().get(); - ManagedSelector.SelectorUpdate clientLivelock = new ManagedSelector.SelectorUpdate() + if (clientLiveLock) { - @Override - public void update(Selector selector) - { - sleep(10); - if (busy.get()) - clientSelector.submit(this); - } - }; - clientSelector.submit(clientLivelock); - - ManagedSelector serverSelector = connector.getContainedBeans(ManagedSelector.class).stream().findAny().get(); - ManagedSelector.SelectorUpdate serverLivelock = new ManagedSelector.SelectorUpdate() + ManagedSelector clientSelector = client.getContainedBeans(ManagedSelector.class).stream().findAny().get(); + busyLiveLock(busy, clientSelector); + } + + if (serverLiveLock) { - @Override - public void update(Selector selector) - { - sleep(10); - if (busy.get()) - serverSelector.submit(this); - } - }; - serverSelector.submit(serverLivelock); + ManagedSelector serverSelector = connector.getContainedBeans(ManagedSelector.class).stream().findAny().get(); + busyLiveLock(busy, serverSelector); + } int requestRate = 5; long pause = 1000 / requestRate; + Logger clientLog = Log.getLogger("TESTClient"); CountDownLatch latch = new CountDownLatch(count); for (int i = 0; i < count; ++i) { @@ -125,6 +137,13 @@ public class LivelockTest { if (result.isSucceeded() && result.getResponse().getStatus() == HttpStatus.OK_200) latch.countDown(); + else + { + if(result.getRequestFailure() != null) + clientLog.warn(result.getRequestFailure()); + if(result.getResponseFailure() != null) + clientLog.warn(result.getResponseFailure()); + } }); sleep(pause); } @@ -134,11 +153,26 @@ public class LivelockTest busy.set(false); } - private void sleep(long time) + private void busyLiveLock(AtomicBoolean busy, ManagedSelector managedSelector) + { + ManagedSelector.SelectorUpdate liveLock = new ManagedSelector.SelectorUpdate() + { + @Override + public void update(Selector selector) + { + sleep(10); + if (busy.get()) + managedSelector.submit(this); + } + }; + managedSelector.submit(liveLock); + } + + private void sleep(long millis) { try { - Thread.sleep(time); + TimeUnit.MILLISECONDS.sleep(millis); } catch (InterruptedException x) { diff --git a/jetty-client/src/test/resources/jetty-logging.properties b/jetty-client/src/test/resources/jetty-logging.properties index a2296dfdf69..3f7f23333ae 100644 --- a/jetty-client/src/test/resources/jetty-logging.properties +++ b/jetty-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 +class=org.eclipse.jetty.util.log.StdErrLog +#org.eclipse.jetty.LEVEL=INFO #org.eclipse.jetty.client.LEVEL=DEBUG #org.eclipse.jetty.io.ChannelEndPoint.LEVEL=DEBUG #org.eclipse.jetty.http.LEVEL=DEBUG diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index 36900ba547f..5f9ad3ccedd 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -42,7 +42,6 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import org.eclipse.jetty.io.ManagedSelector.Connect; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; @@ -322,7 +321,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable return task; processUpdates(); - + updateKeys(); if (!select()) @@ -372,7 +371,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable LOG.debug("updates {}",updates); if (selector != null) - selector.wakeup(); + selector.wakeup(); } private boolean select() @@ -385,6 +384,8 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable if (LOG.isDebugEnabled()) LOG.debug("Selector {} waiting on select", selector); int selected = selector.select(); + if (selected == 0) + selected = selector.selectNow(); if (LOG.isDebugEnabled()) LOG.debug("Selector {} woken up from select, {}/{} selected", selector, selected, selector.keys().size()); From afc820c7f960e9a30c283be070dd57a377b483ef Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 15 Mar 2018 10:19:27 +1100 Subject: [PATCH 51/87] fixed test by removing extra produce Signed-off-by: Greg Wilkins --- .../strategy/ExecutionStrategyTest.java | 52 +++++++------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java index 31fa6245e87..cb342024184 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java @@ -154,9 +154,6 @@ public class ExecutionStrategyTest { final int TASKS = 3*_threads.getMaxThreads(); final BlockingQueue q = new ArrayBlockingQueue<>(_threads.getMaxThreads()); - final AtomicInteger taken = new AtomicInteger(0); - final AtomicInteger run = new AtomicInteger(0); - final AtomicBoolean producing = new AtomicBoolean(false); Producer producer = new TestProducer() { @@ -165,47 +162,35 @@ public class ExecutionStrategyTest public Runnable produce() { final int id = tasks.decrementAndGet(); - try - { - if (!producing.compareAndSet(false,true)) - System.err.println("MULTIPLE PRODUCERS "+id); - if (id>=0) + if (id>=0) + { + while(_threads.isRunning()) { - while(_threads.isRunning()) + try { - try + final CountDownLatch latch = q.take(); + return new Runnable() { - final CountDownLatch latch = q.take(); - taken.incrementAndGet(); - return new Runnable() + @Override + public void run() { - @Override - public void run() - { - run.incrementAndGet(); - // System.err.println("RUN "+id); - latch.countDown(); - } - }; - } - catch(InterruptedException e) - { - e.printStackTrace(); - } + // System.err.println("RUN "+id); + latch.countDown(); + } + }; + } + catch(InterruptedException e) + { + e.printStackTrace(); } } } - finally - { - if (!producing.compareAndSet(true,false)) - System.err.println("Multiple produced "+id); - } return null; } }; - + newExecutionStrategy(producer,_threads); _strategy.dispatch(); @@ -222,7 +207,6 @@ public class ExecutionStrategyTest { Thread.sleep(20); q.offer(latch); - _strategy.produce(); } } catch(Exception e) @@ -235,7 +219,7 @@ public class ExecutionStrategyTest if (!latch.await(30,TimeUnit.SECONDS)) { System.err.println(_strategy); - System.err.printf("tasks=%d latch=%d taken=%d run=%d q=%d%n",TASKS,latch.getCount(),taken.get(),run.get(), q.size()); + System.err.printf("tasks=%d latch=%d q=%d%n",TASKS,latch.getCount(), q.size()); _threads.dumpStdErr(); Assert.fail(); } From c8d6f0a3bba42d46f583b82b8cc719de9f91f90a Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 15 Mar 2018 10:41:50 +1100 Subject: [PATCH 52/87] Recursion protection for SSL flush try again #2233 Protecton from recursion in SSL flush try again #2233 This would not be needed if we could make flush iterate when necessary. Signed-off-by: Greg Wilkins --- .../eclipse/jetty/io/ssl/SslConnection.java | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java index 1ac15fe0ce1..07441e3e4bb 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java @@ -81,7 +81,8 @@ import org.eclipse.jetty.util.thread.Invocable; public class SslConnection extends AbstractConnection { private static final Logger LOG = Log.getLogger(SslConnection.class); - + private static final ThreadLocal __tryWriteAgain = new ThreadLocal<>(); + private final List handshakeListeners = new ArrayList<>(); private final ByteBufferPool _bufferPool; private final SSLEngine _sslEngine; @@ -95,7 +96,7 @@ public class SslConnection extends AbstractConnection private int _renegotiationLimit = -1; private boolean _closedOutbound; private boolean _allowMissingCloseMessage = true; - + private abstract class RunnableTask implements Runnable, Invocable { private final String _operation; @@ -506,11 +507,12 @@ public class SslConnection extends AbstractConnection } else { + // TODO This should not be required and we should be able to do all retries within flush // We can get here because the WriteFlusher might not see progress // when it has just flushed the encrypted data, but not consumed anymore // of the application buffers. This is mostly avoided by another iteration - // within DecryptedEndPoint flush(), but I cannot convince myself that - // this is never ever the case. + // within DecryptedEndPoint flush(), but this still occurs sometime on some + // tests on some systems??? More investigation is needed! try_again = true; } } @@ -526,12 +528,35 @@ public class SslConnection extends AbstractConnection { // don't bother writing, just notify of close getWriteFlusher().onClose(); + return; + } + + // TODO this ugly recursion protection is only needed until we remove the try again + // logic from this method and make flush do the try again. + Boolean tryWriteAgain = __tryWriteAgain.get(); + if (tryWriteAgain==null) + { + try + { + // Keep running complete write until + __tryWriteAgain.set(Boolean.FALSE); + do + { + _runCompleteWrite.run(); + } + while (Boolean.TRUE.equals(__tryWriteAgain.get())); + } + finally + { + __tryWriteAgain.remove(); + } } else { - // Try again - _runCompleteWrite.run(); + // Don't recurse but get top caller to iterate + __tryWriteAgain.set(Boolean.TRUE); } + } } From 39013cbc9166401599e4b30a4df94275c847a057 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Tue, 13 Mar 2018 09:56:22 +1000 Subject: [PATCH 53/87] adding myself in developers section to test commit karma Signed-off-by: olivier lamy --- pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pom.xml b/pom.xml index bae5df5fa97..2223e3de6f9 100644 --- a/pom.xml +++ b/pom.xml @@ -1755,6 +1755,14 @@ IBM -8 + + olamy + Olivier Lamy + oliver.lamy@gmail.com + Webtide, LLC + https://webtide.com + Australia/Brisbane + From 016df7e15b3c85933465c781de808f3289f20da7 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 15 Mar 2018 15:48:31 +1000 Subject: [PATCH 54/87] use settings file which configure using nexus mirror Signed-off-by: olivier lamy --- Jenkinsfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 20a937eb1fe..a2d6e8da43b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -41,6 +41,7 @@ def getFullBuild(jdk, os) { maven: 'maven3', jdk: "$jdk", publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: 'oss-settings.xml', mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") { sh "mvn -V -B clean install -Dtest=None -T6" } @@ -62,6 +63,7 @@ def getFullBuild(jdk, os) { maven: 'maven3', jdk: "$jdk", publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: 'oss-settings.xml', mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") { sh "mvn -V -B javadoc:javadoc -T5" } @@ -83,6 +85,7 @@ def getFullBuild(jdk, os) { maven: 'maven3', jdk: "$jdk", publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: 'oss-settings.xml', mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") { // sh "mvn -V -B install -Dmaven.test.failure.ignore=true -Prun-its -T3 -e -Dmaven.repo.local=${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}" @@ -137,6 +140,7 @@ def getFullBuild(jdk, os) { maven: 'maven3', jdk: "$jdk", publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: 'oss-settings.xml', mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") { sh "mvn -V -B -Pcompact3 clean install -T5" } From 28489abc3ab354528d216b032e05c34903892e64 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 15 Mar 2018 11:08:32 +0100 Subject: [PATCH 55/87] Removed jetty-spdy module that mistakenly reappeared in the project tree. --- jetty-spdy/pom.xml | 88 ------------- jetty-spdy/spdy-alpn-tests/pom.xml | 93 -------------- jetty-spdy/spdy-client/pom.xml | 66 ---------- jetty-spdy/spdy-core/pom.xml | 35 ----- jetty-spdy/spdy-example-webapp/pom.xml | 84 ------------ jetty-spdy/spdy-http-client-transport/pom.xml | 71 ----------- jetty-spdy/spdy-http-common/pom.xml | 48 ------- jetty-spdy/spdy-http-server/pom.xml | 120 ------------------ jetty-spdy/spdy-server/pom.xml | 72 ----------- 9 files changed, 677 deletions(-) delete mode 100644 jetty-spdy/pom.xml delete mode 100644 jetty-spdy/spdy-alpn-tests/pom.xml delete mode 100644 jetty-spdy/spdy-client/pom.xml delete mode 100644 jetty-spdy/spdy-core/pom.xml delete mode 100644 jetty-spdy/spdy-example-webapp/pom.xml delete mode 100644 jetty-spdy/spdy-http-client-transport/pom.xml delete mode 100644 jetty-spdy/spdy-http-common/pom.xml delete mode 100644 jetty-spdy/spdy-http-server/pom.xml delete mode 100644 jetty-spdy/spdy-server/pom.xml diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml deleted file mode 100644 index 9ec565c9d74..00000000000 --- a/jetty-spdy/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - org.eclipse.jetty - jetty-project - 9.2.23-SNAPSHOT - - - 4.0.0 - org.eclipse.jetty.spdy - spdy-parent - pom - Jetty :: SPDY :: Parent - http://www.eclipse.org/jetty - - - spdy-core - spdy-client - spdy-server - spdy-http-common - spdy-http-server - spdy-http-client-transport - spdy-example-webapp - spdy-alpn-tests - - - - - npn - - 1.7 - - - - - - - - - - - maven-pmd-plugin - - true - - - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - org.eclipse.jetty.spdy.*;version="9.1" - org.eclipse.jetty.*;version="[9.0,10.0)",* - <_nouses>true - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - - - - - - - org.eclipse.jetty.toolchain - jetty-test-helper - test - - - - diff --git a/jetty-spdy/spdy-alpn-tests/pom.xml b/jetty-spdy/spdy-alpn-tests/pom.xml deleted file mode 100644 index d0931a162c1..00000000000 --- a/jetty-spdy/spdy-alpn-tests/pom.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - - 4.0.0 - spdy-alpn-tests - Jetty :: SPDY :: ALPN Tests - - - - - maven-dependency-plugin - - - copy - generate-resources - - copy - - - - - org.mortbay.jetty.alpn - alpn-boot - ${alpn.version} - jar - false - ${project.build.directory}/alpn - - - - - - - - maven-surefire-plugin - - -Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar - - - - - - - - org.eclipse.jetty.alpn - alpn-api - ${alpn.api.version} - provided - - - org.eclipse.jetty - jetty-alpn-server - ${project.version} - provided - - - org.eclipse.jetty - jetty-server - ${project.version} - test - - - org.eclipse.jetty.spdy - spdy-server - ${project.version} - test - - - org.eclipse.jetty.spdy - spdy-http-server - ${project.version} - test - - - org.eclipse.jetty.spdy - spdy-http-server - ${project.version} - tests - test - - - junit - junit - test - - - - diff --git a/jetty-spdy/spdy-client/pom.xml b/jetty-spdy/spdy-client/pom.xml deleted file mode 100644 index 6f0bb90e92b..00000000000 --- a/jetty-spdy/spdy-client/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - - 4.0.0 - spdy-client - Jetty :: SPDY :: Client Binding - - - ${project.groupId}.client - - - http://www.eclipse.org/jetty - - - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - org.eclipse.jetty.spdy.client;version="9.1" - !org.eclipse.jetty.npn,!org.eclipse.jetty.alpn,org.eclipse.jetty.*;version="[9.0,10.0)",* - - - - - - - - - - - org.eclipse.jetty.spdy - spdy-core - ${project.version} - - - org.eclipse.jetty - jetty-alpn-client - ${project.version} - - - org.eclipse.jetty.alpn - alpn-api - ${alpn.api.version} - provided - - - org.eclipse.jetty.npn - npn-api - ${npn.api.version} - provided - - - - diff --git a/jetty-spdy/spdy-core/pom.xml b/jetty-spdy/spdy-core/pom.xml deleted file mode 100644 index b35715e3259..00000000000 --- a/jetty-spdy/spdy-core/pom.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - - 4.0.0 - spdy-core - Jetty :: SPDY :: Core - - - ${project.groupId}.core - - - - - org.eclipse.jetty - jetty-util - ${project.version} - - - org.eclipse.jetty - jetty-io - ${project.version} - - - org.mockito - mockito-core - test - - - - diff --git a/jetty-spdy/spdy-example-webapp/pom.xml b/jetty-spdy/spdy-example-webapp/pom.xml deleted file mode 100644 index 2f806788368..00000000000 --- a/jetty-spdy/spdy-example-webapp/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - 4.0.0 - spdy-example-webapp - war - Jetty :: SPDY :: HTTP Web Application - - - - - org.eclipse.jetty - jetty-maven-plugin - ${project.version} - - 8888 - quit - - -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn.version}/npn-boot-${npn.version}.jar - - ${basedir}/src/main/config/example-jetty-spdy.xml - / - - run - run-war - deploy - start - stop - - - - - org.eclipse.jetty.spdy - spdy-http-server - ${project.version} - - - - - - - - - proxy - - - - org.eclipse.jetty - jetty-maven-plugin - ${project.version} - - 8888 - quit - - -Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn.version}/npn-boot-${npn.version}.jar - - ${basedir}/src/main/config/example-jetty-spdy-proxy.xml - / - - run - run-war - deploy - start - stop - - - - - org.eclipse.jetty.spdy - spdy-http-server - ${project.version} - - - - - - - - - diff --git a/jetty-spdy/spdy-http-client-transport/pom.xml b/jetty-spdy/spdy-http-client-transport/pom.xml deleted file mode 100644 index 0c6ad340246..00000000000 --- a/jetty-spdy/spdy-http-client-transport/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - - 4.0.0 - spdy-http-client-transport - Jetty :: SPDY :: HTTP Client Transport - - - ${project.groupId}.client.http - - - - - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - org.eclipse.jetty.spdy.client.http;version="9.1" - !org.eclipse.jetty.npn,org.eclipse.jetty.*;version="[9.0,10.0)",* - - - - - - - - - - - org.eclipse.jetty - jetty-client - ${project.version} - - - org.eclipse.jetty.spdy - spdy-client - ${project.version} - - - org.eclipse.jetty.spdy - spdy-http-common - ${project.version} - - - - org.eclipse.jetty - jetty-server - ${project.version} - test - - - org.eclipse.jetty.spdy - spdy-http-server - ${project.version} - test - - - - diff --git a/jetty-spdy/spdy-http-common/pom.xml b/jetty-spdy/spdy-http-common/pom.xml deleted file mode 100644 index c0a97d9d21f..00000000000 --- a/jetty-spdy/spdy-http-common/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - - 4.0.0 - spdy-http-common - Jetty :: SPDY :: HTTP Common - - - ${project.groupId}.http.common - - - - - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - org.eclipse.jetty.spdy.http;version="9.1" - !org.eclipse.jetty.npn,org.eclipse.jetty.*;version="[9.0,10.0)",* - - - - - - - - - - - org.eclipse.jetty.spdy - spdy-core - ${project.version} - - - - diff --git a/jetty-spdy/spdy-http-server/pom.xml b/jetty-spdy/spdy-http-server/pom.xml deleted file mode 100644 index 4757f3633c1..00000000000 --- a/jetty-spdy/spdy-http-server/pom.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - 4.0.0 - spdy-http-server - Jetty :: SPDY :: HTTP Server - - - ${project.groupId}.http.server - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - - config - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - artifact-jars - - jar - test-jar - - - - - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - org.eclipse.jetty.spdy.server.http;version="9.1", - org.eclipse.jetty.spdy.server.proxy;version="9.1" - - !org.eclipse.jetty.npn,org.eclipse.jetty.*;version="[9.0,10.0)",* - - <_nouses>true - - - - - - - - - - - org.eclipse.jetty.spdy - spdy-http-common - ${project.version} - - - org.eclipse.jetty.spdy - spdy-server - ${project.version} - - - org.eclipse.jetty - jetty-client - ${project.version} - - - org.eclipse.jetty - jetty-servlet - ${project.version} - test - - - org.eclipse.jetty - jetty-servlets - ${project.version} - test - - - org.eclipse.jetty.npn - npn-api - ${npn.api.version} - test - - - org.eclipse.jetty - jetty-continuation - ${project.version} - test - - - org.mockito - mockito-core - test - - - - diff --git a/jetty-spdy/spdy-server/pom.xml b/jetty-spdy/spdy-server/pom.xml deleted file mode 100644 index 71440708754..00000000000 --- a/jetty-spdy/spdy-server/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - org.eclipse.jetty.spdy - spdy-parent - 9.2.23-SNAPSHOT - - - 4.0.0 - spdy-server - Jetty :: SPDY :: Server Binding - - - ${project.groupId}.server - - - http://www.eclipse.org/jetty - - - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - org.eclipse.jetty.spdy.server;version="9.1" - org.eclipse.jetty.alpn;resolution:=optional,org.eclipse.jetty.alpn.server;resolution:=optional, org.eclipse.jetty.npn;resolution:=optional,org.eclipse.jetty.*;version="[9.0,10.0)",* - <_nouses>true - - - - - - - - - - - org.eclipse.jetty.spdy - spdy-core - ${project.version} - - - org.eclipse.jetty.spdy - spdy-client - ${project.version} - - - org.eclipse.jetty - jetty-server - ${project.version} - - - org.eclipse.jetty.npn - npn-api - ${npn.api.version} - provided - - - org.eclipse.jetty.alpn - alpn-api - ${alpn.api.version} - provided - - - - From 4ce7e9591bda00097ff7f8e2f2530de991e3b700 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 15 Mar 2018 22:49:20 +1100 Subject: [PATCH 56/87] Safer simpler version parsing #2284 Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/server/Server.java | 2 +- .../org/eclipse/jetty/start/StartArgs.java | 3 +- .../org/eclipse/jetty/util/JavaVersion.java | 43 +++++++++---------- .../eclipse/jetty/util/JavaVersionTest.java | 11 +++++ 4 files changed, 34 insertions(+), 25 deletions(-) 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 989dbdf004c..a7f2c15f9d6 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 @@ -371,7 +371,7 @@ public class Server extends HandlerWrapper implements Attributes String gitHash = Jetty.GIT_HASH; String timestamp = Jetty.BUILD_TIMESTAMP; - LOG.info("jetty-{}; built: {}; git: {}; jvm {}", getVersion(), timestamp, gitHash, JavaVersion.VERSION); + LOG.info("jetty-{}; built: {}; git: {}; jvm {}", getVersion(), timestamp, gitHash, System.getProperty("java.runtime.version",System.getProperty("java.version"))); if (!Jetty.STABLE) { LOG.warn("THIS IS NOT A STABLE RELEASE! DO NOT USE IN PRODUCTION!"); diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index 235b0358626..00301abfe8f 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -1265,12 +1265,11 @@ public class StartArgs try { JavaVersion ver = JavaVersion.parse(value); - properties.setProperty("java.version",ver.getVersion(),source); + properties.setProperty("java.version",System.getProperty("java.version"),source); properties.setProperty("java.version.platform",Integer.toString(ver.getPlatform()),source); properties.setProperty("java.version.major",Integer.toString(ver.getMajor()),source); properties.setProperty("java.version.minor",Integer.toString(ver.getMinor()),source); properties.setProperty("java.version.micro",Integer.toString(ver.getMicro()),source); - properties.setProperty("java.version.update",Integer.toString(ver.getUpdate()),source); } catch (Throwable x) { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java index 69117e6ddae..f1cbd74b718 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java @@ -32,35 +32,34 @@ public class JavaVersion * Acceptable values should correspond to those returned by JavaVersion.getPlatform(). */ public static final String JAVA_TARGET_PLATFORM = "org.eclipse.jetty.javaTargetPlatform"; - - /** Regex for Java version numbers */ - private static final String VSTR_FORMAT = "(?[1-9][0-9]*(?:(?:\\.0)*\\.[0-9]+)*).*"; - - static final Pattern VSTR_PATTERN = Pattern.compile(VSTR_FORMAT); - - public static final JavaVersion VERSION = parse(System.getProperty("java.runtime.version",System.getProperty("java.version","1.8"))); + + public static final JavaVersion VERSION = parse(System.getProperty("java.version")); public static JavaVersion parse(String v) - { - Matcher m = VSTR_PATTERN.matcher(v); - if (!m.matches() || m.group("VNUM")==null) - { - System.err.println("ERROR: Invalid version string: '" + v + "'"); - return new JavaVersion(v+"-UNKNOWN",8,1,8,0); - } - + { // $VNUM is a dot-separated list of integers of arbitrary length - String[] split = m.group("VNUM").split("\\."); - int[] version = new int[split.length]; - for (int i = 0; i < split.length; i++) - version[i] = Integer.parseInt(split[i]); + String[] split = v.split("[^0-9]"); + int len = Math.min(split.length,3); + int[] version = new int[len]; + for (int i = 0; i < len; i++) + { + try + { + version[i] = Integer.parseInt(split[i]); + } + catch(Throwable e) + { + len = i-1; + break; + } + } return new JavaVersion( v, - (version[0]>=9 || version.length==1)?version[0]:version[1], + (version[0]>=9 || len==1)?version[0]:version[1], version[0], - version.length>1?version[1]:0, - version.length>2?version[2]:0); + len>1?version[1]:0, + len>2?version[2]:0); } private final String version; diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java index bf1640c812e..b02896c454d 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java @@ -28,6 +28,17 @@ import org.junit.Test; */ public class JavaVersionTest { + @Test + public void testAndroid() + { + JavaVersion version = JavaVersion.parse("0.9"); + assertThat(version.toString(),is("0.9")); + assertThat(version.getPlatform(),is(9)); + assertThat(version.getMajor(),is(0)); + assertThat(version.getMinor(),is(9)); + assertThat(version.getMicro(),is(0)); + } + @Test public void test9() { From 1da19dc2fdf794f0f23acc776be94ebba41b2640 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 15 Mar 2018 23:12:58 +1100 Subject: [PATCH 57/87] [WIP!] HTTP Close #1832 (#2338) * Only close if parser closed and output is shutdown Signed-off-by: Greg Wilkins * a better possible fix Signed-off-by: Greg Wilkins * after review Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/io/AbstractEndPoint.java | 8 ++++++++ .../main/java/org/eclipse/jetty/io/WriteFlusher.java | 2 ++ .../java/org/eclipse/jetty/server/HttpConnection.java | 9 ++------- .../eclipse/jetty/server/ConnectionOpenCloseTest.java | 11 ++++++----- 4 files changed, 18 insertions(+), 12 deletions(-) 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 5695e988e45..105bbd74584 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 @@ -62,6 +62,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint protected final void shutdownInput() { + if (LOG.isDebugEnabled()) + LOG.debug("shutdownInput {}",this); while(true) { State s = _state.get(); @@ -114,6 +116,8 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint @Override public final void shutdownOutput() { + if (LOG.isDebugEnabled()) + LOG.debug("shutdownOutput {}",this); while(true) { State s = _state.get(); @@ -166,11 +170,15 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint @Override public final void close() { + if (LOG.isDebugEnabled()) + LOG.debug("close {}",this); close(null); } protected final void close(Throwable failure) { + if (LOG.isDebugEnabled()) + LOG.debug("close({}) {}",failure,this); while(true) { State s = _state.get(); diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java index c9b56d4ecdf..86465065a79 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java @@ -496,6 +496,8 @@ abstract public class WriteFlusher public boolean onFail(Throwable cause) { // Keep trying to handle the failure until we get to IDLE or FAILED state + if (cause!=null) + cause.addSuppressed(new Throwable()); while (true) { State current = _state.get(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index 9577392af53..fc10d546594 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -243,6 +243,8 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http int filled = fillRequestBuffer(); if (filled>0) bytesIn.add(filled); + else if (filled==-1 && getEndPoint().isOutputShutdown()) + close(); // Parse the request buffer. boolean handle = parseRequestBuffer(); @@ -252,13 +254,6 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http if (getEndPoint().getConnection()!=this) break; - // Handle closed parser. - if (_parser.isClose() || _parser.isClosed()) - { - close(); - break; - } - // Handle channel event if (handle) { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java index 97bf92123de..f71c3a24496 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -42,9 +43,11 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.annotation.Slow; +import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -224,11 +227,9 @@ public class ConnectionOpenCloseTest extends AbstractHttpTest "\r\n").getBytes(StandardCharsets.UTF_8)); output.flush(); - InputStream inputStream = socket.getInputStream(); - HttpTester.Response response = HttpTester.parseResponse(inputStream); - Assert.assertEquals(200, response.getStatus()); - - Assert.assertEquals(-1, inputStream.read()); + // Read to EOF + String response = BufferUtil.toString(ByteBuffer.wrap(IO.readBytes(socket.getInputStream()))); + assertThat(response,Matchers.containsString("200 OK")); socket.close(); Assert.assertTrue(openLatch.await(5, TimeUnit.SECONDS)); From 44546e5ca93c140e6f710ca08d5091ac499c9397 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 15 Mar 2018 07:36:50 -0500 Subject: [PATCH 58/87] Fixing jetty-start tests Signed-off-by: Joakim Erdfelt --- .../startup/screen-empty-base-listconfig.adoc | 4 ---- .../startup/screen-http-webapp-deploy-listconfig.adoc | 4 ---- .../src/main/java/org/eclipse/jetty/start/StartArgs.java | 8 ++++---- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc index 113f785ded3..712487db306 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc @@ -59,10 +59,6 @@ System Properties: Properties: ----------- java.version = 1.8.0_92 - java.version.major = 1 - java.version.minor = 8 - java.version.revision = 0 - java.version.update = 92 Jetty Server Classpath: ----------------------- diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc index 4b38f264772..b63440dda76 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc @@ -59,10 +59,6 @@ System Properties: Properties: ----------- java.version = 1.8.0_92 - java.version.major = 1 - java.version.minor = 8 - java.version.revision = 0 - java.version.update = 92 Jetty Server Classpath: ----------------------- diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index 00301abfe8f..bf389e2f71a 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -1265,11 +1265,11 @@ public class StartArgs try { JavaVersion ver = JavaVersion.parse(value); - properties.setProperty("java.version",System.getProperty("java.version"),source); properties.setProperty("java.version.platform",Integer.toString(ver.getPlatform()),source); - properties.setProperty("java.version.major",Integer.toString(ver.getMajor()),source); - properties.setProperty("java.version.minor",Integer.toString(ver.getMinor()),source); - properties.setProperty("java.version.micro",Integer.toString(ver.getMicro()),source); + // @deprecated - below will be removed in Jetty 10.x + properties.setProperty("java.version.major", Integer.toString(ver.getMajor()), "Deprecated"); + properties.setProperty("java.version.minor", Integer.toString(ver.getMinor()), "Deprecated"); + properties.setProperty("java.version.micro", Integer.toString(ver.getMicro()), "Deprecated"); } catch (Throwable x) { From b00bb2adb2c200469f7032e5472e1f99318b7fa0 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 15 Mar 2018 16:07:28 +0100 Subject: [PATCH 59/87] Reverted logging level back to INFO. Signed-off-by: Simone Bordet --- .../src/test/resources/jetty-logging.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties b/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties index a7ef5da7827..287d28319e0 100644 --- a/jetty-http2/http2-http-client-transport/src/test/resources/jetty-logging.properties +++ b/jetty-http2/http2-http-client-transport/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.client.LEVEL=DEBUG +#org.eclipse.jetty.client.LEVEL=DEBUG org.eclipse.jetty.http2.hpack.LEVEL=INFO #org.eclipse.jetty.http2.LEVEL=DEBUG #org.eclipse.jetty.io.ssl.LEVEL=DEBUG From 06bb007eb9a961a4a15381c45fefb81e71e6ed6c Mon Sep 17 00:00:00 2001 From: WalkerWatch Date: Thu, 15 Mar 2018 11:52:30 -0400 Subject: [PATCH 60/87] Added documentation warning for #173 --- .../asciidoc/administration/startup/startup-modules.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc index e198222ee56..ee2ff06ebe3 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc @@ -148,6 +148,14 @@ This is done by editing the associated ini file for the module. If your server setup is using a centralized ini configuration, you will edit the `${jetty.base}/server.ini` file. If you have elected to manage each module within it's own ini file, you can find these files in the `${jetty.base}/start.d` directory. +____ +[IMPORTANT] +It is important that you *do not* modify the module files in the `$JETTY_HOME/modules` directory. +$JETTY_HOME should always remain a standard of truth. +If you want to make a change to an actual module file (not the values in its `ini-template`), either edit its associated `ini` file in the `$JETTY_BASE/start.d` directory or make a copy of the desired module file and copy it to the `$JETTY_BASE` directory and edit it there. +The start.jar reads local `$JETTY_BASE/modules` files (if they exist) before scanning `$JETTY_HOME`. +____ + When a module is activated, a number of properties are set by default. To view these defaults, open up the associated ini file. Listed in the ini file is the associated module file and any properties that can be set. From 534b8ea38b3e55b8d5a895de9c602bda6e6a78a8 Mon Sep 17 00:00:00 2001 From: WalkerWatch Date: Thu, 15 Mar 2018 13:23:42 -0400 Subject: [PATCH 61/87] Add edit warning for .mod files. Resolves #173 --- apache-jsp/src/main/config/modules/apache-jsp.mod | 2 ++ apache-jstl/src/main/config/modules/apache-jstl.mod | 2 ++ .../jetty-alpn-server/src/main/config/modules/alpn-impl.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_05.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_101.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_102.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_11.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_111.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_112.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_121.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_131.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_141.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_144.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_151.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_152.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_161.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_162.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_20.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_25.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_31.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_40.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_45.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_51.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_60.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_65.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_66.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_73.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_74.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_91.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-1.8.0_92.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-8.mod | 2 ++ .../src/main/config/modules/alpn-impl/alpn-9.mod | 2 ++ .../jetty-alpn-server/src/main/config/modules/alpn.mod | 2 ++ jetty-annotations/src/main/config/modules/annotations.mod | 2 ++ jetty-cdi/cdi-2/src/main/config/modules/cdi2.mod | 2 ++ jetty-cdi/cdi-servlet/src/main/config/modules/cdi.mod | 2 ++ jetty-cdi/cdi-servlet/src/main/config/modules/cdi1.mod | 2 ++ jetty-client/src/main/config/modules/client.mod | 2 ++ jetty-deploy/src/main/config/modules/deploy.mod | 2 ++ .../src/main/config/modules/global-webapp-common.mod | 2 ++ jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod | 2 ++ .../src/main/config-template/modules/gcloud-datastore.mod | 2 ++ .../src/main/config-template/modules/gcloud.mod | 2 ++ .../main/config-template/modules/session-store-gcloud.mod | 2 ++ .../main/config/modules/session-store-hazelcast-embedded.mod | 2 ++ .../main/config/modules/session-store-hazelcast-remote.mod | 2 ++ jetty-home/src/main/resources/modules/conscrypt.mod | 2 ++ jetty-home/src/main/resources/modules/hawtio.mod | 2 ++ jetty-home/src/main/resources/modules/jamon.mod | 2 ++ jetty-home/src/main/resources/modules/jminix.mod | 2 ++ jetty-home/src/main/resources/modules/jolokia.mod | 2 ++ jetty-home/src/main/resources/modules/jsp.mod | 2 ++ jetty-home/src/main/resources/modules/jstl.mod | 2 ++ jetty-home/src/main/resources/modules/setuid.mod | 2 ++ jetty-home/src/main/resources/modules/stop.mod | 2 ++ jetty-http2/http2-server/src/main/config/modules/http2.mod | 2 ++ jetty-http2/http2-server/src/main/config/modules/http2c.mod | 2 ++ .../config/modules/session-store-infinispan-embedded-910.mod | 2 ++ .../config/modules/session-store-infinispan-embedded.mod | 2 ++ .../config/modules/session-store-infinispan-remote-910.mod | 2 ++ .../main/config/modules/session-store-infinispan-remote.mod | 2 ++ jetty-jaas/src/main/config/modules/jaas.mod | 2 ++ jetty-jaspi/src/main/config/modules/jaspi.mod | 2 ++ jetty-jmx/src/main/config/modules/jmx-remote.mod | 2 ++ jetty-jmx/src/main/config/modules/jmx.mod | 2 ++ jetty-jndi/src/main/jndi-config/modules/jndi.mod | 2 ++ jetty-jndi/src/main/jndi-config/modules/mail.mod | 2 ++ .../jetty-simple-webapp/src/base/modules/testmod.mod | 2 ++ jetty-maven-plugin/src/main/resources/maven.mod | 2 ++ .../modules/sessions/session-data-cache/xmemcached.mod | 2 ++ jetty-nosql/src/main/config/modules/session-store-mongo.mod | 2 ++ .../src/main/config/modules/sessions/mongo/address.mod | 2 ++ jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod | 2 ++ jetty-overlay-deployer/src/main/config/modules/overlay.mod | 2 ++ jetty-plus/src/main/plus-config/modules/plus.mod | 2 ++ jetty-plus/src/main/plus-config/modules/transactions.mod | 2 ++ jetty-proxy/src/main/config/modules/proxy.mod | 2 ++ jetty-quickstart/src/main/config/modules/quickstart.mod | 2 ++ .../src/main/config/modules/rewrite-compactpath.mod | 5 ++--- jetty-rewrite/src/main/config/modules/rewrite-customizer.mod | 5 ++--- jetty-rewrite/src/main/config/modules/rewrite.mod | 2 ++ jetty-security/src/main/config/modules/security.mod | 2 ++ jetty-server/src/main/config/modules/connectionlimit.mod | 2 ++ jetty-server/src/main/config/modules/continuation.mod | 2 ++ jetty-server/src/main/config/modules/debug.mod | 2 ++ jetty-server/src/main/config/modules/debuglog.mod | 2 ++ jetty-server/src/main/config/modules/ext.mod | 2 ++ jetty-server/src/main/config/modules/gzip.mod | 2 ++ jetty-server/src/main/config/modules/home-base-warning.mod | 2 ++ jetty-server/src/main/config/modules/http-forwarded.mod | 2 ++ jetty-server/src/main/config/modules/http.mod | 2 ++ jetty-server/src/main/config/modules/https.mod | 2 ++ jetty-server/src/main/config/modules/ipaccess.mod | 2 ++ jetty-server/src/main/config/modules/jvm.mod | 2 ++ jetty-server/src/main/config/modules/logback-access.mod | 2 ++ jetty-server/src/main/config/modules/lowresources.mod | 2 ++ jetty-server/src/main/config/modules/proxy-protocol-ssl.mod | 2 ++ jetty-server/src/main/config/modules/proxy-protocol.mod | 2 ++ jetty-server/src/main/config/modules/requestlog.mod | 2 ++ jetty-server/src/main/config/modules/resources.mod | 2 ++ jetty-server/src/main/config/modules/server.mod | 2 ++ jetty-server/src/main/config/modules/session-cache-hash.mod | 2 ++ jetty-server/src/main/config/modules/session-cache-null.mod | 2 ++ jetty-server/src/main/config/modules/session-store-cache.mod | 2 ++ jetty-server/src/main/config/modules/session-store-file.mod | 2 ++ jetty-server/src/main/config/modules/session-store-jdbc.mod | 2 ++ jetty-server/src/main/config/modules/sessions.mod | 2 ++ .../src/main/config/modules/sessions/jdbc/datasource.mod | 2 ++ .../src/main/config/modules/sessions/jdbc/driver.mod | 2 ++ jetty-server/src/main/config/modules/ssl.mod | 2 ++ jetty-server/src/main/config/modules/stats.mod | 2 ++ jetty-server/src/main/config/modules/threadpool.mod | 2 ++ jetty-servlet/src/main/config/modules/servlet.mod | 2 ++ jetty-servlets/src/main/config/modules/servlets.mod | 2 ++ jetty-spring/src/main/config/modules/spring.mod | 2 ++ jetty-start/src/test/resources/dist-home/modules/main.mod | 2 ++ .../src/main/config/modules/unixsocket-forwarded.mod | 2 ++ jetty-unixsocket/src/main/config/modules/unixsocket-http.mod | 2 ++ .../src/main/config/modules/unixsocket-http2c.mod | 2 ++ .../src/main/config/modules/unixsocket-proxy-protocol.mod | 2 ++ .../src/main/config/modules/unixsocket-secure.mod | 2 ++ jetty-unixsocket/src/main/config/modules/unixsocket.mod | 2 ++ jetty-util/src/main/config/modules/console-capture.mod | 2 ++ jetty-util/src/main/config/modules/jcl-slf4j.mod | 2 ++ jetty-util/src/main/config/modules/jul-impl.mod | 2 ++ jetty-util/src/main/config/modules/jul-slf4j.mod | 2 ++ jetty-util/src/main/config/modules/log4j-impl.mod | 2 ++ jetty-util/src/main/config/modules/log4j2-api.mod | 2 ++ jetty-util/src/main/config/modules/log4j2-impl.mod | 2 ++ jetty-util/src/main/config/modules/log4j2-slf4j.mod | 2 ++ jetty-util/src/main/config/modules/logback-impl.mod | 2 ++ jetty-util/src/main/config/modules/logging-jetty.mod | 2 ++ jetty-util/src/main/config/modules/logging-jul.mod | 2 ++ jetty-util/src/main/config/modules/logging-log4j.mod | 2 ++ jetty-util/src/main/config/modules/logging-log4j2.mod | 2 ++ jetty-util/src/main/config/modules/logging-logback.mod | 2 ++ jetty-util/src/main/config/modules/logging-slf4j.mod | 2 ++ jetty-util/src/main/config/modules/slf4j-api.mod | 2 ++ jetty-util/src/main/config/modules/slf4j-jul.mod | 2 ++ jetty-util/src/main/config/modules/slf4j-log4j.mod | 2 ++ jetty-util/src/main/config/modules/slf4j-log4j2.mod | 2 ++ jetty-util/src/main/config/modules/slf4j-logback.mod | 2 ++ jetty-util/src/main/config/modules/slf4j-simple-impl.mod | 2 ++ jetty-webapp/src/main/config/modules/webapp.mod | 2 ++ .../src/main/config/modules/websocket.mod | 2 ++ 149 files changed, 298 insertions(+), 6 deletions(-) diff --git a/apache-jsp/src/main/config/modules/apache-jsp.mod b/apache-jsp/src/main/config/modules/apache-jsp.mod index 5fa57f7c85c..62ea32b33c0 100644 --- a/apache-jsp/src/main/config/modules/apache-jsp.mod +++ b/apache-jsp/src/main/config/modules/apache-jsp.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables use of the apache implementation of JSP diff --git a/apache-jstl/src/main/config/modules/apache-jstl.mod b/apache-jstl/src/main/config/modules/apache-jstl.mod index 37e6f7757f5..55c89366ade 100644 --- a/apache-jstl/src/main/config/modules/apache-jstl.mod +++ b/apache-jstl/src/main/config/modules/apache-jstl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the apache version of JSTL diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl.mod index d726e163d24..181d668a67d 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Selects an ALPN (Application Layer Protocol Negotiation) implementation by java version. diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0.mod index 91fea30cd0e..bbcca55ad48 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_05.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_05.mod index 91fea30cd0e..bbcca55ad48 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_05.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_05.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_101.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_101.mod index eebd2a92550..d940468a7ff 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_101.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_101.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_102.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_102.mod index eebd2a92550..d940468a7ff 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_102.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_102.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_11.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_11.mod index 91fea30cd0e..bbcca55ad48 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_11.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_11.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_111.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_111.mod index eebd2a92550..d940468a7ff 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_111.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_111.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar|lib/alpn/alpn-boot-8.1.9.v20160720.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_112.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_112.mod index 3887113d09b..e244e3bed3d 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_112.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_112.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.10.v20161026/alpn-boot-8.1.10.v20161026.jar|lib/alpn/alpn-boot-8.1.10.v20161026.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_121.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_121.mod index eb50f520252..6afa18151a4 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_121.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_121.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_131.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_131.mod index eb50f520252..6afa18151a4 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_131.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_131.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_141.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_141.mod index eb50f520252..6afa18151a4 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_141.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_141.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_144.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_144.mod index eb50f520252..6afa18151a4 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_144.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_144.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_151.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_151.mod index eb50f520252..6afa18151a4 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_151.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_151.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_152.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_152.mod index eb50f520252..6afa18151a4 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_152.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_152.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_161.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_161.mod index b50a352334d..e2e91808cd3 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_161.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_161.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_162.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_162.mod index b50a352334d..e2e91808cd3 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_162.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_162.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.12.v20180117/alpn-boot-8.1.12.v20180117.jar|lib/alpn/alpn-boot-8.1.12.v20180117.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_20.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_20.mod index 91fea30cd0e..bbcca55ad48 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_20.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_20.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_25.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_25.mod index 55f736902df..f34b1841244 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_25.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_25.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_31.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_31.mod index 030029db54d..9ffca1a9699 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_31.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_31.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_40.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_40.mod index ebd06d4dda6..3d5c1aeb044 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_40.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_40.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_45.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_45.mod index ebd06d4dda6..3d5c1aeb044 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_45.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_45.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_51.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_51.mod index a0472beca95..51a8dbb518d 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_51.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_51.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.4.v20150727/alpn-boot-8.1.4.v20150727.jar|lib/alpn/alpn-boot-8.1.4.v20150727.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_60.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_60.mod index 0751b15b093..4f639da61a1 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_60.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_60.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar|lib/alpn/alpn-boot-8.1.5.v20150921.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_65.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_65.mod index 32ae03ea282..80d1541775d 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_65.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_65.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_66.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_66.mod index 32ae03ea282..80d1541775d 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_66.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_66.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod index 47bc2df34c1..bf0de731394 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod index 47bc2df34c1..bf0de731394 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_73.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_73.mod index 47bc2df34c1..bf0de731394 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_73.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_73.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_74.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_74.mod index 47bc2df34c1..bf0de731394 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_74.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_74.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod index 47bc2df34c1..bf0de731394 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_91.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_91.mod index 47bc2df34c1..bf0de731394 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_91.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_91.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_92.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_92.mod index 10d83db2181..267aa41ea37 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_92.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_92.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [files] http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar|lib/alpn/alpn-boot-8.1.8.v20160420.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-8.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-8.mod index 6ace07a2e6b..84454089e27 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-8.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-8.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides ALPN support for JDK 8, modifying the sun.security.ssl classes and adding them to the JVM boot classpath. diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod index 9a2708ba89a..cc7f4257348 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides support for ALPN based on JDK 9 APIs. diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod index cb02222ed89..a245331f71f 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the ALPN (Application Layer Protocol Negotiation) TLS extension. diff --git a/jetty-annotations/src/main/config/modules/annotations.mod b/jetty-annotations/src/main/config/modules/annotations.mod index 4217be54fb3..ca8c3bad139 100644 --- a/jetty-annotations/src/main/config/modules/annotations.mod +++ b/jetty-annotations/src/main/config/modules/annotations.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables Annotation scanning for deployed webapplications. diff --git a/jetty-cdi/cdi-2/src/main/config/modules/cdi2.mod b/jetty-cdi/cdi-2/src/main/config/modules/cdi2.mod index da019048ad7..df6ee4135cd 100644 --- a/jetty-cdi/cdi-2/src/main/config/modules/cdi2.mod +++ b/jetty-cdi/cdi-2/src/main/config/modules/cdi2.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Jetty setup to support Weld/CDI2 with WELD inside the webapp diff --git a/jetty-cdi/cdi-servlet/src/main/config/modules/cdi.mod b/jetty-cdi/cdi-servlet/src/main/config/modules/cdi.mod index c05530d631e..26262df8dd4 100644 --- a/jetty-cdi/cdi-servlet/src/main/config/modules/cdi.mod +++ b/jetty-cdi/cdi-servlet/src/main/config/modules/cdi.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Experimental CDI/Weld integration diff --git a/jetty-cdi/cdi-servlet/src/main/config/modules/cdi1.mod b/jetty-cdi/cdi-servlet/src/main/config/modules/cdi1.mod index e2b7105427f..c2deb6124f3 100644 --- a/jetty-cdi/cdi-servlet/src/main/config/modules/cdi1.mod +++ b/jetty-cdi/cdi-servlet/src/main/config/modules/cdi1.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Experimental CDI/Weld integration Deprecated in favour of cdi2 module. diff --git a/jetty-client/src/main/config/modules/client.mod b/jetty-client/src/main/config/modules/client.mod index e9d13c8c689..ccc1d50db83 100644 --- a/jetty-client/src/main/config/modules/client.mod +++ b/jetty-client/src/main/config/modules/client.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds the Jetty HTTP client to the server classpath. diff --git a/jetty-deploy/src/main/config/modules/deploy.mod b/jetty-deploy/src/main/config/modules/deploy.mod index 737e24f2e5d..6321ae50496 100644 --- a/jetty-deploy/src/main/config/modules/deploy.mod +++ b/jetty-deploy/src/main/config/modules/deploy.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables webapplication deployment from the webapps directory. diff --git a/jetty-deploy/src/main/config/modules/global-webapp-common.mod b/jetty-deploy/src/main/config/modules/global-webapp-common.mod index 2785fef3c8c..59b7386f05a 100644 --- a/jetty-deploy/src/main/config/modules/global-webapp-common.mod +++ b/jetty-deploy/src/main/config/modules/global-webapp-common.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables Deployer to apply common configuration to all webapp deployments diff --git a/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod b/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod index 6a4beaf1ab1..9cb340d4387 100644 --- a/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod +++ b/jetty-fcgi/fcgi-server/src/main/config/modules/fcgi.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds the FastCGI implementation to the classpath. diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod index c65ccd33704..9415b77ed9d 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud-datastore.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables GCloud Datastore API and implementation diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod index 454bd6e5581..64e1fb2df00 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/gcloud.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Control GCloud API classpath diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod index 1d21cff1b68..69054019de9 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables GCloudDatastore session management. diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod index daa55012162..2263ae0807b 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session data store in an embedded Hazelcast Map diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod index 55baa0e3d68..c6a26fc7123 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session data store in a remote Hazelcast Map diff --git a/jetty-home/src/main/resources/modules/conscrypt.mod b/jetty-home/src/main/resources/modules/conscrypt.mod index 0dfe600461e..85b885a89c5 100644 --- a/jetty-home/src/main/resources/modules/conscrypt.mod +++ b/jetty-home/src/main/resources/modules/conscrypt.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Installs the Conscrypt JSSE provider diff --git a/jetty-home/src/main/resources/modules/hawtio.mod b/jetty-home/src/main/resources/modules/hawtio.mod index fd0358ec0a6..a64f8327a0c 100644 --- a/jetty-home/src/main/resources/modules/hawtio.mod +++ b/jetty-home/src/main/resources/modules/hawtio.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Deploys the Hawtio console as a webapplication. diff --git a/jetty-home/src/main/resources/modules/jamon.mod b/jetty-home/src/main/resources/modules/jamon.mod index c8207f9af82..db81214f3e0 100644 --- a/jetty-home/src/main/resources/modules/jamon.mod +++ b/jetty-home/src/main/resources/modules/jamon.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Deploys the JAMon webapplication diff --git a/jetty-home/src/main/resources/modules/jminix.mod b/jetty-home/src/main/resources/modules/jminix.mod index 2e250ddeef3..7f2ff89e3a2 100644 --- a/jetty-home/src/main/resources/modules/jminix.mod +++ b/jetty-home/src/main/resources/modules/jminix.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Deploys the Jminix JMX Console within the server diff --git a/jetty-home/src/main/resources/modules/jolokia.mod b/jetty-home/src/main/resources/modules/jolokia.mod index 1edc38668a2..17ec799906c 100644 --- a/jetty-home/src/main/resources/modules/jolokia.mod +++ b/jetty-home/src/main/resources/modules/jolokia.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Deploys the Jolokia console as a web application. diff --git a/jetty-home/src/main/resources/modules/jsp.mod b/jetty-home/src/main/resources/modules/jsp.mod index 2bc7ba85225..12bbcd05b3c 100644 --- a/jetty-home/src/main/resources/modules/jsp.mod +++ b/jetty-home/src/main/resources/modules/jsp.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables JSP for all webapplications deployed on the server. diff --git a/jetty-home/src/main/resources/modules/jstl.mod b/jetty-home/src/main/resources/modules/jstl.mod index dedb2c052c1..7311f47315a 100644 --- a/jetty-home/src/main/resources/modules/jstl.mod +++ b/jetty-home/src/main/resources/modules/jstl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables JSTL for all webapplications deployed on the server diff --git a/jetty-home/src/main/resources/modules/setuid.mod b/jetty-home/src/main/resources/modules/setuid.mod index c1174ccba8d..be4f8476714 100644 --- a/jetty-home/src/main/resources/modules/setuid.mod +++ b/jetty-home/src/main/resources/modules/setuid.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the unix setUID configuration so that the server may be started as root to open privileged ports/files before diff --git a/jetty-home/src/main/resources/modules/stop.mod b/jetty-home/src/main/resources/modules/stop.mod index 6a86c04f4d7..a7b8c966c4d 100644 --- a/jetty-home/src/main/resources/modules/stop.mod +++ b/jetty-home/src/main/resources/modules/stop.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] This module causes jetty to stop immediately after starting. This is good for testing configuration and/or precompiling quickstart webapps diff --git a/jetty-http2/http2-server/src/main/config/modules/http2.mod b/jetty-http2/http2-server/src/main/config/modules/http2.mod index e5def621a6a..2ca6596e578 100644 --- a/jetty-http2/http2-server/src/main/config/modules/http2.mod +++ b/jetty-http2/http2-server/src/main/config/modules/http2.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables HTTP2 protocol support on the TLS(SSL) Connector, using the ALPN extension to select which protocol to use. diff --git a/jetty-http2/http2-server/src/main/config/modules/http2c.mod b/jetty-http2/http2-server/src/main/config/modules/http2c.mod index 228d5a8ca31..b109a8c4ce8 100644 --- a/jetty-http2/http2-server/src/main/config/modules/http2c.mod +++ b/jetty-http2/http2-server/src/main/config/modules/http2c.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the HTTP2C protocol on the HTTP Connector The connector will accept both HTTP/1 and HTTP/2 connections. diff --git a/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded-910.mod b/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded-910.mod index 96b6acb23e1..e7c8f425f8a 100644 --- a/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded-910.mod +++ b/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded-910.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session data store in a local Infinispan cache diff --git a/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded.mod b/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded.mod index 1110aaadbd3..21dc1e65c9b 100644 --- a/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded.mod +++ b/jetty-infinispan/src/main/config/modules/session-store-infinispan-embedded.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session data store in a local Infinispan cache diff --git a/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote-910.mod b/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote-910.mod index 36493531d38..93903bd41a3 100644 --- a/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote-910.mod +++ b/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote-910.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session data store in a remote Infinispan cache diff --git a/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote.mod b/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote.mod index 0ad03b4f512..844b47323cb 100644 --- a/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote.mod +++ b/jetty-infinispan/src/main/config/modules/session-store-infinispan-remote.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session data store in a remote Infinispan cache diff --git a/jetty-jaas/src/main/config/modules/jaas.mod b/jetty-jaas/src/main/config/modules/jaas.mod index 26c68fff54b..d8c78b63869 100644 --- a/jetty-jaas/src/main/config/modules/jaas.mod +++ b/jetty-jaas/src/main/config/modules/jaas.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable JAAS for deployed webapplications. diff --git a/jetty-jaspi/src/main/config/modules/jaspi.mod b/jetty-jaspi/src/main/config/modules/jaspi.mod index 0d552730346..372c00e07bd 100644 --- a/jetty-jaspi/src/main/config/modules/jaspi.mod +++ b/jetty-jaspi/src/main/config/modules/jaspi.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable JASPI authentication for deployed webapplications. diff --git a/jetty-jmx/src/main/config/modules/jmx-remote.mod b/jetty-jmx/src/main/config/modules/jmx-remote.mod index 438f3368ef9..bf6b200471c 100644 --- a/jetty-jmx/src/main/config/modules/jmx-remote.mod +++ b/jetty-jmx/src/main/config/modules/jmx-remote.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables remote RMI access to JMX diff --git a/jetty-jmx/src/main/config/modules/jmx.mod b/jetty-jmx/src/main/config/modules/jmx.mod index a59c6dd9c1b..969b5f167fb 100644 --- a/jetty-jmx/src/main/config/modules/jmx.mod +++ b/jetty-jmx/src/main/config/modules/jmx.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables JMX instrumentation for server beans and enables JMX agent. diff --git a/jetty-jndi/src/main/jndi-config/modules/jndi.mod b/jetty-jndi/src/main/jndi-config/modules/jndi.mod index 023ff9845a4..d65f31095b6 100644 --- a/jetty-jndi/src/main/jndi-config/modules/jndi.mod +++ b/jetty-jndi/src/main/jndi-config/modules/jndi.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds the Jetty JNDI implementation to the classpath. diff --git a/jetty-jndi/src/main/jndi-config/modules/mail.mod b/jetty-jndi/src/main/jndi-config/modules/mail.mod index 69e8470f9c9..99214ad5cd8 100644 --- a/jetty-jndi/src/main/jndi-config/modules/mail.mod +++ b/jetty-jndi/src/main/jndi-config/modules/mail.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds the javax.mail implementation to the classpath. diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod index e1ee0758792..e451df43f4a 100644 --- a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/base/modules/testmod.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables test setup diff --git a/jetty-maven-plugin/src/main/resources/maven.mod b/jetty-maven-plugin/src/main/resources/maven.mod index ee54ce0ebbb..0fd52cdeb80 100644 --- a/jetty-maven-plugin/src/main/resources/maven.mod +++ b/jetty-maven-plugin/src/main/resources/maven.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables an unassembled maven webapp to run in a jetty distro diff --git a/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod b/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod index e1e71817158..0618c02950a 100644 --- a/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod +++ b/jetty-memcached/jetty-memcached-sessions/src/main/config/modules/sessions/session-data-cache/xmemcached.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Memcache cache for SessionData diff --git a/jetty-nosql/src/main/config/modules/session-store-mongo.mod b/jetty-nosql/src/main/config/modules/session-store-mongo.mod index a0df7bafdcb..e3ffafdd42d 100644 --- a/jetty-nosql/src/main/config/modules/session-store-mongo.mod +++ b/jetty-nosql/src/main/config/modules/session-store-mongo.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables NoSql session management with a MongoDB driver. diff --git a/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod b/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod index 15fcfeae6d2..333877d8cb4 100644 --- a/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod +++ b/jetty-nosql/src/main/config/modules/sessions/mongo/address.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Server/port address connections for session storage diff --git a/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod b/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod index fc43772b0b3..813904e4f8f 100644 --- a/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod +++ b/jetty-nosql/src/main/config/modules/sessions/mongo/uri.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] MongoURI connections for session storage diff --git a/jetty-overlay-deployer/src/main/config/modules/overlay.mod b/jetty-overlay-deployer/src/main/config/modules/overlay.mod index 1c95193c1de..8522e997103 100644 --- a/jetty-overlay-deployer/src/main/config/modules/overlay.mod +++ b/jetty-overlay-deployer/src/main/config/modules/overlay.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable the jetty overlay deployer that allows webapplications to be dynamically composed of layers. diff --git a/jetty-plus/src/main/plus-config/modules/plus.mod b/jetty-plus/src/main/plus-config/modules/plus.mod index 7058a5969ca..1c43a34ae42 100644 --- a/jetty-plus/src/main/plus-config/modules/plus.mod +++ b/jetty-plus/src/main/plus-config/modules/plus.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables JNDI and resource injection for webapplications and other servlet 3.x features not supported in the core diff --git a/jetty-plus/src/main/plus-config/modules/transactions.mod b/jetty-plus/src/main/plus-config/modules/transactions.mod index 9b692f2f755..5433cfa5343 100644 --- a/jetty-plus/src/main/plus-config/modules/transactions.mod +++ b/jetty-plus/src/main/plus-config/modules/transactions.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Puts javax.transaction api on the classpath diff --git a/jetty-proxy/src/main/config/modules/proxy.mod b/jetty-proxy/src/main/config/modules/proxy.mod index c14ee0cba76..b1be24399cf 100644 --- a/jetty-proxy/src/main/config/modules/proxy.mod +++ b/jetty-proxy/src/main/config/modules/proxy.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable the Jetty Proxy, that allows the server to act as a non-transparent proxy for browsers. diff --git a/jetty-quickstart/src/main/config/modules/quickstart.mod b/jetty-quickstart/src/main/config/modules/quickstart.mod index cefa5f16887..102801714b6 100644 --- a/jetty-quickstart/src/main/config/modules/quickstart.mod +++ b/jetty-quickstart/src/main/config/modules/quickstart.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the Jetty Quickstart module for rapid deployment of preconfigured webapplications. diff --git a/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod b/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod index f51f05d30af..bdd63f1f4e6 100644 --- a/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod +++ b/jetty-rewrite/src/main/config/modules/rewrite-compactpath.mod @@ -1,6 +1,5 @@ -# -# Jetty Rewrite CompactPath module -# +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Add a rule to the rewrite module to compact paths so that double slashes in the path are treated as a single slash. diff --git a/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod b/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod index 2546654f000..5caea6942c8 100644 --- a/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod +++ b/jetty-rewrite/src/main/config/modules/rewrite-customizer.mod @@ -1,6 +1,5 @@ -# -# Jetty Rewrite Customizer module -# +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables a rewrite Rules container as a request customizer on the servers default HttpConfiguration instance diff --git a/jetty-rewrite/src/main/config/modules/rewrite.mod b/jetty-rewrite/src/main/config/modules/rewrite.mod index 3d61531dba2..60c229dfae9 100644 --- a/jetty-rewrite/src/main/config/modules/rewrite.mod +++ b/jetty-rewrite/src/main/config/modules/rewrite.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the jetty-rewrite handler. Specific rewrite rules must be added to either to etc/jetty-rewrite.xml or a custom xml/module diff --git a/jetty-security/src/main/config/modules/security.mod b/jetty-security/src/main/config/modules/security.mod index 3955fcfee84..ea56fdd6b6d 100644 --- a/jetty-security/src/main/config/modules/security.mod +++ b/jetty-security/src/main/config/modules/security.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds servlet standard security handling to the classpath. diff --git a/jetty-server/src/main/config/modules/connectionlimit.mod b/jetty-server/src/main/config/modules/connectionlimit.mod index b51829bfee7..997f38905a9 100644 --- a/jetty-server/src/main/config/modules/connectionlimit.mod +++ b/jetty-server/src/main/config/modules/connectionlimit.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable a server wide connection limit diff --git a/jetty-server/src/main/config/modules/continuation.mod b/jetty-server/src/main/config/modules/continuation.mod index af03ae41ced..a2aba820c14 100644 --- a/jetty-server/src/main/config/modules/continuation.mod +++ b/jetty-server/src/main/config/modules/continuation.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables support for Continuation style asynchronous Servlets. Now deprecated in favour of Servlet 3.1 diff --git a/jetty-server/src/main/config/modules/debug.mod b/jetty-server/src/main/config/modules/debug.mod index 9462422ff3c..b0cac1f827b 100644 --- a/jetty-server/src/main/config/modules/debug.mod +++ b/jetty-server/src/main/config/modules/debug.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the DebugListener to generate additional logging regarding detailed request handling events. diff --git a/jetty-server/src/main/config/modules/debuglog.mod b/jetty-server/src/main/config/modules/debuglog.mod index 28e6d8c725d..860733475ef 100644 --- a/jetty-server/src/main/config/modules/debuglog.mod +++ b/jetty-server/src/main/config/modules/debuglog.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Deprecated Debug Log using the DebugHandle. Replaced with the debug module. diff --git a/jetty-server/src/main/config/modules/ext.mod b/jetty-server/src/main/config/modules/ext.mod index 3834181a301..103336000c6 100644 --- a/jetty-server/src/main/config/modules/ext.mod +++ b/jetty-server/src/main/config/modules/ext.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds all jar files discovered in $JETTY_HOME/lib/ext and $JETTY_BASE/lib/ext to the servers classpath. diff --git a/jetty-server/src/main/config/modules/gzip.mod b/jetty-server/src/main/config/modules/gzip.mod index b210a8c0fa8..63a8b99e9ba 100644 --- a/jetty-server/src/main/config/modules/gzip.mod +++ b/jetty-server/src/main/config/modules/gzip.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable GzipHandler for dynamic gzip compression for the entire server. diff --git a/jetty-server/src/main/config/modules/home-base-warning.mod b/jetty-server/src/main/config/modules/home-base-warning.mod index 3e599f0788f..ee342355272 100644 --- a/jetty-server/src/main/config/modules/home-base-warning.mod +++ b/jetty-server/src/main/config/modules/home-base-warning.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Generates a warning that server has been run from $JETTY_HOME rather than from a $JETTY_BASE. diff --git a/jetty-server/src/main/config/modules/http-forwarded.mod b/jetty-server/src/main/config/modules/http-forwarded.mod index b84ca7ce3b1..34e25642b2c 100644 --- a/jetty-server/src/main/config/modules/http-forwarded.mod +++ b/jetty-server/src/main/config/modules/http-forwarded.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds a forwarded request customizer to the HTTP Connector to process forwarded-for style headers from a proxy. diff --git a/jetty-server/src/main/config/modules/http.mod b/jetty-server/src/main/config/modules/http.mod index c288d6ab5d9..aca43d87d9d 100644 --- a/jetty-server/src/main/config/modules/http.mod +++ b/jetty-server/src/main/config/modules/http.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables a HTTP connector on the server. By default HTTP/1 is support, but HTTP2C can diff --git a/jetty-server/src/main/config/modules/https.mod b/jetty-server/src/main/config/modules/https.mod index ad13224e2f8..8136579de2c 100644 --- a/jetty-server/src/main/config/modules/https.mod +++ b/jetty-server/src/main/config/modules/https.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds HTTPS protocol support to the TLS(SSL) Connector diff --git a/jetty-server/src/main/config/modules/ipaccess.mod b/jetty-server/src/main/config/modules/ipaccess.mod index 0a985c917d9..d4bc71bdb1f 100644 --- a/jetty-server/src/main/config/modules/ipaccess.mod +++ b/jetty-server/src/main/config/modules/ipaccess.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable the ipaccess handler to apply a white/black list control of the remote IP of requests. diff --git a/jetty-server/src/main/config/modules/jvm.mod b/jetty-server/src/main/config/modules/jvm.mod index 30b0d966b96..e8262f99028 100644 --- a/jetty-server/src/main/config/modules/jvm.mod +++ b/jetty-server/src/main/config/modules/jvm.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] A noop module that creates an ini template useful for setting JVM arguments (eg -Xmx ) diff --git a/jetty-server/src/main/config/modules/logback-access.mod b/jetty-server/src/main/config/modules/logback-access.mod index 9d5da6e144a..ee5ec462218 100644 --- a/jetty-server/src/main/config/modules/logback-access.mod +++ b/jetty-server/src/main/config/modules/logback-access.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables logback request log. diff --git a/jetty-server/src/main/config/modules/lowresources.mod b/jetty-server/src/main/config/modules/lowresources.mod index c68db526cbe..b1e91d7f7aa 100644 --- a/jetty-server/src/main/config/modules/lowresources.mod +++ b/jetty-server/src/main/config/modules/lowresources.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables a low resource monitor on the server that can take actions if threads and/or connections diff --git a/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod b/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod index a33efe84a99..7fb3d53e694 100644 --- a/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod +++ b/jetty-server/src/main/config/modules/proxy-protocol-ssl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the Proxy Protocol on the TLS(SSL) Connector. http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt diff --git a/jetty-server/src/main/config/modules/proxy-protocol.mod b/jetty-server/src/main/config/modules/proxy-protocol.mod index 48820e5c145..38bcd8f96c0 100644 --- a/jetty-server/src/main/config/modules/proxy-protocol.mod +++ b/jetty-server/src/main/config/modules/proxy-protocol.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the Proxy Protocol on the HTTP Connector. http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt diff --git a/jetty-server/src/main/config/modules/requestlog.mod b/jetty-server/src/main/config/modules/requestlog.mod index ef8630eb477..e8e971be87b 100644 --- a/jetty-server/src/main/config/modules/requestlog.mod +++ b/jetty-server/src/main/config/modules/requestlog.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables a NCSA style request log. diff --git a/jetty-server/src/main/config/modules/resources.mod b/jetty-server/src/main/config/modules/resources.mod index 00a5de93ba1..aebfebeeb70 100644 --- a/jetty-server/src/main/config/modules/resources.mod +++ b/jetty-server/src/main/config/modules/resources.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds the $JETTY_HOME/resources and/or $JETTY_BASE/resources directory to the server classpath. Useful for configuration diff --git a/jetty-server/src/main/config/modules/server.mod b/jetty-server/src/main/config/modules/server.mod index cee335be34a..441a463bea2 100644 --- a/jetty-server/src/main/config/modules/server.mod +++ b/jetty-server/src/main/config/modules/server.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the core Jetty server on the classpath. diff --git a/jetty-server/src/main/config/modules/session-cache-hash.mod b/jetty-server/src/main/config/modules/session-cache-hash.mod index 2236405fc55..32ab705c7a2 100644 --- a/jetty-server/src/main/config/modules/session-cache-hash.mod +++ b/jetty-server/src/main/config/modules/session-cache-hash.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable first level session cache in ConcurrentHashMap. If not enabled, sessions will use a HashSessionCache by default, so enabling diff --git a/jetty-server/src/main/config/modules/session-cache-null.mod b/jetty-server/src/main/config/modules/session-cache-null.mod index 1574ffdd73a..abdf2d7e076 100644 --- a/jetty-server/src/main/config/modules/session-cache-null.mod +++ b/jetty-server/src/main/config/modules/session-cache-null.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] A trivial SessionCache that does not actually cache sessions. diff --git a/jetty-server/src/main/config/modules/session-store-cache.mod b/jetty-server/src/main/config/modules/session-store-cache.mod index db717d4276b..72c012aad63 100644 --- a/jetty-server/src/main/config/modules/session-store-cache.mod +++ b/jetty-server/src/main/config/modules/session-store-cache.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables caching of SessionData in front of a SessionDataStore. diff --git a/jetty-server/src/main/config/modules/session-store-file.mod b/jetty-server/src/main/config/modules/session-store-file.mod index 93370659fc9..f704d619352 100644 --- a/jetty-server/src/main/config/modules/session-store-file.mod +++ b/jetty-server/src/main/config/modules/session-store-file.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables session persistent storage in files. diff --git a/jetty-server/src/main/config/modules/session-store-jdbc.mod b/jetty-server/src/main/config/modules/session-store-jdbc.mod index e154f17bb91..eab2799cf18 100644 --- a/jetty-server/src/main/config/modules/session-store-jdbc.mod +++ b/jetty-server/src/main/config/modules/session-store-jdbc.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables JDBC peristent/distributed session storage. diff --git a/jetty-server/src/main/config/modules/sessions.mod b/jetty-server/src/main/config/modules/sessions.mod index ee3d734df69..c1bcad083d0 100644 --- a/jetty-server/src/main/config/modules/sessions.mod +++ b/jetty-server/src/main/config/modules/sessions.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] The session management. By enabling this module, it allows session management to be configured via the ini templates diff --git a/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod b/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod index c4d003b0469..be665ff9f3b 100644 --- a/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod +++ b/jetty-server/src/main/config/modules/sessions/jdbc/datasource.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] JDBC Datasource connections for session storage diff --git a/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod b/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod index efd084a668b..eb7391a807d 100644 --- a/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod +++ b/jetty-server/src/main/config/modules/sessions/jdbc/driver.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] JDBC Driver connections for session storage diff --git a/jetty-server/src/main/config/modules/ssl.mod b/jetty-server/src/main/config/modules/ssl.mod index b9e530f3d25..0584460531c 100644 --- a/jetty-server/src/main/config/modules/ssl.mod +++ b/jetty-server/src/main/config/modules/ssl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables a TLS(SSL) Connector on the server. This may be used for HTTPS and/or HTTP2 by enabling diff --git a/jetty-server/src/main/config/modules/stats.mod b/jetty-server/src/main/config/modules/stats.mod index 4b80d520697..8f213c2d651 100644 --- a/jetty-server/src/main/config/modules/stats.mod +++ b/jetty-server/src/main/config/modules/stats.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable detailed statistics collection for the server, available via JMX. diff --git a/jetty-server/src/main/config/modules/threadpool.mod b/jetty-server/src/main/config/modules/threadpool.mod index 591ddebb94f..c0201b3c7e0 100644 --- a/jetty-server/src/main/config/modules/threadpool.mod +++ b/jetty-server/src/main/config/modules/threadpool.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the Server thread pool. diff --git a/jetty-servlet/src/main/config/modules/servlet.mod b/jetty-servlet/src/main/config/modules/servlet.mod index f21e18a87e7..d9a26916f94 100644 --- a/jetty-servlet/src/main/config/modules/servlet.mod +++ b/jetty-servlet/src/main/config/modules/servlet.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables standard Servlet handling. diff --git a/jetty-servlets/src/main/config/modules/servlets.mod b/jetty-servlets/src/main/config/modules/servlets.mod index 5e1c84fc272..07cd5fd046d 100644 --- a/jetty-servlets/src/main/config/modules/servlets.mod +++ b/jetty-servlets/src/main/config/modules/servlets.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Puts a collection of jetty utility servlets and filters on the server classpath (CGI, CrossOriginFilter, DosFilter, diff --git a/jetty-spring/src/main/config/modules/spring.mod b/jetty-spring/src/main/config/modules/spring.mod index cd52a5dd70e..0f7762de4b4 100644 --- a/jetty-spring/src/main/config/modules/spring.mod +++ b/jetty-spring/src/main/config/modules/spring.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable spring configuration processing so all jetty style xml files can optionally be written as spring beans diff --git a/jetty-start/src/test/resources/dist-home/modules/main.mod b/jetty-start/src/test/resources/dist-home/modules/main.mod index 853030567d4..730db51631c 100644 --- a/jetty-start/src/test/resources/dist-home/modules/main.mod +++ b/jetty-start/src/test/resources/dist-home/modules/main.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Example of a module diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket-forwarded.mod b/jetty-unixsocket/src/main/config/modules/unixsocket-forwarded.mod index 3af8240d7c2..4aacc4f27cc 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket-forwarded.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket-forwarded.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds a forwarded request customizer to the HTTP configuration used by the Unix Domain Socket connector, for use when behind a proxy operating diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket-http.mod b/jetty-unixsocket/src/main/config/modules/unixsocket-http.mod index d86002780f3..e8f17427237 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket-http.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket-http.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds a HTTP protocol support to the Unix Domain Socket connector. It should be used when a proxy is forwarding either HTTP or decrypted diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket-http2c.mod b/jetty-unixsocket/src/main/config/modules/unixsocket-http2c.mod index 396fdc1f609..7de5cb019fb 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket-http2c.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket-http2c.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds a HTTP2C connetion factory to the Unix Domain Socket Connector It can be used when either the proxy forwards direct diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket-proxy-protocol.mod b/jetty-unixsocket/src/main/config/modules/unixsocket-proxy-protocol.mod index a8186366ba8..c30c59bfe7f 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket-proxy-protocol.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket-proxy-protocol.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables the proxy protocol on the Unix Domain Socket Connector http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket-secure.mod b/jetty-unixsocket/src/main/config/modules/unixsocket-secure.mod index 4284943804b..a66ed83f716 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket-secure.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket-secure.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable a secure request customizer on the HTTP Configuration used by the Unix Domain Socket Connector. diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket.mod b/jetty-unixsocket/src/main/config/modules/unixsocket.mod index 2bdb57df920..84a45d21831 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enables a Unix Domain Socket Connector that can receive requests from a local proxy and/or SSL offloader (eg haproxy) in either diff --git a/jetty-util/src/main/config/modules/console-capture.mod b/jetty-util/src/main/config/modules/console-capture.mod index b4cda2351e4..e91e2baa93b 100644 --- a/jetty-util/src/main/config/modules/console-capture.mod +++ b/jetty-util/src/main/config/modules/console-capture.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Redirects JVMs console stderr and stdout to a log file, including output from Jetty's default StdErrLog logging. diff --git a/jetty-util/src/main/config/modules/jcl-slf4j.mod b/jetty-util/src/main/config/modules/jcl-slf4j.mod index ce109a259e9..cbe80839ca1 100644 --- a/jetty-util/src/main/config/modules/jcl-slf4j.mod +++ b/jetty-util/src/main/config/modules/jcl-slf4j.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a Java Commons Logging (JCL) binding to SLF4J logging. diff --git a/jetty-util/src/main/config/modules/jul-impl.mod b/jetty-util/src/main/config/modules/jul-impl.mod index b691795b6e1..7ac22f79fb2 100644 --- a/jetty-util/src/main/config/modules/jul-impl.mod +++ b/jetty-util/src/main/config/modules/jul-impl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configures the Java Util Logging mechanism diff --git a/jetty-util/src/main/config/modules/jul-slf4j.mod b/jetty-util/src/main/config/modules/jul-slf4j.mod index 64397022f18..cf8317ec64e 100644 --- a/jetty-util/src/main/config/modules/jul-slf4j.mod +++ b/jetty-util/src/main/config/modules/jul-slf4j.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a Java Util Loggin binding to SLF4J logging. diff --git a/jetty-util/src/main/config/modules/log4j-impl.mod b/jetty-util/src/main/config/modules/log4j-impl.mod index dcc8fa52613..5be5f77f385 100644 --- a/jetty-util/src/main/config/modules/log4j-impl.mod +++ b/jetty-util/src/main/config/modules/log4j-impl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a Log4j v1.2 API and implementation. To receive jetty logs enable the jetty-slf4j and slf4j-log4j modules. diff --git a/jetty-util/src/main/config/modules/log4j2-api.mod b/jetty-util/src/main/config/modules/log4j2-api.mod index da7a609b047..3c4e4e82e8f 100644 --- a/jetty-util/src/main/config/modules/log4j2-api.mod +++ b/jetty-util/src/main/config/modules/log4j2-api.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides the Log4j v2 API diff --git a/jetty-util/src/main/config/modules/log4j2-impl.mod b/jetty-util/src/main/config/modules/log4j2-impl.mod index e069ecd62b1..d95806e7c54 100644 --- a/jetty-util/src/main/config/modules/log4j2-impl.mod +++ b/jetty-util/src/main/config/modules/log4j2-impl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a Log4j v2 implementation. To receive jetty logs enable the jetty-slf4j, slf4j-log4j and log4j-log4j2 modules. diff --git a/jetty-util/src/main/config/modules/log4j2-slf4j.mod b/jetty-util/src/main/config/modules/log4j2-slf4j.mod index f8085253127..6c351779b10 100644 --- a/jetty-util/src/main/config/modules/log4j2-slf4j.mod +++ b/jetty-util/src/main/config/modules/log4j2-slf4j.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a Log4j v2 binding to SLF4J logging. diff --git a/jetty-util/src/main/config/modules/logback-impl.mod b/jetty-util/src/main/config/modules/logback-impl.mod index e001ca0a76e..cc8569ef692 100644 --- a/jetty-util/src/main/config/modules/logback-impl.mod +++ b/jetty-util/src/main/config/modules/logback-impl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides the logback core implementation and logback-access diff --git a/jetty-util/src/main/config/modules/logging-jetty.mod b/jetty-util/src/main/config/modules/logging-jetty.mod index 85a89b6d102..65f926d3a89 100644 --- a/jetty-util/src/main/config/modules/logging-jetty.mod +++ b/jetty-util/src/main/config/modules/logging-jetty.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configure jetty logging mechanism. Provides a ${jetty.base}/resources/jetty-logging.properties. diff --git a/jetty-util/src/main/config/modules/logging-jul.mod b/jetty-util/src/main/config/modules/logging-jul.mod index a2dbe05e804..bc0d414ba73 100644 --- a/jetty-util/src/main/config/modules/logging-jul.mod +++ b/jetty-util/src/main/config/modules/logging-jul.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configure jetty logging to use Java Util Logging (jul) SLF4J is used as the core logging mechanism. diff --git a/jetty-util/src/main/config/modules/logging-log4j.mod b/jetty-util/src/main/config/modules/logging-log4j.mod index a19d24aaeab..75b2f29b36d 100644 --- a/jetty-util/src/main/config/modules/logging-log4j.mod +++ b/jetty-util/src/main/config/modules/logging-log4j.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configure jetty logging to use Log4j Logging SLF4J is used as the core logging mechanism. diff --git a/jetty-util/src/main/config/modules/logging-log4j2.mod b/jetty-util/src/main/config/modules/logging-log4j2.mod index f946abef861..34bea9b9be6 100644 --- a/jetty-util/src/main/config/modules/logging-log4j2.mod +++ b/jetty-util/src/main/config/modules/logging-log4j2.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configure jetty logging to use log4j version 2 SLF4J is used as the core logging mechanism. diff --git a/jetty-util/src/main/config/modules/logging-logback.mod b/jetty-util/src/main/config/modules/logging-logback.mod index b5c72046981..f6699c0257d 100644 --- a/jetty-util/src/main/config/modules/logging-logback.mod +++ b/jetty-util/src/main/config/modules/logging-logback.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configure jetty logging to use Logback Logging. SLF4J is used as the core logging mechanism. diff --git a/jetty-util/src/main/config/modules/logging-slf4j.mod b/jetty-util/src/main/config/modules/logging-slf4j.mod index a9174b86ddc..aac12a87ef7 100644 --- a/jetty-util/src/main/config/modules/logging-slf4j.mod +++ b/jetty-util/src/main/config/modules/logging-slf4j.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Configure jetty logging to use slf4j. Any slf4j-impl implementation is used diff --git a/jetty-util/src/main/config/modules/slf4j-api.mod b/jetty-util/src/main/config/modules/slf4j-api.mod index 12054fc5e14..b490f3f20d0 100644 --- a/jetty-util/src/main/config/modules/slf4j-api.mod +++ b/jetty-util/src/main/config/modules/slf4j-api.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides SLF4J API. Requires a slf4j implementation (eg slf4j-simple-impl) otherwise a noop implementation is used. diff --git a/jetty-util/src/main/config/modules/slf4j-jul.mod b/jetty-util/src/main/config/modules/slf4j-jul.mod index 26bf8b786ae..a0e072daab2 100644 --- a/jetty-util/src/main/config/modules/slf4j-jul.mod +++ b/jetty-util/src/main/config/modules/slf4j-jul.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a SLF4J binding to Java Util Logging (JUL) logging. diff --git a/jetty-util/src/main/config/modules/slf4j-log4j.mod b/jetty-util/src/main/config/modules/slf4j-log4j.mod index 391061ee193..d61ded58678 100644 --- a/jetty-util/src/main/config/modules/slf4j-log4j.mod +++ b/jetty-util/src/main/config/modules/slf4j-log4j.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a SLF4J binding to the Log4j v1.2 API logging. diff --git a/jetty-util/src/main/config/modules/slf4j-log4j2.mod b/jetty-util/src/main/config/modules/slf4j-log4j2.mod index d1e327b40b9..4a5d104eea5 100644 --- a/jetty-util/src/main/config/modules/slf4j-log4j2.mod +++ b/jetty-util/src/main/config/modules/slf4j-log4j2.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a SLF4J binding to Log4j v2 logging. diff --git a/jetty-util/src/main/config/modules/slf4j-logback.mod b/jetty-util/src/main/config/modules/slf4j-logback.mod index 3ea375bb916..f9ebe8bfe1d 100644 --- a/jetty-util/src/main/config/modules/slf4j-logback.mod +++ b/jetty-util/src/main/config/modules/slf4j-logback.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides a SLF4J binding to Logback logging. diff --git a/jetty-util/src/main/config/modules/slf4j-simple-impl.mod b/jetty-util/src/main/config/modules/slf4j-simple-impl.mod index 168ff76e6f3..bc1b7fd92f8 100644 --- a/jetty-util/src/main/config/modules/slf4j-simple-impl.mod +++ b/jetty-util/src/main/config/modules/slf4j-simple-impl.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Provides SLF4J simple logging implementation. To receive jetty logs enable the jetty-slf4j module. diff --git a/jetty-webapp/src/main/config/modules/webapp.mod b/jetty-webapp/src/main/config/modules/webapp.mod index 59f067f8118..cbffca1919c 100644 --- a/jetty-webapp/src/main/config/modules/webapp.mod +++ b/jetty-webapp/src/main/config/modules/webapp.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Adds support for servlet specification webapplication to the server classpath. Without this, only Jetty specific handlers may be deployed. diff --git a/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod b/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod index 4166982d247..b2a0ecc516c 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod +++ b/jetty-websocket/javax-websocket-server-impl/src/main/config/modules/websocket.mod @@ -1,3 +1,5 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + [description] Enable websockets for deployed web applications From 0b44f47b4558bf031e731728f95383e53047b19f Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 16 Mar 2018 09:48:35 +1100 Subject: [PATCH 62/87] removed extra debug Signed-off-by: Greg Wilkins --- jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java index 86465065a79..c9b56d4ecdf 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java @@ -496,8 +496,6 @@ abstract public class WriteFlusher public boolean onFail(Throwable cause) { // Keep trying to handle the failure until we get to IDLE or FAILED state - if (cause!=null) - cause.addSuppressed(new Throwable()); while (true) { State current = _state.get(); From 98875c3097af87685b9ffd85a0c86de7854b7269 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Fri, 16 Mar 2018 12:23:20 +1000 Subject: [PATCH 63/87] add jdk11 profile Signed-off-by: olivier lamy --- pom.xml | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fdb66f57ae1..70b0e2a49d6 100644 --- a/pom.xml +++ b/pom.xml @@ -1006,7 +1006,7 @@ - + jdk10 @@ -1050,6 +1050,51 @@ + + + + jdk11 + + 11 + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.1-SNAPSHOT + + true + + + + + + + + oss.snapshots + OSS Snapshots + https://oss.sonatype.org/content/repositories/snapshots + + false + + + true + + + + apache.snapshots + https://repository.apache.org/content/repositories/snapshots + + false + + + true + + + + errorprone From ff00f5383a81aafc7b3707c516514ddb9e5dcc68 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Fri, 16 Mar 2018 12:26:04 +1000 Subject: [PATCH 64/87] fix bad copy/paste Signed-off-by: olivier lamy --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 70b0e2a49d6..602e31ece14 100644 --- a/pom.xml +++ b/pom.xml @@ -1050,7 +1050,6 @@ - jdk11 From e7b411b90d60fb44cd6037ad09e22f7133bdab92 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 16 Mar 2018 14:38:08 -0500 Subject: [PATCH 65/87] Fixing #361 - javadoc update/cleanup for GzipHandler Signed-off-by: Joakim Erdfelt --- .../server/handler/gzip/GzipHandler.java | 306 ++++++++++++++++-- 1 file changed, 277 insertions(+), 29 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java index bf073a6188c..417571ad94a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java @@ -49,13 +49,102 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; /** - * A Handler that can dynamically GZIP compress responses. Unlike - * previous and 3rd party GzipFilters, this mechanism works with asynchronously - * generated responses and does not need to wrap the response or it's output - * stream. Instead it uses the efficient {@link org.eclipse.jetty.server.HttpOutput.Interceptor} mechanism. + * A Handler that can dynamically GZIP uncompress requests, and compress responses. *

    - * The handler can be applied to the entire server (a gzip.mod is included in - * the distribution) or it may be applied to individual contexts. + * The GzipHandler can be applied to the entire server (a {@code gzip.mod} is included in + * the {@code jetty-home}) or it may be applied to individual contexts. + *

    + *

    + * Both Request uncompress and Response compress are gated by a configurable + * {@link DispatcherType} check on the GzipHandler. + * (This is similar in behavior to a {@link javax.servlet.Filter} configuration + * you would find in a Servlet Descriptor file ({@code WEB-INF/web.xml}) + *
    (Default: {@link DispatcherType#REQUEST}). + *

    + *

    + * Requests with a {@code Content-Encoding} header with the value {@code gzip} will + * be uncompressed by a {@link GzipHttpInputInterceptor} for any API that uses + * {@link HttpServletRequest#getInputStream()} or {@link HttpServletRequest#getReader()}. + *

    + *

    + * Response compression has a number of checks before GzipHandler will perform compression. + *

    + *
      + *
    1. + * Does the request contain a {@code Accept-Encoding} header that specifies + * {@code gzip} value? + *
    2. + *
    3. + * Is the {@link HttpServletRequest#getMethod()} allowed by the configured HTTP Method Filter. + *
      (Default: {@code GET}) + *
    4. + *
    5. + * Is the incoming Path allowed by the configured Path Specs filters? + *
      (Default: all paths are allowed) + *
    6. + *
    7. + * Is the Request User-Agent allowed by the configured User-Agent filters? + *
      (Default: MSIE 6 is excluded) + *
    8. + *
    9. + * Is the Response {@code Content-Length} header present, and does its + * value meet the minimum gzip size requirements? + *
      (Default: 16 bytes. see {@link GzipHandler#DEFAULT_MIN_GZIP_SIZE}) + *
    10. + *
    11. + * Is the Request {@code Accept} header present and does it contain the + * required {@code gzip} value? + *
    12. + *
    + *

    + * When you encounter a configurable filter in the GzipHandler (method, paths, user-agent, + * mime-types, etc) that has both Included and Excluded values, note that the Included + * values always win over the Excluded values. + *

    + *

    + * Important note about Default Values: + * It is important to note that the GzipHandler will automatically configure itself from the + * MimeType present on the Server, System, and Contexts and the ultimate set of default values + * for the various filters (paths, methods, mime-types, etc) can be influenced by the + * available mime types to work with. + *

    + *

    + * ETag (or Entity Tag) information: any Request headers for {@code If-None-Match} or + * {@code If-Match} will be evaluated by the GzipHandler to determine if it was involved + * in compression of the response earlier. This is usually present as a {@code --gzip} suffix + * on the ETag that the Client User-Agent is tracking and handed to the Jetty server. + * The special {@code --gzip} suffix on the ETag is how GzipHandler knows that the content + * passed through itself, and this suffix will be stripped from the Request header values + * before the request is sent onwards to the specific webapp / servlet endpoint for + * handling. + * If a ETag is present in the Response headers, and GzipHandler is compressing the + * contents, it will add the {@code --gzip} suffix before the Response headers are committed + * and sent to the User Agent. + *

    + *

    + * This implementation relies on an Jetty internal {@link org.eclipse.jetty.server.HttpOutput.Interceptor} + * mechanism to allow for effective and efficient compression of the response on all Output API usages: + *

    + *
      + *
    • + * {@link javax.servlet.ServletOutputStream} - Obtained from {@link HttpServletResponse#getOutputStream()} + * using the traditional Blocking I/O techniques + *
    • + *
    • + * {@link javax.servlet.WriteListener} - Provided to + * {@link javax.servlet.ServletOutputStream#setWriteListener(javax.servlet.WriteListener)} + * using the new (since Servlet 3.1) Async I/O techniques + *
    • + *
    • + * {@link java.io.PrintWriter} - Obtained from {@link HttpServletResponse#getWriter()} + * using Blocking I/O techniques + *
    • + *
    + *

    + * Historically the compression of responses were accomplished via + * Servlet Filters (eg: {@code GzipFilter}) and usage of {@link javax.servlet.http.HttpServletResponseWrapper}. + * Since the introduction of Async I/O in Servlet 3.1, this older form of Gzip support + * in web applications has been problematic and bug ridden. *

    */ public class GzipHandler extends HandlerWrapper implements GzipFactory @@ -80,11 +169,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory private HttpField _vary; /** - * Instantiates a new gzip handler. - * The excluded Mime Types are initialized to common known - * images, audio, video and other already compressed types. - * The included methods is initialized to GET. - * The excluded agent patterns are set to exclude MSIE 6.0 + * Instantiates a new GzipHandler. */ public GzipHandler() { @@ -113,7 +198,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Add excluded to the User-Agent filtering. + * * @param patterns Regular expressions matching user agents to exclude + * @see #addIncludedAgentPatterns(String...) */ public void addExcludedAgentPatterns(String... patterns) { @@ -121,7 +209,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Add excluded to the HTTP methods filtering. + * * @param methods The methods to exclude in compression + * @see #addIncludedMethods(String...) */ public void addExcludedMethods(String... methods) { @@ -129,27 +220,47 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory _methods.exclude(m); } + /** + * Get the Set of {@link DispatcherType} that this Filter will operate on. + * + * @return the set of {@link DispatcherType} this filter will operate on + */ public EnumSet getDispatcherTypes() { return _dispatchers; } + /** + * Set of supported {@link DispatcherType} that this filter will operate on. + * + * @param dispatchers the set of {@link DispatcherType} that this filter will operate on + */ public void setDispatcherTypes(EnumSet dispatchers) { _dispatchers = dispatchers; } + /** + * Set the list of supported {@link DispatcherType} that this filter will operate on. + * + * @param dispatchers the list of {@link DispatcherType} that this filter will operate on + */ public void setDispatcherTypes(DispatcherType... dispatchers) { _dispatchers = EnumSet.copyOf(Arrays.asList(dispatchers)); } /** - * Adds mime types to the excluded list. + * Adds excluded MIME types for response filtering. + * + *

    + * Deprecation Warning: + * For backward compatibility the MIME types parameters may be comma separated strings, + * but this will not be supported in future versions of Jetty. + *

    * * @param types The mime types to exclude (without charset or other parameters). - * For backward compatibility the mimetypes may be comma separated strings, but this - * will not be supported in future versions. + * @see #addIncludedMimeTypes(String...) */ public void addExcludedMimeTypes(String... types) { @@ -158,7 +269,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * Add paths to excluded paths list. + * Adds excluded Path Specs for request filtering. + * *

    * There are 2 syntaxes supported, Servlet url-pattern based, and * Regex based. This means that the initial characters on the path spec @@ -181,6 +293,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory * otherwise they are absolute.
    * For backward compatibility the pathspecs may be comma separated strings, but this * will not be supported in future versions. + * @see #addIncludedPaths(String...) */ public void addExcludedPaths(String... pathspecs) { @@ -189,7 +302,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Adds included User-Agents for filtering. + * * @param patterns Regular expressions matching user agents to include + * @see #addExcludedAgentPatterns(String...) */ public void addIncludedAgentPatterns(String... patterns) { @@ -197,7 +313,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * @param methods The methods to include in compression + * Adds included HTTP Methods (eg: POST, PATCH, DELETE) for filtering. + * + * @param methods The HTTP methods to include in compression. + * @see #addExcludedMethods(String...) */ public void addIncludedMethods(String... methods) { @@ -206,7 +325,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Is the {@link Deflater} running {@link Deflater#SYNC_FLUSH} or not. + * * @return True if {@link Deflater#SYNC_FLUSH} is used, else {@link Deflater#NO_FLUSH} + * @see #setSyncFlush(boolean) */ public boolean isSyncFlush() { @@ -214,10 +336,12 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - *

    Set the {@link Deflater} flush mode to use. {@link Deflater#SYNC_FLUSH} + * Set the {@link Deflater} flush mode to use. {@link Deflater#SYNC_FLUSH} * should be used if the application wishes to stream the data, but this may * hurt compression performance. + * * @param syncFlush True if {@link Deflater#SYNC_FLUSH} is used, else {@link Deflater#NO_FLUSH} + * @see #isSyncFlush() */ public void setSyncFlush(boolean syncFlush) { @@ -225,11 +349,12 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * Add included mime types. Inclusion takes precedence over - * exclusion. + * Add included MIME types for response filtering + * * @param types The mime types to include (without charset or other parameters) * For backward compatibility the mimetypes may be comma separated strings, but this * will not be supported in future versions. + * @see #addExcludedMimeTypes(String...) */ public void addIncludedMimeTypes(String... types) { @@ -238,7 +363,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * Adds paths specs to the included list. + * Add included Path Specs for filtering. + * *

    * There are 2 syntaxes supported, Servlet url-pattern based, and * Regex based. This means that the initial characters on the path spec @@ -323,55 +449,109 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory return df; } - + + /** + * Get the current filter list of excluded User-Agent patterns + * + * @return the filter list of excluded User-Agent patterns + * @see #getIncludedAgentPatterns() + */ public String[] getExcludedAgentPatterns() { Set excluded=_agentPatterns.getExcluded(); return excluded.toArray(new String[excluded.size()]); } + /** + * Get the current filter list of excluded HTTP methods + * + * @return the filter list of excluded HTTP methods + * @see #getIncludedMethods() + */ public String[] getExcludedMethods() { Set excluded=_methods.getExcluded(); return excluded.toArray(new String[excluded.size()]); } + /** + * Get the current filter list of excluded MIME types + * + * @return the filter list of excluded MIME types + * @see #getIncludedMimeTypes() + */ public String[] getExcludedMimeTypes() { Set excluded=_mimeTypes.getExcluded(); return excluded.toArray(new String[excluded.size()]); } + /** + * Get the current filter list of excluded Path Specs + * + * @return the filter list of excluded Path Specs + * @see #getIncludedPaths() + */ public String[] getExcludedPaths() { Set excluded=_paths.getExcluded(); return excluded.toArray(new String[excluded.size()]); } + /** + * Get the current filter list of included User-Agent patterns + * + * @return the filter list of included User-Agent patterns + * @see #getExcludedAgentPatterns() + */ public String[] getIncludedAgentPatterns() { Set includes=_agentPatterns.getIncluded(); return includes.toArray(new String[includes.size()]); } - + + /** + * Get the current filter list of included HTTP Methods + * + * @return the filter list of included HTTP methods + * @see #getExcludedMethods() + */ public String[] getIncludedMethods() { Set includes=_methods.getIncluded(); return includes.toArray(new String[includes.size()]); } + /** + * Get the current filter list of included MIME types + * + * @return the filter list of included MIME types + * @see #getExcludedMimeTypes() + */ public String[] getIncludedMimeTypes() { Set includes=_mimeTypes.getIncluded(); return includes.toArray(new String[includes.size()]); } + /** + * Get the current filter list of included Path Specs + * + * @return the filter list of included Path Specs + * @see #getExcludedPaths() + */ public String[] getIncludedPaths() { Set includes=_paths.getIncluded(); return includes.toArray(new String[includes.size()]); } + /** + * Get the current filter list of included HTTP methods + * + * @return the filter list of included HTTP methods + * @deprecated use {@link #getIncludedMethods()} instead. (Will be removed in Jetty 10) + */ @Deprecated public String[] getMethods() { @@ -379,7 +559,11 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * @return minimum response size that triggers compression + * Get the minimum size, in bytes, that a response {@code Content-Length} must be + * before compression will trigger. + * + * @return minimum response size (in bytes) that triggers compression + * @see #setMinGzipSize(int) */ public int getMinGzipSize() { @@ -392,7 +576,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * @return size in bytes of the buffer to inflate compressed request, or 0 for no inflation. + * Get the size (in bytes) of the {@link java.util.zip.Inflater} buffer used to inflate + * compressed requests. + * + * @return size in bytes of the buffer, or 0 for no inflation. */ public int getInflateBufferSize() { @@ -400,7 +587,9 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * @param size size in bytes of the buffer to inflate compressed request, or 0 for no inflation. + * Set the size (in bytes) of the {@link java.util.zip.Inflater} buffer used to inflate comrpessed requests. + * + * @param size size in bytes of the buffer, or 0 for no inflation. */ public void setInflateBufferSize(int size) { @@ -535,6 +724,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Test if the provided User-Agent is allowed based on the User-Agent filters. + * * @param ua the user agent * @return whether compressing is allowed for the given user agent */ @@ -546,6 +737,12 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory return _agentPatterns.test(ua); } + /** + * Test if the provided MIME type is allowed based on the MIME type filters. + * + * @param mimetype the MIME type to test + * @return true if allowed, false otherwise + */ @Override public boolean isMimeTypeGzipable(String mimetype) { @@ -553,6 +750,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Test if the provided Request URI is allowed based on the Path Specs filters. + * * @param requestURI the request uri * @return whether compressing is allowed for the given the path */ @@ -577,6 +776,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Set the Check if {@code *.gz} file for the incoming file exists. + * * @param checkGzExists whether to check if a static gz file exists for * the resource that the DefaultServlet may serve as precompressed. */ @@ -586,7 +787,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Set the Compression level that {@link Deflater} uses. + * * @param compressionLevel The compression level to use to initialize {@link Deflater#setLevel(int)} + * @see Deflater#setLevel(int) */ public void setCompressionLevel(int compressionLevel) { @@ -594,7 +798,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * @param patterns Regular expressions matching user agents to exclude + * Set the excluded filter list of User-Agent patterns (replacing any previously set) + * + * @param patterns Regular expressions list matching user agents to exclude + * @see #setIncludedAgentPatterns(String...) */ public void setExcludedAgentPatterns(String... patterns) { @@ -603,7 +810,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Set the excluded filter list of HTTP methods (replacing any previously set) + * * @param methods the HTTP methods to exclude + * @see #setIncludedMethods(String...) */ public void setExcludedMethods(String... methods) { @@ -612,7 +822,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Set the excluded filter list of MIME types (replacing any previously set) + * * @param types The mime types to exclude (without charset or other parameters) + * @see #setIncludedMimeTypes(String...) */ public void setExcludedMimeTypes(String... types) { @@ -621,9 +834,12 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * @param pathspecs Path specs (as per servlet spec) to exclude. If a + * Set the excluded filter list of Path specs (replacing any previously set) + * + * @param pathspecs Path specs (as per servlet spec) to exclude. If a * ServletContext is available, the paths are relative to the context path, * otherwise they are absolute. + * @see #setIncludedPaths(String...) */ public void setExcludedPaths(String... pathspecs) { @@ -632,7 +848,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Set the included filter list of User-Agent patterns (replacing any previously set) + * * @param patterns Regular expressions matching user agents to include + * @see #setExcludedAgentPatterns(String...) */ public void setIncludedAgentPatterns(String... patterns) { @@ -641,7 +860,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** + * Set the included filter list of HTTP methods (replacing any previously set) + * * @param methods The methods to include in compression + * @see #setExcludedMethods(String...) */ public void setIncludedMethods(String... methods) { @@ -650,9 +872,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * Sets included mime types. Inclusion takes precedence over exclusion. + * Set the included filter list of MIME types (replacing any previously set) * * @param types The mime types to include (without charset or other parameters) + * @see #setExcludedMimeTypes(String...) */ public void setIncludedMimeTypes(String... types) { @@ -661,11 +884,12 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } /** - * Set the path specs to include. Inclusion takes precedence over exclusion. + * Set the included filter list of Path specs (replacing any previously set) * * @param pathspecs Path specs (as per servlet spec) to include. If a * ServletContext is available, the paths are relative to the context path, * otherwise they are absolute + * @see #setExcludedPaths(String...) */ public void setIncludedPaths(String... pathspecs) { @@ -683,21 +907,45 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory _minGzipSize = minGzipSize; } + /** + * Set the included filter list of HTTP Methods (replacing any previously set) + * + * @param csvMethods the list of methods, CSV format + * @see #setExcludedMethodList(String) + */ public void setIncludedMethodList(String csvMethods) { setIncludedMethods(StringUtil.csvSplit(csvMethods)); } + /** + * Get the included filter list of HTTP methods in CSV format + * + * @return the included filter list of HTTP methods in CSV format + * @see #getExcludedMethodList() + */ public String getIncludedMethodList() { return String.join(",", getIncludedMethods()); } + /** + * Set the excluded filter list of HTTP Methods (replacing any previously set) + * + * @param csvMethods the list of methods, CSV format + * @see #setIncludedMethodList(String) + */ public void setExcludedMethodList(String csvMethods) { setExcludedMethods(StringUtil.csvSplit(csvMethods)); } + /** + * Get the excluded filter list of HTTP methods in CSV format + * + * @return the excluded filter list of HTTP methods in CSV format + * @see #getIncludedMethodList() + */ public String getExcludedMethodList() { return String.join(",", getExcludedMethods()); From 44d718417ae4ea5d768122bb447f4fd59e12b91f Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 16 Mar 2018 15:27:37 -0500 Subject: [PATCH 66/87] Fixing #2346 - missing exception stacktrace Signed-off-by: Joakim Erdfelt --- .../src/main/java/org/eclipse/jetty/server/HttpChannel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 df4dcebe050..9ab2ba49179 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 @@ -566,7 +566,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor if (LOG.isDebugEnabled()) LOG.debug(_request.getRequestURI(), failure); else - LOG.warn("{} {}",_request.getRequestURI(), failure); + LOG.warn(_request.getRequestURI(), failure); } else { From c2b2935cee48517fa142456e7769d287bd080312 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Sat, 17 Mar 2018 11:18:07 +1000 Subject: [PATCH 67/87] #2344 upgrade javadoc plugin to 3.0.0 Signed-off-by: olivier lamy --- jetty-bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index d5f3567437a..9248c4ea8fc 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 + 3.0.0 true diff --git a/pom.xml b/pom.xml index 602e31ece14..d1b0edd14a0 100644 --- a/pom.xml +++ b/pom.xml @@ -460,7 +460,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 + 3.0.0 UTF-8 UTF-8 From fc5369a1de847122bec1b8243b11cb7e8c6b2546 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 19 Mar 2018 11:13:08 +1100 Subject: [PATCH 68/87] simplified idle tests Signed-off-by: Greg Wilkins --- .../jetty/io/ByteArrayEndPointTest.java | 37 +------------------ .../jetty/io/SelectChannelEndPointTest.java | 7 ++-- 2 files changed, 4 insertions(+), 40 deletions(-) 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 98acf13a35b..e50cf959623 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 @@ -293,9 +293,9 @@ public class ByteArrayEndPointTest assertEquals("test", BufferUtil.toString(buffer)); // Wait for a read timeout. + long start = System.nanoTime(); fcb = new FutureCallback(); endp.fillInterested(fcb); - long start = System.nanoTime(); try { fcb.get(); @@ -308,40 +308,5 @@ public class ByteArrayEndPointTest assertThat(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), greaterThan(halfIdleTimeout)); assertThat("Endpoint open", endp.isOpen(), is(true)); - // We need to delay the write timeout test below from the read timeout test above. - // The reason is that the scheduler thread that fails the endPoint WriteFlusher - // because of the read timeout above runs concurrently with the write below, and - // if it runs just after the write below, the test fails because the write callback - // below fails immediately rather than after the idle timeout. - Thread.sleep(halfIdleTimeout); - - // Write more than the output capacity, then wait for idle timeout. - fcb = new FutureCallback(); - start = System.nanoTime(); - endp.write(fcb, BufferUtil.toBuffer("This is too long")); - try - { - fcb.get(); - fail(); - } - catch (ExecutionException t) - { - assertThat(t.getCause(), instanceOf(TimeoutException.class)); - } - assertThat(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), greaterThan(halfIdleTimeout)); - // Still open because it has not been oshut or closed explicitly. - assertThat("Endpoint open", endp.isOpen(), is(true)); - - // Make sure the endPoint is closed when the callback fails. - endp.fillInterested(new Closer(endp)); - Thread.sleep(halfIdleTimeout); - // Still open because it has not been oshut or closed explicitly. - assertThat("Endpoint open", endp.isOpen(), is(true)); - - // Shutdown output. - endp.shutdownOutput(); - - Thread.sleep(idleTimeout); - assertThat("Endpoint closed", endp.isOpen(), is(false)); } } 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 dcaa5f7982c..756a2d12315 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 @@ -444,6 +444,8 @@ public class SelectChannelEndPointTest server.configureBlocking(false); _manager.accept(server); + Assert.assertTrue(_lastEndPointLatch.await(10, TimeUnit.SECONDS)); + _lastEndPoint.setIdleTimeout(idleTimeout); // Write client to server long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); @@ -457,14 +459,11 @@ public class SelectChannelEndPointTest assertEquals(c, (char)b); } - Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); - _lastEndPoint.setIdleTimeout(idleTimeout); - // read until idle shutdown received int b = client.getInputStream().read(); assertEquals(-1, b); long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; - assertThat(idle, greaterThan(idleTimeout / 2L)); + assertThat(idle, greaterThan(idleTimeout - 100L)); assertThat(idle, lessThan(idleTimeout * 2L)); // But endpoint may still be open for a little bit. From daef17bdce1ea0c8b665038fd5af4ea564c76798 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 19 Mar 2018 10:09:04 +0100 Subject: [PATCH 69/87] Issue #171 - Specify HTTP authentication for a single request. Updated documentation to show how it is done. Signed-off-by: Simone Bordet --- .../clients/http/http-client-authentication.adoc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-authentication.adoc b/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-authentication.adoc index 52c7b224bf4..fa954e06721 100644 --- a/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-authentication.adoc +++ b/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-authentication.adoc @@ -75,6 +75,17 @@ URI uri = URI.create("http://domain.com/secure"); auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, "username", "password")); ---- -In this way, the original request is enriched by `HttpClient` immediately with the `Authorization` header, and the server should respond with a 200 and the resource content rather than with the 401 and the challenge. +In this way, requests for the given URI are enriched by `HttpClient` immediately with the `Authorization` header, and the server should respond with a 200 and the resource content rather than with the 401 and the challenge. + +It is also possible to preempt the authentication for a single request only, in this way: + +[source, java, subs="{sub-order}"] +---- +URI uri = URI.create("http://domain.com/secure"); +Authentication.Result authn = new BasicAuthentication.BasicResult(uri, "username", "password") +Request request = httpClient.newRequest(uri); +authn.apply(request); +request.send(); +---- See also the link:#http-client-proxy-authentication[proxy authentication section] for further information about how authentication works with HTTP proxies. From 7bc5e6e33a92fe1e07ced9239f517e10d9e5410d Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Mon, 19 Mar 2018 10:43:26 +0100 Subject: [PATCH 70/87] Small code cleanup and optimization in dump(). Signed-off-by: Simone Bordet --- .../main/java/org/eclipse/jetty/io/ManagedSelector.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index 5f9ad3ccedd..bad0ea71de0 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -245,16 +245,15 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable @Override public void dump(Appendable out, String indent) throws IOException { + List keys; + List updates; Selector selector = _selector; - List keys = null; - List updates = null; if (selector != null && selector.isOpen()) { DumpKeys dump = new DumpKeys(); - String updatesAt; + String updatesAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now()); synchronized(ManagedSelector.this) { - updatesAt = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now()); updates = new ArrayList<>(_updates); _updates.addFirst(dump); _selecting = false; From 13224e4ee8c9d23e1239331b0b4fc8b375bed720 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 19 Mar 2018 14:16:49 -0500 Subject: [PATCH 71/87] Adding TestTracker to SelectChannelEndPointTest Hoping that this will reveal the specific circumstances (test order) that lead to the frequent test failures on CI Signed-off-by: Joakim Erdfelt --- .../java/org/eclipse/jetty/io/SelectChannelEndPointTest.java | 5 +++++ 1 file changed, 5 insertions(+) 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 756a2d12315..0ace6bfdab5 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 @@ -46,6 +46,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; @@ -59,10 +60,14 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; public class SelectChannelEndPointTest { + @Rule + public TestTracker tracker = new TestTracker(); + private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class); protected CountDownLatch _lastEndPointLatch; protected volatile EndPoint _lastEndPoint; From 7c5b49fb7fcd5d113b31d88f9c311a35d76247c7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 19 Mar 2018 15:04:03 -0500 Subject: [PATCH 72/87] Issue #2226 - SelectChannelEndPoint test cleanup + Renamed SelectChannelEndPointInterestsTest to SocketChannelEndPointInterestsTest + Merged EndPointTest abstract class into SocketChannelEndPointTest as it's only used by that testcase Signed-off-by: Joakim Erdfelt --- .../org/eclipse/jetty/io/EndPointTest.java | 157 ------------------ ...> SocketChannelEndPointInterestsTest.java} | 2 +- .../jetty/io/SocketChannelEndPointTest.java | 138 +++++++++++++-- 3 files changed, 127 insertions(+), 170 deletions(-) delete mode 100644 jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java rename jetty-io/src/test/java/org/eclipse/jetty/io/{SelectChannelEndPointInterestsTest.java => SocketChannelEndPointInterestsTest.java} (99%) diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java deleted file mode 100644 index 794ab2d69a7..00000000000 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/EndPointTest.java +++ /dev/null @@ -1,157 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.util.BufferUtil; -import org.junit.Test; - -public abstract class EndPointTest -{ - public static class EndPointPair - { - public T client; - public T server; - } - - protected abstract EndPointPair newConnection() throws Exception; - - - @Test - public void testClientServerExchange() throws Exception - { - EndPointPair c = newConnection(); - ByteBuffer buffer = BufferUtil.allocate(4096); - - // Client sends a request - c.client.flush(BufferUtil.toBuffer("request")); - - // Server receives the request - int len = c.server.fill(buffer); - assertEquals(7,len); - assertEquals("request",BufferUtil.toString(buffer)); - - // Client and server are open - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); - - // Server sends response and closes output - c.server.flush(BufferUtil.toBuffer("response")); - c.server.shutdownOutput(); - - // client server are open, server is oshut - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - // Client reads response - BufferUtil.clear(buffer); - len = c.client.fill(buffer); - assertEquals(8,len); - assertEquals("response",BufferUtil.toString(buffer)); - - // Client and server are open, server is oshut - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - // Client reads -1 - BufferUtil.clear(buffer); - len = c.client.fill(buffer); - assertEquals(-1,len); - - // Client and server are open, server is oshut, client is ishut - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - // Client shutsdown output, which is a close because already ishut - c.client.shutdownOutput(); - - // Client is closed. Server is open and oshut - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - // Server reads close - BufferUtil.clear(buffer); - len = c.server.fill(buffer); - assertEquals(-1,len); - - // Client and Server are closed - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertFalse(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - } - - - - @Test - public void testClientClose() throws Exception - { - EndPointPair c = newConnection(); - ByteBuffer buffer = BufferUtil.allocate(4096); - - c.client.flush(BufferUtil.toBuffer("request")); - int len = c.server.fill(buffer); - assertEquals(7,len); - assertEquals("request",BufferUtil.toString(buffer)); - - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); - - c.client.close(); - - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); - - len = c.server.fill(buffer); - assertEquals(-1,len); - - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); - - c.server.shutdownOutput(); - - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertFalse(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - } - -} diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java similarity index 99% rename from jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java rename to jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java index 1a6ad99f879..04e17c9e4a0 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java @@ -43,7 +43,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Test; -public class SelectChannelEndPointInterestsTest +public class SocketChannelEndPointInterestsTest { private QueuedThreadPool threadPool; private Scheduler scheduler; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java index 691b7ee1e68..be6b4560ae9 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java @@ -18,14 +18,27 @@ package org.eclipse.jetty.io; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import org.eclipse.jetty.util.BufferUtil; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Test; -public class SocketChannelEndPointTest extends EndPointTest +public class SocketChannelEndPointTest { + public static class EndPointPair + { + public SocketChannelEndPoint client; + public SocketChannelEndPoint server; + } + static ServerSocketChannel connector; @BeforeClass @@ -42,25 +55,126 @@ public class SocketChannelEndPointTest extends EndPointTest newConnection() throws Exception + private EndPointPair newConnection() throws Exception { - EndPointPair c = new EndPointPair<>(); + EndPointPair c = new EndPointPair(); c.client=new SocketChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()),null,null,null); c.server=new SocketChannelEndPoint(connector.accept(),null,null,null); return c; } - @Override - public void testClientClose() throws Exception - { - super.testClientClose(); - } - - @Override + @Test public void testClientServerExchange() throws Exception { - super.testClientServerExchange(); + EndPointPair c = newConnection(); + ByteBuffer buffer = BufferUtil.allocate(4096); + + // Client sends a request + c.client.flush(BufferUtil.toBuffer("request")); + + // Server receives the request + int len = c.server.fill(buffer); + assertEquals(7,len); + assertEquals("request",BufferUtil.toString(buffer)); + + // Client and server are open + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + // Server sends response and closes output + c.server.flush(BufferUtil.toBuffer("response")); + c.server.shutdownOutput(); + + // client server are open, server is oshut + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Client reads response + BufferUtil.clear(buffer); + len = c.client.fill(buffer); + assertEquals(8,len); + assertEquals("response",BufferUtil.toString(buffer)); + + // Client and server are open, server is oshut + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Client reads -1 + BufferUtil.clear(buffer); + len = c.client.fill(buffer); + assertEquals(-1,len); + + // Client and server are open, server is oshut, client is ishut + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Client shutsdown output, which is a close because already ishut + c.client.shutdownOutput(); + + // Client is closed. Server is open and oshut + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Server reads close + BufferUtil.clear(buffer); + len = c.server.fill(buffer); + assertEquals(-1,len); + + // Client and Server are closed + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertFalse(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); } + + @Test + public void testClientClose() throws Exception + { + EndPointPair c = newConnection(); + ByteBuffer buffer = BufferUtil.allocate(4096); + + c.client.flush(BufferUtil.toBuffer("request")); + int len = c.server.fill(buffer); + assertEquals(7,len); + assertEquals("request",BufferUtil.toString(buffer)); + + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + c.client.close(); + + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + len = c.server.fill(buffer); + assertEquals(-1,len); + + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + c.server.shutdownOutput(); + + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertFalse(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + } + } From 423d160f0d065d05fcbf29499a845b4230bdceb2 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 19 Mar 2018 16:01:17 -0500 Subject: [PATCH 73/87] Issue #2226 - SelectChannelEndPoint test cleanup + Renamed old SocketChannelEndPointTest to SocketChannelEndPointOpenCloseTest + Moved SelectChannelEndPointSslTest.checkSslEngineBehavior() to new SslEngineBehaviorTest as its unrelated to the rest of the SelectChannelEndPointTest logic Signed-off-by: Joakim Erdfelt --- .../SocketChannelEndPointOpenCloseTest.java | 180 ++++++++++++++++++ .../jetty/io/SslEngineBehaviorTest.java | 145 ++++++++++++++ 2 files changed, 325 insertions(+) create mode 100644 jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java create mode 100644 jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java new file mode 100644 index 00000000000..3ba75ca4684 --- /dev/null +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java @@ -0,0 +1,180 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.nio.ByteBuffer; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +import org.eclipse.jetty.util.BufferUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SocketChannelEndPointOpenCloseTest +{ + public static class EndPointPair + { + public SocketChannelEndPoint client; + public SocketChannelEndPoint server; + } + + static ServerSocketChannel connector; + + @BeforeClass + public static void open() throws Exception + { + connector = ServerSocketChannel.open(); + connector.socket().bind(null); + } + + @AfterClass + public static void close() throws Exception + { + connector.close(); + connector=null; + } + + private EndPointPair newConnection() throws Exception + { + EndPointPair c = new EndPointPair(); + + c.client=new SocketChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()),null,null,null); + c.server=new SocketChannelEndPoint(connector.accept(),null,null,null); + return c; + } + + @Test + public void testClientServerExchange() throws Exception + { + EndPointPair c = newConnection(); + ByteBuffer buffer = BufferUtil.allocate(4096); + + // Client sends a request + c.client.flush(BufferUtil.toBuffer("request")); + + // Server receives the request + int len = c.server.fill(buffer); + assertEquals(7,len); + assertEquals("request",BufferUtil.toString(buffer)); + + // Client and server are open + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + // Server sends response and closes output + c.server.flush(BufferUtil.toBuffer("response")); + c.server.shutdownOutput(); + + // client server are open, server is oshut + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Client reads response + BufferUtil.clear(buffer); + len = c.client.fill(buffer); + assertEquals(8,len); + assertEquals("response",BufferUtil.toString(buffer)); + + // Client and server are open, server is oshut + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Client reads -1 + BufferUtil.clear(buffer); + len = c.client.fill(buffer); + assertEquals(-1,len); + + // Client and server are open, server is oshut, client is ishut + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Client shutsdown output, which is a close because already ishut + c.client.shutdownOutput(); + + // Client is closed. Server is open and oshut + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + + // Server reads close + BufferUtil.clear(buffer); + len = c.server.fill(buffer); + assertEquals(-1,len); + + // Client and Server are closed + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertFalse(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + } + + @Test + public void testClientClose() throws Exception + { + EndPointPair c = newConnection(); + ByteBuffer buffer = BufferUtil.allocate(4096); + + c.client.flush(BufferUtil.toBuffer("request")); + int len = c.server.fill(buffer); + assertEquals(7,len); + assertEquals("request",BufferUtil.toString(buffer)); + + assertTrue(c.client.isOpen()); + assertFalse(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + c.client.close(); + + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + len = c.server.fill(buffer); + assertEquals(-1,len); + + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertTrue(c.server.isOpen()); + assertFalse(c.server.isOutputShutdown()); + + c.server.shutdownOutput(); + + assertFalse(c.client.isOpen()); + assertTrue(c.client.isOutputShutdown()); + assertFalse(c.server.isOpen()); + assertTrue(c.server.isOutputShutdown()); + } + +} diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java new file mode 100644 index 00000000000..bb798be2f3b --- /dev/null +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java @@ -0,0 +1,145 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 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 static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.nio.ByteBuffer; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; + +import org.eclipse.jetty.toolchain.test.JDK; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SslEngineBehaviorTest +{ + private static SslContextFactory sslCtxFactory; + + @BeforeClass + public static void startSsl() throws Exception + { + File keystore = MavenTestingUtils.getTestResourceFile("keystore"); + sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); + sslCtxFactory.setKeyStorePassword("storepwd"); + sslCtxFactory.setKeyManagerPassword("keypwd"); + sslCtxFactory.setEndpointIdentificationAlgorithm(""); + sslCtxFactory.start(); + } + + @AfterClass + public static void stopSsl() throws Exception + { + sslCtxFactory.stop(); + } + + @Test + public void checkSslEngineBehaviour() throws Exception + { + Assume.assumeFalse(JDK.IS_9); + + SSLEngine server = sslCtxFactory.newSSLEngine(); + SSLEngine client = sslCtxFactory.newSSLEngine(); + + ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); + ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); + ByteBuffer serverIn = ByteBuffer.allocate(server.getSession().getApplicationBufferSize()); + ByteBuffer serverOut = ByteBuffer.allocate(server.getSession().getApplicationBufferSize()); + ByteBuffer clientIn = ByteBuffer.allocate(client.getSession().getApplicationBufferSize()); + + SSLEngineResult result; + + // start the client + client.setUseClientMode(true); + client.beginHandshake(); + Assert.assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,client.getHandshakeStatus()); + + // what if we try an unwrap? + netS2C.flip(); + result=client.unwrap(netS2C,clientIn); + // unwrap is a noop + assertEquals(SSLEngineResult.Status.OK,result.getStatus()); + assertEquals(0,result.bytesConsumed()); + assertEquals(0,result.bytesProduced()); + assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,result.getHandshakeStatus()); + netS2C.clear(); + + // do the needed WRAP of empty buffer + result=client.wrap(BufferUtil.EMPTY_BUFFER,netC2S); + // unwrap is a noop + assertEquals(SSLEngineResult.Status.OK,result.getStatus()); + assertEquals(0,result.bytesConsumed()); + assertThat(result.bytesProduced(),greaterThan(0)); + assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); + netC2S.flip(); + assertEquals(netC2S.remaining(),result.bytesProduced()); + + // start the server + server.setUseClientMode(false); + server.beginHandshake(); + Assert.assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,server.getHandshakeStatus()); + + // what if we try a needless wrap? + serverOut.put(BufferUtil.toBuffer("Hello World")); + serverOut.flip(); + result=server.wrap(serverOut,netS2C); + // wrap is a noop + assertEquals(SSLEngineResult.Status.OK,result.getStatus()); + assertEquals(0,result.bytesConsumed()); + assertEquals(0,result.bytesProduced()); + assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); + + // Do the needed unwrap, to an empty buffer + result=server.unwrap(netC2S,BufferUtil.EMPTY_BUFFER); + assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus()); + assertEquals(0,result.bytesConsumed()); + assertEquals(0,result.bytesProduced()); + assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); + + // Do the needed unwrap, to a full buffer + serverIn.position(serverIn.limit()); + result=server.unwrap(netC2S,serverIn); + assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus()); + assertEquals(0,result.bytesConsumed()); + assertEquals(0,result.bytesProduced()); + assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); + + // Do the needed unwrap, to an empty buffer + serverIn.clear(); + result=server.unwrap(netC2S,serverIn); + assertEquals(SSLEngineResult.Status.OK,result.getStatus()); + assertThat(result.bytesConsumed(),greaterThan(0)); + assertEquals(0,result.bytesProduced()); + assertEquals(SSLEngineResult.HandshakeStatus.NEED_TASK,result.getHandshakeStatus()); + + server.getDelegatedTask().run(); + + assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP,server.getHandshakeStatus()); + } +} From 1493e570646666290cd4c11578179d424a821fb7 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 19 Mar 2018 16:03:16 -0500 Subject: [PATCH 74/87] Issue #2226 - SelectChannelEndPoint test cleanup + New SocketChannelEndPointTest replacement class * Is Parameterized for both Normal/Ssl scenarios * Builds a new set of connections/selector manager etc for each test * TestConnection moved to inner static class to not rely on test class fields/methods * Adding SafeInteger to help track down bad test behavior. Blocking Read behavior doesn't do what we think, see Exception on CI. Signed-off-by: Joakim Erdfelt --- .../jetty/io/SocketChannelEndPointTest.java | 1031 +++++++++++++++-- 1 file changed, 922 insertions(+), 109 deletions(-) diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java index be6b4560ae9..4fef01e1e1a 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java @@ -18,163 +18,976 @@ package org.eclipse.jetty.io; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.net.SocketTimeoutException; import java.nio.ByteBuffer; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSocket; + +import org.eclipse.jetty.io.ssl.SslConnection; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; -import org.junit.AfterClass; -import org.junit.BeforeClass; +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.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.hamcrest.Matchers; +import org.junit.After; +import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@SuppressWarnings("Duplicates") +@RunWith(Parameterized.class) public class SocketChannelEndPointTest { - public static class EndPointPair + private static final Logger LOG = Log.getLogger(SocketChannelEndPoint.class); + + public interface Scenario { - public SocketChannelEndPoint client; - public SocketChannelEndPoint server; + Socket newClient(ServerSocketChannel connector) throws IOException; + + Connection newConnection(SelectableChannel channel, EndPoint endPoint, Executor executor, SafeInteger blockAt, SafeInteger writeCount); + + boolean supportsHalfCloses(); } - static ServerSocketChannel connector; - - @BeforeClass - public static void open() throws Exception + @Parameterized.Parameters(name = "{0}") + public static List data() throws Exception { - connector = ServerSocketChannel.open(); - connector.socket().bind(null); + List ret = new ArrayList<>(); + + NormalScenario normalScenario = new NormalScenario(); + ret.add(new Object[]{normalScenario}); + ret.add(new Object[]{new SslScenario(normalScenario)}); + + return ret; } - @AfterClass - public static void close() throws Exception + public Scenario _scenario; + + private ServerSocketChannel _connector; + private QueuedThreadPool _threadPool; + private Scheduler _scheduler; + private SelectorManager _manager; + private volatile EndPoint _lastEndPoint; + private CountDownLatch _lastEndPointLatch; + + // Must be volatile or the test may fail spuriously + private SafeInteger _blockAt = new SafeInteger("_blockAt", 0); + private SafeInteger _writeCount = new SafeInteger("_writeCount", 1); + + public SocketChannelEndPointTest(Scenario scenario) throws Exception { - connector.close(); - connector=null; + _scenario = scenario; + _threadPool = new QueuedThreadPool(); + _scheduler = new TimerScheduler(); + _manager = new ScenarioSelectorManager(_threadPool, _scheduler); + + _lastEndPointLatch = new CountDownLatch(1); + _connector = ServerSocketChannel.open(); + _connector.socket().bind(null); + _scheduler.start(); + _threadPool.start(); + _manager.start(); } - private EndPointPair newConnection() throws Exception + @After + public void stopManager() throws Exception { - EndPointPair c = new EndPointPair(); - - c.client=new SocketChannelEndPoint(SocketChannel.open(connector.socket().getLocalSocketAddress()),null,null,null); - c.server=new SocketChannelEndPoint(connector.accept(),null,null,null); - return c; + _scheduler.stop(); + _manager.stop(); + _threadPool.stop(); + _connector.close(); } @Test - public void testClientServerExchange() throws Exception + public void testEcho() throws Exception { - EndPointPair c = newConnection(); - ByteBuffer buffer = BufferUtil.allocate(4096); + Socket client = _scenario.newClient(_connector); - // Client sends a request - c.client.flush(BufferUtil.toBuffer("request")); + client.setSoTimeout(60000); - // Server receives the request - int len = c.server.fill(buffer); - assertEquals(7,len); - assertEquals("request",BufferUtil.toString(buffer)); + SocketChannel server = _connector.accept(); + server.configureBlocking(false); - // Client and server are open - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); + _manager.accept(server); - // Server sends response and closes output - c.server.flush(BufferUtil.toBuffer("response")); - c.server.shutdownOutput(); + // Write client to server + client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - // client server are open, server is oshut - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } - // Client reads response - BufferUtil.clear(buffer); - len = c.client.fill(buffer); - assertEquals(8,len); - assertEquals("response",BufferUtil.toString(buffer)); + // wait for read timeout + client.setSoTimeout(500); + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + try + { + client.getInputStream().read(); + Assert.fail(); + } + catch (SocketTimeoutException e) + { + long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; + Assert.assertThat("timeout duration", duration, greaterThanOrEqualTo(400L)); + } - // Client and server are open, server is oshut - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); + // write then shutdown + client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8)); - // Client reads -1 - BufferUtil.clear(buffer); - len = c.client.fill(buffer); - assertEquals(-1,len); + // Verify echo server to client + for (char c : "Goodbye Cruel TLS".toCharArray()) + { + int b = client.getInputStream().read(); + Assert.assertThat("expect valid char integer", b, greaterThan(0)); + assertEquals("expect characters to be same", c, (char) b); + } + client.close(); - // Client and server are open, server is oshut, client is ishut - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - // Client shutsdown output, which is a close because already ishut - c.client.shutdownOutput(); - - // Client is closed. Server is open and oshut - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); - - // Server reads close - BufferUtil.clear(buffer); - len = c.server.fill(buffer); - assertEquals(-1,len); - - // Client and Server are closed - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertFalse(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); + for (int i = 0; i < 10; ++i) + { + if (server.isOpen()) + Thread.sleep(10); + else + break; + } + assertFalse(server.isOpen()); } @Test - public void testClientClose() throws Exception + public void testShutdown() throws Exception { - EndPointPair c = newConnection(); - ByteBuffer buffer = BufferUtil.allocate(4096); + assumeTrue("Scenario supports half-close", _scenario.supportsHalfCloses()); - c.client.flush(BufferUtil.toBuffer("request")); - int len = c.server.fill(buffer); - assertEquals(7,len); - assertEquals("request",BufferUtil.toString(buffer)); + Socket client = _scenario.newClient(_connector); - assertTrue(c.client.isOpen()); - assertFalse(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); + client.setSoTimeout(500); - c.client.close(); + SocketChannel server = _connector.accept(); + server.configureBlocking(false); - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); + _manager.accept(server); - len = c.server.fill(buffer); - assertEquals(-1,len); + // Write client to server + client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertTrue(c.server.isOpen()); - assertFalse(c.server.isOutputShutdown()); + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } - c.server.shutdownOutput(); + // wait for read timeout + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + try + { + client.getInputStream().read(); + Assert.fail(); + } + catch (SocketTimeoutException e) + { + assertTrue(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start >= 400); + } - assertFalse(c.client.isOpen()); - assertTrue(c.client.isOutputShutdown()); - assertFalse(c.server.isOpen()); - assertTrue(c.server.isOutputShutdown()); + // write then shutdown + client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8)); + client.shutdownOutput(); + + // Verify echo server to client + for (char c : "Goodbye Cruel TLS".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + + // Read close + assertEquals(-1, client.getInputStream().read()); } + @Test + public void testReadBlocked() throws Exception + { + Socket client = _scenario.newClient(_connector); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + + OutputStream clientOutputStream = client.getOutputStream(); + InputStream clientInputStream = client.getInputStream(); + + int specifiedTimeout = 1000; + client.setSoTimeout(specifiedTimeout); + + // Write 8 and cause block waiting for 10 + _blockAt.set(10); + clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8)); + clientOutputStream.flush(); + + Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); + _lastEndPoint.setIdleTimeout(10 * specifiedTimeout); + Thread.sleep((11 * specifiedTimeout) / 10); + + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + try + { + int b = clientInputStream.read(); + Assert.fail("Should have timed out waiting for a response, but read " + b); + } + catch (SocketTimeoutException e) + { + int elapsed = Long.valueOf(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start).intValue(); + Assert.assertThat("Expected timeout", elapsed, greaterThanOrEqualTo(3 * specifiedTimeout / 4)); + } + + // write remaining characters + clientOutputStream.write("90ABCDEF".getBytes(StandardCharsets.UTF_8)); + clientOutputStream.flush(); + + // Verify echo server to client + for (char c : "1234567890ABCDEF".toCharArray()) + { + int b = clientInputStream.read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + } + + @Test + public void testIdle() throws Exception + { + int idleTimeout = 2000; + + Socket client = _scenario.newClient(_connector); + + client.setSoTimeout(idleTimeout * 10); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + Assert.assertTrue(_lastEndPointLatch.await(10, TimeUnit.SECONDS)); + _lastEndPoint.setIdleTimeout(idleTimeout); + + // Write client to server + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); + + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + + // read until idle shutdown received + int b = client.getInputStream().read(); + assertEquals(-1, b); + long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; + assertThat(idle, greaterThan(idleTimeout - 100L)); + assertThat(idle, lessThan(idleTimeout * 2L)); + + // But endpoint may still be open for a little bit. + for (int i = 0; i < 20; ++i) + { + if (_lastEndPoint.isOpen()) + Thread.sleep(2 * idleTimeout / 10); + else + break; + } + assertFalse(_lastEndPoint.isOpen()); + } + + @Test + public void testBlockedReadIdle() throws Exception + { + Socket client = _scenario.newClient(_connector); + InputStream clientInputStream = client.getInputStream(); + OutputStream clientOutputStream = client.getOutputStream(); + + client.setSoTimeout(5000); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + + // Write client to server + clientOutputStream.write("HelloWorld".getBytes(StandardCharsets.UTF_8)); + + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = clientInputStream.read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + + Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); + int idleTimeout = 500; + _lastEndPoint.setIdleTimeout(idleTimeout); + + // Write 8 and cause block waiting for 10 + _blockAt.set(10); + clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8)); + clientOutputStream.flush(); + + // read until idle shutdown received + long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + int b = clientInputStream.read(); + assertEquals('E', b); + long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; + assertTrue(idle > idleTimeout / 2); + assertTrue(idle < idleTimeout * 2); + + for (char c : "E: 12345678".toCharArray()) + { + b = clientInputStream.read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + b = clientInputStream.read(); + assertEquals(-1, b); + + // But endpoint is still open. + if (_lastEndPoint.isOpen()) + // Wait for another idle callback + Thread.sleep(idleTimeout * 2); + + // endpoint is closed. + assertFalse(_lastEndPoint.isOpen()); + } + + @Test + public void testStress() throws Exception + { + Socket client = _scenario.newClient(_connector); + client.setSoTimeout(30000); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + final int writes = 200000; + + final byte[] bytes = "HelloWorld-".getBytes(StandardCharsets.UTF_8); + byte[] count = "0\n".getBytes(StandardCharsets.UTF_8); + BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream()); + final CountDownLatch latch = new CountDownLatch(writes); + final InputStream in = new BufferedInputStream(client.getInputStream()); + final long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + out.write(bytes); + out.write(count); + out.flush(); + + Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); + _lastEndPoint.setIdleTimeout(5000); + + new Thread() + { + @Override + public void run() + { + Thread.currentThread().setPriority(MAX_PRIORITY); + long last = -1; + int count = -1; + try + { + while (latch.getCount() > 0) + { + // Verify echo server to client + for (byte b0 : bytes) + { + int b = in.read(); + Assert.assertThat(b, greaterThan(0)); + assertEquals(0xff & b0, b); + } + + count = 0; + int b = in.read(); + while (b > 0 && b != '\n') + { + count = count * 10 + (b - '0'); + b = in.read(); + } + last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + + //if (latch.getCount()%1000==0) + // System.out.println(writes-latch.getCount()); + + latch.countDown(); + } + } + catch (Throwable e) + { + + long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + System.err.println("count=" + count); + System.err.println("latch=" + latch.getCount()); + System.err.println("time=" + (now - start)); + System.err.println("last=" + (now - last)); + System.err.println("endp=" + _lastEndPoint); + System.err.println("conn=" + _lastEndPoint.getConnection()); + + e.printStackTrace(); + } + } + }.start(); + + // Write client to server + for (int i = 1; i < writes; i++) + { + out.write(bytes); + out.write(Integer.toString(i).getBytes(StandardCharsets.ISO_8859_1)); + out.write('\n'); + if (i % 1000 == 0) + { + //System.err.println(i+"/"+writes); + out.flush(); + } + Thread.yield(); + } + out.flush(); + + long last = latch.getCount(); + while (!latch.await(5, TimeUnit.SECONDS)) + { + //System.err.println(latch.getCount()); + if (latch.getCount() == last) + Assert.fail(); + last = latch.getCount(); + } + + assertEquals(0, latch.getCount()); + } + + @Test + public void testWriteBlocked() throws Exception + { + Socket client = _scenario.newClient(_connector); + + client.setSoTimeout(10000); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + + // Write client to server + _writeCount.set(10000); + String data = "Now is the time for all good men to come to the aid of the party"; + client.getOutputStream().write(data.getBytes(StandardCharsets.UTF_8)); + BufferedInputStream in = new BufferedInputStream(client.getInputStream()); + + int byteNum = 0; + try + { + for (int i = 0; i < _writeCount.get(); i++) + { + if (i % 1000 == 0) + TimeUnit.MILLISECONDS.sleep(200); + + // Verify echo server to client + for (int j = 0; j < data.length(); j++) + { + char c = data.charAt(j); + int b = in.read(); + byteNum++; + assertTrue(b > 0); + assertEquals("test-" + i + "/" + j, c, (char) b); + } + + if (i == 0) + _lastEndPoint.setIdleTimeout(60000); + } + } + catch (SocketTimeoutException e) + { + System.err.println("SelectorManager.dump() = " + _manager.dump()); + LOG.warn("Server: " + server); + LOG.warn("Error reading byte #" + byteNum, e); + throw e; + } + + client.close(); + + for (int i = 0; i < 10; ++i) + { + if (server.isOpen()) + Thread.sleep(10); + else + break; + } + assertFalse(server.isOpen()); + } + + + // TODO make this test reliable + @Test + @Ignore + public void testRejectedExecution() throws Exception + { + _manager.stop(); + _threadPool.stop(); + + final CountDownLatch latch = new CountDownLatch(1); + + BlockingQueue q = new ArrayBlockingQueue<>(4); + _threadPool = new QueuedThreadPool(4, 4, 60000, q); + _manager = new SelectorManager(_threadPool, _scheduler, 1) + { + + @Override + protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException + { + SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, selectionKey, getScheduler()); + _lastEndPoint = endp; + _lastEndPointLatch.countDown(); + return endp; + } + + @Override + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException + { + return new TestConnection(endpoint, latch, getExecutor(), _blockAt, _writeCount); + } + }; + + _threadPool.start(); + _manager.start(); + + AtomicInteger timeout = new AtomicInteger(); + AtomicInteger rejections = new AtomicInteger(); + AtomicInteger echoed = new AtomicInteger(); + + CountDownLatch closed = new CountDownLatch(20); + for (int i = 0; i < 20; i++) + { + new Thread() + { + @Override + public void run() + { + try (Socket client = _scenario.newClient(_connector);) + { + client.setSoTimeout(5000); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + + // Write client to server + client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); + client.getOutputStream().flush(); + client.shutdownOutput(); + + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + assertEquals(-1, client.getInputStream().read()); + echoed.incrementAndGet(); + } + catch (SocketTimeoutException x) + { + x.printStackTrace(); + timeout.incrementAndGet(); + } + catch (Throwable x) + { + rejections.incrementAndGet(); + } + finally + { + closed.countDown(); + } + } + }.start(); + } + + // unblock the handling + latch.countDown(); + + // wait for all clients to complete or fail + closed.await(); + + // assert some clients must have been rejected + Assert.assertThat(rejections.get(), Matchers.greaterThan(0)); + // but not all of them + Assert.assertThat(rejections.get(), Matchers.lessThan(20)); + // none should have timed out + Assert.assertThat(timeout.get(), Matchers.equalTo(0)); + // and the rest should have worked + Assert.assertThat(echoed.get(), Matchers.equalTo(20 - rejections.get())); + + // and the selector is still working for new requests + try (Socket client = _scenario.newClient(_connector)) + { + client.setSoTimeout(5000); + + SocketChannel server = _connector.accept(); + server.configureBlocking(false); + + _manager.accept(server); + + // Write client to server + client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); + client.getOutputStream().flush(); + client.shutdownOutput(); + + // Verify echo server to client + for (char c : "HelloWorld".toCharArray()) + { + int b = client.getInputStream().read(); + assertTrue(b > 0); + assertEquals(c, (char) b); + } + assertEquals(-1, client.getInputStream().read()); + } + } + + public class ScenarioSelectorManager extends SelectorManager + { + protected ScenarioSelectorManager(Executor executor, Scheduler scheduler) + { + super(executor, scheduler); + } + + protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException + { + SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, key, getScheduler()); + endp.setIdleTimeout(60000); + _lastEndPoint = endp; + _lastEndPointLatch.countDown(); + return endp; + } + + @Override + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException + { + return _scenario.newConnection(channel, endpoint, getExecutor(), _blockAt, _writeCount); + } + } + + public static class NormalScenario implements Scenario + { + @Override + public Socket newClient(ServerSocketChannel connector) throws IOException + { + return new Socket(connector.socket().getInetAddress(), connector.socket().getLocalPort()); + } + + @Override + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + { + return new TestConnection(endpoint, executor, blockAt, writeCount); + } + + @Override + public boolean supportsHalfCloses() + { + return true; + } + + @Override + public String toString() + { + return "normal"; + } + } + + public static class SslScenario implements Scenario + { + private final NormalScenario _normalScenario; + private final SslContextFactory __sslCtxFactory = new SslContextFactory(); + private final ByteBufferPool __byteBufferPool = new MappedByteBufferPool(); + + public SslScenario(NormalScenario normalScenario) throws Exception + { + _normalScenario = normalScenario; + File keystore = MavenTestingUtils.getTestResourceFile("keystore"); + __sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); + __sslCtxFactory.setKeyStorePassword("storepwd"); + __sslCtxFactory.setKeyManagerPassword("keypwd"); + __sslCtxFactory.setEndpointIdentificationAlgorithm(""); + __sslCtxFactory.start(); + } + + @Override + public Socket newClient(ServerSocketChannel connector) throws IOException + { + SSLSocket socket = __sslCtxFactory.newSslSocket(); + socket.connect(connector.socket().getLocalSocketAddress()); + return socket; + } + + @Override + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + { + SSLEngine engine = __sslCtxFactory.newSSLEngine(); + engine.setUseClientMode(false); + SslConnection sslConnection = new SslConnection(__byteBufferPool, executor, endpoint, engine); + sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed()); + sslConnection.setRenegotiationLimit(__sslCtxFactory.getRenegotiationLimit()); + Connection appConnection = _normalScenario.newConnection(channel, sslConnection.getDecryptedEndPoint(), executor, blockAt, writeCount); + sslConnection.getDecryptedEndPoint().setConnection(appConnection); + return sslConnection; + } + + @Override + public boolean supportsHalfCloses() + { + return false; + } + + @Override + public String toString() + { + return "ssl"; + } + } + + /** + * Testing possibility of a bad test configuration + */ + public static class SafeInteger + { + private final String name; + private int value; + private boolean getCalled = false; + private Throwable firstGetThrowable; + + public SafeInteger(String name, int value) + { + this.name = name; + this.value = value; + } + + public void set(int value) + { + synchronized(this) + { + if(getCalled) + throw new IllegalStateException(name + ".get() already called, unable to " + name + ".set(" + value + ") now: TOOLATE", firstGetThrowable); + this.value = value; + } + } + + public int get() + { + synchronized (this) + { + if(!getCalled) + { + // first occurrence. + firstGetThrowable = new Throwable("First Get Here"); + } + getCalled = true; + return this.value; + } + } + } + + @SuppressWarnings("Duplicates") + public static class TestConnection extends AbstractConnection + { + private static final Logger LOG = Log.getLogger(TestConnection.class); + + volatile FutureCallback _blockingRead; + final SafeInteger _blockAt; + final SafeInteger _writeCount; + // volatile int _blockAt = 0; + ByteBuffer _in = BufferUtil.allocate(32 * 1024); + ByteBuffer _out = BufferUtil.allocate(32 * 1024); + long _last = -1; + final CountDownLatch _latch; + + public TestConnection(EndPoint endp, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + { + super(endp, executor); + _latch = null; + this._blockAt = blockAt; + this._writeCount = writeCount; + } + + public TestConnection(EndPoint endp, CountDownLatch latch, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + { + super(endp, executor); + _latch = latch; + this._blockAt = blockAt; + this._writeCount = writeCount; + } + + @Override + public void onOpen() + { + super.onOpen(); + fillInterested(); + } + + @Override + public void onFillInterestedFailed(Throwable cause) + { + Callback blocking = _blockingRead; + if (blocking != null) + { + _blockingRead = null; + blocking.failed(cause); + return; + } + super.onFillInterestedFailed(cause); + } + + @Override + public void onFillable() + { + if (_latch != null) + { + try + { + _latch.await(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + Callback blocking = _blockingRead; + if (blocking != null) + { + _blockingRead = null; + blocking.succeeded(); + return; + } + + EndPoint _endp = getEndPoint(); + try + { + _last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); + boolean progress = true; + while (progress) + { + progress = false; + + // Fill the input buffer with everything available + BufferUtil.compact(_in); + if (BufferUtil.isFull(_in)) + throw new IllegalStateException("FULL " + BufferUtil.toDetailString(_in)); + int filled = _endp.fill(_in); + if (filled > 0) + progress = true; + + // If the tests wants to block, then block + while (_blockAt.get() > 0 && _endp.isOpen() && _in.remaining() < _blockAt.get()) + { + FutureCallback future = _blockingRead = new FutureCallback(); + fillInterested(); + future.get(); + filled = _endp.fill(_in); + progress |= filled > 0; + } + + // Copy to the out buffer + if (BufferUtil.hasContent(_in) && BufferUtil.append(_out, _in) > 0) + progress = true; + + // Blocking writes + if (BufferUtil.hasContent(_out)) + { + ByteBuffer out = _out.duplicate(); + BufferUtil.clear(_out); + for (int i = 0; i < _writeCount.get(); i++) + { + FutureCallback blockingWrite = new FutureCallback(); + _endp.write(blockingWrite, out.asReadOnlyBuffer()); + blockingWrite.get(); + } + progress = true; + } + + // are we done? + if (_endp.isInputShutdown()) + _endp.shutdownOutput(); + } + + if (_endp.isOpen()) + fillInterested(); + } + catch (ExecutionException e) + { + // Timeout does not close, so echo exception then shutdown + try + { + FutureCallback blockingWrite = new FutureCallback(); + _endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in))); + blockingWrite.get(); + _endp.shutdownOutput(); + } + catch (Exception e2) + { + // e2.printStackTrace(); + } + } + catch (InterruptedException | EofException e) + { + LOG.info(e); + } + catch (Exception e) + { + LOG.warn(e); + } + } + } } From a437466996ca99f8c9dbbd3539b5b2fa4956c375 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 19 Mar 2018 16:45:01 -0500 Subject: [PATCH 75/87] Issue #2226 - SelectChannelEndPoint test cleanup Fixing NPE in testcase Signed-off-by: Joakim Erdfelt --- .../test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java index bb798be2f3b..2113f0feabe 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java @@ -45,6 +45,7 @@ public class SslEngineBehaviorTest @BeforeClass public static void startSsl() throws Exception { + sslCtxFactory = new SslContextFactory(); File keystore = MavenTestingUtils.getTestResourceFile("keystore"); sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); sslCtxFactory.setKeyStorePassword("storepwd"); From a107bdd2bba16ea8f21e5a2867c4b60992fe1b70 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 19 Mar 2018 17:26:44 -0500 Subject: [PATCH 76/87] Issue #2226 - SelectChannelEndPoint test cleanup Applying recommended changes from review. Signed-off-by: Joakim Erdfelt --- .../io/SelectChannelEndPointSslTest.java | 210 ----- .../jetty/io/SelectChannelEndPointTest.java | 837 ------------------ .../jetty/io/SocketChannelEndPointTest.java | 174 +--- 3 files changed, 15 insertions(+), 1206 deletions(-) delete mode 100644 jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java delete mode 100644 jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java deleted file mode 100644 index da7139002aa..00000000000 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java +++ /dev/null @@ -1,210 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.io.File; -import java.io.IOException; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SocketChannel; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLEngineResult; -import javax.net.ssl.SSLEngineResult.HandshakeStatus; -import javax.net.ssl.SSLSocket; - -import org.eclipse.jetty.io.ssl.SslConnection; -import org.eclipse.jetty.toolchain.test.JDK; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.annotation.Stress; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.junit.Assert; -import org.junit.Assume; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import static org.hamcrest.Matchers.greaterThan; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - - -public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest -{ - private static SslContextFactory __sslCtxFactory=new SslContextFactory(); - private static ByteBufferPool __byteBufferPool = new MappedByteBufferPool(); - - @BeforeClass - public static void initSslEngine() throws Exception - { - File keystore = MavenTestingUtils.getTestResourceFile("keystore"); - __sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); - __sslCtxFactory.setKeyStorePassword("storepwd"); - __sslCtxFactory.setKeyManagerPassword("keypwd"); - __sslCtxFactory.setEndpointIdentificationAlgorithm(""); - __sslCtxFactory.start(); - } - - @Override - protected Socket newClient() throws IOException - { - SSLSocket socket = __sslCtxFactory.newSslSocket(); - socket.connect(_connector.socket().getLocalSocketAddress()); - return socket; - } - - @Override - protected Connection newConnection(SelectableChannel channel, EndPoint endpoint) - { - SSLEngine engine = __sslCtxFactory.newSSLEngine(); - engine.setUseClientMode(false); - SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine); - sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed()); - sslConnection.setRenegotiationLimit(__sslCtxFactory.getRenegotiationLimit()); - Connection appConnection = super.newConnection(channel,sslConnection.getDecryptedEndPoint()); - sslConnection.getDecryptedEndPoint().setConnection(appConnection); - return sslConnection; - } - - @Test - @Override - public void testEcho() throws Exception - { - super.testEcho(); - } - - @Ignore // SSL does not do half closes - @Override - public void testShutdown() throws Exception - { - } - - @Test - @Override - public void testWriteBlocked() throws Exception - { - super.testWriteBlocked(); - } - - @Override - public void testReadBlocked() throws Exception - { - super.testReadBlocked(); - } - - @Override - public void testIdle() throws Exception - { - super.testIdle(); - } - - @Test - @Override - @Stress("Requires a relatively idle (network wise) environment") - public void testStress() throws Exception - { - super.testStress(); - } - - @Test - public void checkSslEngineBehaviour() throws Exception - { - Assume.assumeFalse(JDK.IS_9); - - SSLEngine server = __sslCtxFactory.newSSLEngine(); - SSLEngine client = __sslCtxFactory.newSSLEngine(); - - ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); - ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); - ByteBuffer serverIn = ByteBuffer.allocate(server.getSession().getApplicationBufferSize()); - ByteBuffer serverOut = ByteBuffer.allocate(server.getSession().getApplicationBufferSize()); - ByteBuffer clientIn = ByteBuffer.allocate(client.getSession().getApplicationBufferSize()); - - SSLEngineResult result; - - // start the client - client.setUseClientMode(true); - client.beginHandshake(); - Assert.assertEquals(HandshakeStatus.NEED_WRAP,client.getHandshakeStatus()); - - // what if we try an unwrap? - netS2C.flip(); - result=client.unwrap(netS2C,clientIn); - // unwrap is a noop - assertEquals(SSLEngineResult.Status.OK,result.getStatus()); - assertEquals(0,result.bytesConsumed()); - assertEquals(0,result.bytesProduced()); - assertEquals(HandshakeStatus.NEED_WRAP,result.getHandshakeStatus()); - netS2C.clear(); - - // do the needed WRAP of empty buffer - result=client.wrap(BufferUtil.EMPTY_BUFFER,netC2S); - // unwrap is a noop - assertEquals(SSLEngineResult.Status.OK,result.getStatus()); - assertEquals(0,result.bytesConsumed()); - assertThat(result.bytesProduced(),greaterThan(0)); - assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); - netC2S.flip(); - assertEquals(netC2S.remaining(),result.bytesProduced()); - - // start the server - server.setUseClientMode(false); - server.beginHandshake(); - Assert.assertEquals(HandshakeStatus.NEED_UNWRAP,server.getHandshakeStatus()); - - // what if we try a needless wrap? - serverOut.put(BufferUtil.toBuffer("Hello World")); - serverOut.flip(); - result=server.wrap(serverOut,netS2C); - // wrap is a noop - assertEquals(SSLEngineResult.Status.OK,result.getStatus()); - assertEquals(0,result.bytesConsumed()); - assertEquals(0,result.bytesProduced()); - assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); - - // Do the needed unwrap, to an empty buffer - result=server.unwrap(netC2S,BufferUtil.EMPTY_BUFFER); - assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus()); - assertEquals(0,result.bytesConsumed()); - assertEquals(0,result.bytesProduced()); - assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); - - // Do the needed unwrap, to a full buffer - serverIn.position(serverIn.limit()); - result=server.unwrap(netC2S,serverIn); - assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW,result.getStatus()); - assertEquals(0,result.bytesConsumed()); - assertEquals(0,result.bytesProduced()); - assertEquals(HandshakeStatus.NEED_UNWRAP,result.getHandshakeStatus()); - - // Do the needed unwrap, to an empty buffer - serverIn.clear(); - result=server.unwrap(netC2S,serverIn); - assertEquals(SSLEngineResult.Status.OK,result.getStatus()); - assertThat(result.bytesConsumed(),greaterThan(0)); - assertEquals(0,result.bytesProduced()); - assertEquals(HandshakeStatus.NEED_TASK,result.getHandshakeStatus()); - - server.getDelegatedTask().run(); - - assertEquals(HandshakeStatus.NEED_WRAP,server.getHandshakeStatus()); - } -} 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 deleted file mode 100644 index 0ace6bfdab5..00000000000 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointTest.java +++ /dev/null @@ -1,837 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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 static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.lessThan; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.nio.ByteBuffer; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.util.BufferUtil; -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.QueuedThreadPool; -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; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; - -public class SelectChannelEndPointTest -{ - @Rule - public TestTracker tracker = new TestTracker(); - - private static final Logger LOG = Log.getLogger(SelectChannelEndPointTest.class); - protected CountDownLatch _lastEndPointLatch; - protected volatile EndPoint _lastEndPoint; - protected ServerSocketChannel _connector; - protected QueuedThreadPool _threadPool = new QueuedThreadPool(); - protected Scheduler _scheduler = new TimerScheduler(); - protected SelectorManager _manager = new SelectorManager(_threadPool, _scheduler) - { - @Override - public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) - { - return SelectChannelEndPointTest.this.newConnection(channel, endpoint); - } - - @Override - protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException - { - SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, key, getScheduler()); - endp.setIdleTimeout(60000); - _lastEndPoint = endp; - _lastEndPointLatch.countDown(); - return endp; - } - - }; - - // Must be volatile or the test may fail spuriously - protected volatile int _blockAt = 0; - private volatile int _writeCount = 1; - - @Before - public void startManager() throws Exception - { - System.gc(); - _writeCount = 1; - _lastEndPoint = null; - _lastEndPointLatch = new CountDownLatch(1); - _connector = ServerSocketChannel.open(); - _connector.socket().bind(null); - _scheduler.start(); - _threadPool.start(); - _manager.start(); - } - - @After - public void stopManager() throws Exception - { - _scheduler.stop(); - _manager.stop(); - _threadPool.stop(); - _connector.close(); - } - - protected Socket newClient() throws IOException - { - return new Socket(_connector.socket().getInetAddress(), _connector.socket().getLocalPort()); - } - - protected Connection newConnection(SelectableChannel channel, EndPoint endpoint) - { - return new TestConnection(endpoint); - } - - public class TestConnection extends AbstractConnection - { - volatile FutureCallback _blockingRead; - ByteBuffer _in = BufferUtil.allocate(32 * 1024); - ByteBuffer _out = BufferUtil.allocate(32 * 1024); - long _last = -1; - final CountDownLatch _latch; - - public TestConnection(EndPoint endp) - { - super(endp, _threadPool); - _latch=null; - } - - public TestConnection(EndPoint endp,CountDownLatch latch) - { - super(endp, _threadPool); - _latch=latch; - } - - @Override - public void onOpen() - { - super.onOpen(); - fillInterested(); - } - - @Override - public void onFillInterestedFailed(Throwable cause) - { - Callback blocking = _blockingRead; - if (blocking!=null) - { - _blockingRead=null; - blocking.failed(cause); - return; - } - super.onFillInterestedFailed(cause); - } - - @Override - public void onFillable() - { - if (_latch!=null) - { - try - { - _latch.await(); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - - Callback blocking = _blockingRead; - if (blocking!=null) - { - _blockingRead=null; - blocking.succeeded(); - return; - } - - EndPoint _endp = getEndPoint(); - try - { - _last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - boolean progress = true; - while (progress) - { - progress = false; - - // Fill the input buffer with everything available - BufferUtil.compact(_in); - if (BufferUtil.isFull(_in)) - throw new IllegalStateException("FULL " + BufferUtil.toDetailString(_in)); - int filled = _endp.fill(_in); - if (filled > 0) - progress = true; - - // If the tests wants to block, then block - while (_blockAt > 0 && _endp.isOpen() && _in.remaining() < _blockAt) - { - FutureCallback future = _blockingRead = new FutureCallback(); - fillInterested(); - future.get(); - filled = _endp.fill(_in); - progress |= filled > 0; - } - - // Copy to the out buffer - if (BufferUtil.hasContent(_in) && BufferUtil.append(_out, _in) > 0) - progress = true; - - // Blocking writes - if (BufferUtil.hasContent(_out)) - { - ByteBuffer out = _out.duplicate(); - BufferUtil.clear(_out); - for (int i = 0; i < _writeCount; i++) - { - FutureCallback blockingWrite = new FutureCallback(); - _endp.write(blockingWrite, out.asReadOnlyBuffer()); - blockingWrite.get(); - } - progress = true; - } - - // are we done? - if (_endp.isInputShutdown()) - _endp.shutdownOutput(); - } - - if (_endp.isOpen()) - fillInterested(); - } - catch (ExecutionException e) - { - // Timeout does not close, so echo exception then shutdown - try - { - FutureCallback blockingWrite = new FutureCallback(); - _endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in))); - blockingWrite.get(); - _endp.shutdownOutput(); - } - catch (Exception e2) - { - // e2.printStackTrace(); - } - } - catch (InterruptedException | EofException e) - { - Log.getRootLogger().ignore(e); - } - catch (Exception e) - { - Log.getRootLogger().warn(e); - } - finally - { - } - } - } - - @Test - public void testEcho() throws Exception - { - Socket client = newClient(); - - client.setSoTimeout(60000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - - // wait for read timeout - client.setSoTimeout(500); - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - try - { - client.getInputStream().read(); - Assert.fail(); - } - catch (SocketTimeoutException e) - { - long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; - Assert.assertThat("timeout duration", duration, greaterThanOrEqualTo(400L)); - } - - // write then shutdown - client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "Goodbye Cruel TLS".toCharArray()) - { - int b = client.getInputStream().read(); - Assert.assertThat("expect valid char integer", b, greaterThan(0)); - assertEquals("expect characters to be same", c, (char)b); - } - client.close(); - - for (int i = 0; i < 10; ++i) - { - if (server.isOpen()) - Thread.sleep(10); - else - break; - } - assertFalse(server.isOpen()); - } - - @Test - public void testShutdown() throws Exception - { - Socket client = newClient(); - - client.setSoTimeout(500); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - - // wait for read timeout - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - try - { - client.getInputStream().read(); - Assert.fail(); - } - catch (SocketTimeoutException e) - { - assertTrue(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start >= 400); - } - - // write then shutdown - client.getOutputStream().write("Goodbye Cruel TLS".getBytes(StandardCharsets.UTF_8)); - client.shutdownOutput(); - - // Verify echo server to client - for (char c : "Goodbye Cruel TLS".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - - // Read close - assertEquals(-1, client.getInputStream().read()); - } - - @Test - public void testReadBlocked() throws Exception - { - Socket client = newClient(); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - OutputStream clientOutputStream = client.getOutputStream(); - InputStream clientInputStream = client.getInputStream(); - - int specifiedTimeout = 1000; - client.setSoTimeout(specifiedTimeout); - - // Write 8 and cause block waiting for 10 - _blockAt = 10; - clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8)); - clientOutputStream.flush(); - - Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); - _lastEndPoint.setIdleTimeout(10 * specifiedTimeout); - Thread.sleep((11 * specifiedTimeout) / 10); - - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - try - { - int b = clientInputStream.read(); - Assert.fail("Should have timed out waiting for a response, but read " + b); - } - catch (SocketTimeoutException e) - { - int elapsed = Long.valueOf(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start).intValue(); - Assert.assertThat("Expected timeout", elapsed, greaterThanOrEqualTo(3 * specifiedTimeout / 4)); - } - - // write remaining characters - clientOutputStream.write("90ABCDEF".getBytes(StandardCharsets.UTF_8)); - clientOutputStream.flush(); - - // Verify echo server to client - for (char c : "1234567890ABCDEF".toCharArray()) - { - int b = clientInputStream.read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - } - - @Test - public void testIdle() throws Exception - { - int idleTimeout = 2000; - - Socket client = newClient(); - - client.setSoTimeout(idleTimeout*10); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - Assert.assertTrue(_lastEndPointLatch.await(10, TimeUnit.SECONDS)); - _lastEndPoint.setIdleTimeout(idleTimeout); - - // Write client to server - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - - // read until idle shutdown received - int b = client.getInputStream().read(); - assertEquals(-1, b); - long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; - assertThat(idle, greaterThan(idleTimeout - 100L)); - assertThat(idle, lessThan(idleTimeout * 2L)); - - // But endpoint may still be open for a little bit. - for (int i = 0; i < 20; ++i) - { - if (_lastEndPoint.isOpen()) - Thread.sleep(2 * idleTimeout / 10); - else - break; - } - assertFalse(_lastEndPoint.isOpen()); - } - - @Test - public void testBlockedReadIdle() throws Exception - { - Socket client = newClient(); - InputStream clientInputStream = client.getInputStream(); - OutputStream clientOutputStream = client.getOutputStream(); - - client.setSoTimeout(5000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - clientOutputStream.write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = clientInputStream.read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - - Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); - int idleTimeout = 500; - _lastEndPoint.setIdleTimeout(idleTimeout); - - // Write 8 and cause block waiting for 10 - _blockAt = 10; - clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8)); - clientOutputStream.flush(); - - // read until idle shutdown received - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - int b = clientInputStream.read(); - assertEquals('E', b); - long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; - assertTrue(idle > idleTimeout / 2); - assertTrue(idle < idleTimeout * 2); - - for (char c : "E: 12345678".toCharArray()) - { - b = clientInputStream.read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - b = clientInputStream.read(); - assertEquals(-1,b); - - // But endpoint is still open. - if(_lastEndPoint.isOpen()) - // Wait for another idle callback - Thread.sleep(idleTimeout * 2); - - // endpoint is closed. - assertFalse(_lastEndPoint.isOpen()); - } - - @Test - public void testStress() throws Exception - { - Socket client = newClient(); - client.setSoTimeout(30000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - final int writes = 200000; - - final byte[] bytes = "HelloWorld-".getBytes(StandardCharsets.UTF_8); - byte[] count = "0\n".getBytes(StandardCharsets.UTF_8); - BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream()); - final CountDownLatch latch = new CountDownLatch(writes); - final InputStream in = new BufferedInputStream(client.getInputStream()); - final long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - out.write(bytes); - out.write(count); - out.flush(); - - Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); - _lastEndPoint.setIdleTimeout(5000); - - new Thread() - { - @Override - public void run() - { - Thread.currentThread().setPriority(MAX_PRIORITY); - long last = -1; - int count = -1; - try - { - while (latch.getCount() > 0) - { - // Verify echo server to client - for (byte b0 : bytes) - { - int b = in.read(); - Assert.assertThat(b, greaterThan(0)); - assertEquals(0xff & b0, b); - } - - count = 0; - int b = in.read(); - while (b > 0 && b != '\n') - { - count = count * 10 + (b - '0'); - b = in.read(); - } - last = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - - //if (latch.getCount()%1000==0) - // System.out.println(writes-latch.getCount()); - - latch.countDown(); - } - } - catch (Throwable e) - { - - long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - System.err.println("count=" + count); - System.err.println("latch=" + latch.getCount()); - System.err.println("time=" + (now - start)); - System.err.println("last=" + (now - last)); - System.err.println("endp=" + _lastEndPoint); - System.err.println("conn=" + _lastEndPoint.getConnection()); - - e.printStackTrace(); - } - } - }.start(); - - // Write client to server - for (int i = 1; i < writes; i++) - { - out.write(bytes); - out.write(Integer.toString(i).getBytes(StandardCharsets.ISO_8859_1)); - out.write('\n'); - if (i % 1000 == 0) - { - //System.err.println(i+"/"+writes); - out.flush(); - } - Thread.yield(); - } - out.flush(); - - long last = latch.getCount(); - while (!latch.await(5, TimeUnit.SECONDS)) - { - //System.err.println(latch.getCount()); - if (latch.getCount() == last) - Assert.fail(); - last = latch.getCount(); - } - - assertEquals(0, latch.getCount()); - } - - @Test - public void testWriteBlocked() throws Exception - { - Socket client = newClient(); - - client.setSoTimeout(10000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - _writeCount = 10000; - String data = "Now is the time for all good men to come to the aid of the party"; - client.getOutputStream().write(data.getBytes(StandardCharsets.UTF_8)); - BufferedInputStream in = new BufferedInputStream(client.getInputStream()); - - int byteNum = 0; - try - { - for (int i = 0; i < _writeCount; i++) - { - if (i % 1000 == 0) - TimeUnit.MILLISECONDS.sleep(200); - - // Verify echo server to client - for (int j = 0; j < data.length(); j++) - { - char c = data.charAt(j); - int b = in.read(); - byteNum++; - assertTrue(b > 0); - assertEquals("test-" + i + "/" + j,c,(char)b); - } - - if (i == 0) - _lastEndPoint.setIdleTimeout(60000); - } - } - catch (SocketTimeoutException e) - { - System.err.println("SelectorManager.dump() = " + _manager.dump()); - LOG.warn("Server: " + server); - LOG.warn("Error reading byte #" + byteNum,e); - throw e; - } - - client.close(); - - for (int i = 0; i < 10; ++i) - { - if (server.isOpen()) - Thread.sleep(10); - else - break; - } - assertFalse(server.isOpen()); - } - - - // TODO make this test reliable - @Test - @Ignore - public void testRejectedExecution() throws Exception - { - _manager.stop(); - _threadPool.stop(); - - final CountDownLatch latch = new CountDownLatch(1); - - BlockingQueue q = new ArrayBlockingQueue<>(4); - _threadPool = new QueuedThreadPool(4,4,60000,q); - _manager = new SelectorManager(_threadPool, _scheduler, 1) - { - - @Override - protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException - { - SocketChannelEndPoint endp = new SocketChannelEndPoint(channel,selector,selectionKey,getScheduler()); - _lastEndPoint = endp; - _lastEndPointLatch.countDown(); - return endp; - } - - @Override - public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException - { - return new TestConnection(endpoint,latch); - } - }; - - _threadPool.start(); - _manager.start(); - - AtomicInteger timeout = new AtomicInteger(); - AtomicInteger rejections = new AtomicInteger(); - AtomicInteger echoed = new AtomicInteger(); - - CountDownLatch closed = new CountDownLatch(20); - for (int i=0;i<20;i++) - { - new Thread() - { - @Override - public void run() - { - try(Socket client = newClient();) - { - client.setSoTimeout(5000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - client.getOutputStream().flush(); - client.shutdownOutput(); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - assertEquals(-1,client.getInputStream().read()); - echoed.incrementAndGet(); - } - catch(SocketTimeoutException x) - { - x.printStackTrace(); - timeout.incrementAndGet(); - } - catch(Throwable x) - { - rejections.incrementAndGet(); - } - finally - { - closed.countDown(); - } - } - }.start(); - } - - // unblock the handling - latch.countDown(); - - // wait for all clients to complete or fail - closed.await(); - - // assert some clients must have been rejected - Assert.assertThat(rejections.get(),Matchers.greaterThan(0)); - // but not all of them - Assert.assertThat(rejections.get(),Matchers.lessThan(20)); - // none should have timed out - Assert.assertThat(timeout.get(),Matchers.equalTo(0)); - // and the rest should have worked - Assert.assertThat(echoed.get(),Matchers.equalTo(20-rejections.get())); - - // and the selector is still working for new requests - try(Socket client = newClient();) - { - client.setSoTimeout(5000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - client.getOutputStream().flush(); - client.shutdownOutput(); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char)b); - } - assertEquals(-1,client.getInputStream().read()); - } - - } -} diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java index 4fef01e1e1a..017104b7954 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java @@ -20,10 +20,8 @@ package org.eclipse.jetty.io; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; @@ -56,6 +54,7 @@ import javax.net.ssl.SSLSocket; import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.FutureCallback; @@ -69,6 +68,7 @@ import org.hamcrest.Matchers; import org.junit.After; import org.junit.Assert; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -83,7 +83,7 @@ public class SocketChannelEndPointTest { Socket newClient(ServerSocketChannel connector) throws IOException; - Connection newConnection(SelectableChannel channel, EndPoint endPoint, Executor executor, SafeInteger blockAt, SafeInteger writeCount); + Connection newConnection(SelectableChannel channel, EndPoint endPoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount); boolean supportsHalfCloses(); } @@ -100,7 +100,10 @@ public class SocketChannelEndPointTest return ret; } - public Scenario _scenario; + @Rule + public TestTracker tracker = new TestTracker(); + + private final Scenario _scenario; private ServerSocketChannel _connector; private QueuedThreadPool _threadPool; @@ -110,8 +113,8 @@ public class SocketChannelEndPointTest private CountDownLatch _lastEndPointLatch; // Must be volatile or the test may fail spuriously - private SafeInteger _blockAt = new SafeInteger("_blockAt", 0); - private SafeInteger _writeCount = new SafeInteger("_writeCount", 1); + private AtomicInteger _blockAt = new AtomicInteger(0); + private AtomicInteger _writeCount = new AtomicInteger(1); public SocketChannelEndPointTest(Scenario scenario) throws Exception { @@ -299,112 +302,6 @@ public class SocketChannelEndPointTest } } - @Test - public void testIdle() throws Exception - { - int idleTimeout = 2000; - - Socket client = _scenario.newClient(_connector); - - client.setSoTimeout(idleTimeout * 10); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - Assert.assertTrue(_lastEndPointLatch.await(10, TimeUnit.SECONDS)); - _lastEndPoint.setIdleTimeout(idleTimeout); - - // Write client to server - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = client.getInputStream().read(); - assertTrue(b > 0); - assertEquals(c, (char) b); - } - - // read until idle shutdown received - int b = client.getInputStream().read(); - assertEquals(-1, b); - long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; - assertThat(idle, greaterThan(idleTimeout - 100L)); - assertThat(idle, lessThan(idleTimeout * 2L)); - - // But endpoint may still be open for a little bit. - for (int i = 0; i < 20; ++i) - { - if (_lastEndPoint.isOpen()) - Thread.sleep(2 * idleTimeout / 10); - else - break; - } - assertFalse(_lastEndPoint.isOpen()); - } - - @Test - public void testBlockedReadIdle() throws Exception - { - Socket client = _scenario.newClient(_connector); - InputStream clientInputStream = client.getInputStream(); - OutputStream clientOutputStream = client.getOutputStream(); - - client.setSoTimeout(5000); - - SocketChannel server = _connector.accept(); - server.configureBlocking(false); - - _manager.accept(server); - - // Write client to server - clientOutputStream.write("HelloWorld".getBytes(StandardCharsets.UTF_8)); - - // Verify echo server to client - for (char c : "HelloWorld".toCharArray()) - { - int b = clientInputStream.read(); - assertTrue(b > 0); - assertEquals(c, (char) b); - } - - Assert.assertTrue(_lastEndPointLatch.await(1, TimeUnit.SECONDS)); - int idleTimeout = 500; - _lastEndPoint.setIdleTimeout(idleTimeout); - - // Write 8 and cause block waiting for 10 - _blockAt.set(10); - clientOutputStream.write("12345678".getBytes(StandardCharsets.UTF_8)); - clientOutputStream.flush(); - - // read until idle shutdown received - long start = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); - int b = clientInputStream.read(); - assertEquals('E', b); - long idle = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) - start; - assertTrue(idle > idleTimeout / 2); - assertTrue(idle < idleTimeout * 2); - - for (char c : "E: 12345678".toCharArray()) - { - b = clientInputStream.read(); - assertTrue(b > 0); - assertEquals(c, (char) b); - } - b = clientInputStream.read(); - assertEquals(-1, b); - - // But endpoint is still open. - if (_lastEndPoint.isOpen()) - // Wait for another idle callback - Thread.sleep(idleTimeout * 2); - - // endpoint is closed. - assertFalse(_lastEndPoint.isOpen()); - } - @Test public void testStress() throws Exception { @@ -729,7 +626,7 @@ public class SocketChannelEndPointTest } @Override - public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount) { return new TestConnection(endpoint, executor, blockAt, writeCount); } @@ -773,7 +670,7 @@ public class SocketChannelEndPointTest } @Override - public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount) { SSLEngine engine = __sslCtxFactory.newSSLEngine(); engine.setUseClientMode(false); @@ -798,62 +695,21 @@ public class SocketChannelEndPointTest } } - /** - * Testing possibility of a bad test configuration - */ - public static class SafeInteger - { - private final String name; - private int value; - private boolean getCalled = false; - private Throwable firstGetThrowable; - - public SafeInteger(String name, int value) - { - this.name = name; - this.value = value; - } - - public void set(int value) - { - synchronized(this) - { - if(getCalled) - throw new IllegalStateException(name + ".get() already called, unable to " + name + ".set(" + value + ") now: TOOLATE", firstGetThrowable); - this.value = value; - } - } - - public int get() - { - synchronized (this) - { - if(!getCalled) - { - // first occurrence. - firstGetThrowable = new Throwable("First Get Here"); - } - getCalled = true; - return this.value; - } - } - } - @SuppressWarnings("Duplicates") public static class TestConnection extends AbstractConnection { private static final Logger LOG = Log.getLogger(TestConnection.class); volatile FutureCallback _blockingRead; - final SafeInteger _blockAt; - final SafeInteger _writeCount; + final AtomicInteger _blockAt; + final AtomicInteger _writeCount; // volatile int _blockAt = 0; ByteBuffer _in = BufferUtil.allocate(32 * 1024); ByteBuffer _out = BufferUtil.allocate(32 * 1024); long _last = -1; final CountDownLatch _latch; - public TestConnection(EndPoint endp, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + public TestConnection(EndPoint endp, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount) { super(endp, executor); _latch = null; @@ -861,7 +717,7 @@ public class SocketChannelEndPointTest this._writeCount = writeCount; } - public TestConnection(EndPoint endp, CountDownLatch latch, Executor executor, SafeInteger blockAt, SafeInteger writeCount) + public TestConnection(EndPoint endp, CountDownLatch latch, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount) { super(endp, executor); _latch = latch; From adeaf77c02c0478f0022b8e5383b6be5e941236f Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 20 Mar 2018 10:38:53 +0100 Subject: [PATCH 77/87] Small optimization to save the allocation of an iterator, in case the selector has been woken up without selected keys. Signed-off-by: Simone Bordet --- .../src/main/java/org/eclipse/jetty/io/ManagedSelector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java index bad0ea71de0..eb18828a44e 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java @@ -397,7 +397,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable } _keys = selector.selectedKeys(); - _cursor = _keys.iterator(); + _cursor = _keys.isEmpty() ? Collections.emptyIterator() : _keys.iterator(); if (LOG.isDebugEnabled()) LOG.debug("Selector {} processing {} keys, {} updates", selector, _keys.size(), updates); From afd067771937bd46eb72bbd2c4d27956e0874386 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 20 Mar 2018 11:00:47 +0100 Subject: [PATCH 78/87] Fixes #2358 - Add ALPN module file for JDK 10. Also added ALPN module file for JDK 11. Removed merge leftovers under directory protonego-impl/. Signed-off-by: Simone Bordet --- .../src/main/config/modules/alpn-impl/alpn-10.mod | 4 ++++ .../src/main/config/modules/alpn-impl/alpn-11.mod | 4 ++++ .../src/main/config/modules/alpn-impl/alpn-9.mod | 2 +- .../main/config/modules/protonego-impl/alpn-1.8.0_144.mod | 8 -------- .../dist-home/modules/protonego-impl/alpn-1.8.0_144.mod | 8 -------- 5 files changed, 9 insertions(+), 17 deletions(-) create mode 100644 jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-10.mod create mode 100644 jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-11.mod delete mode 100644 jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_144.mod delete mode 100644 jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_144.mod diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-10.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-10.mod new file mode 100644 index 00000000000..689601a4197 --- /dev/null +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-10.mod @@ -0,0 +1,4 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[depend] +alpn-impl/alpn-9 diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-11.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-11.mod new file mode 100644 index 00000000000..689601a4197 --- /dev/null +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-11.mod @@ -0,0 +1,4 @@ +DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[depend] +alpn-impl/alpn-9 diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod index cc7f4257348..e1de6726af9 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-9.mod @@ -1,7 +1,7 @@ DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Provides support for ALPN based on JDK 9 APIs. +Provides support for ALPN based on JDK 9+ APIs. [lib] lib/jetty-alpn-java-server-${jetty.version}.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_144.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_144.mod deleted file mode 100644 index fdd3868701d..00000000000 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn-1.8.0_144.mod +++ /dev/null @@ -1,8 +0,0 @@ -[name] -protonego-boot - -[files] -http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar - -[exec] --Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar diff --git a/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_144.mod b/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_144.mod deleted file mode 100644 index fdd3868701d..00000000000 --- a/jetty-start/src/test/resources/dist-home/modules/protonego-impl/alpn-1.8.0_144.mod +++ /dev/null @@ -1,8 +0,0 @@ -[name] -protonego-boot - -[files] -http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.11.v20170118/alpn-boot-8.1.11.v20170118.jar|lib/alpn/alpn-boot-8.1.11.v20170118.jar - -[exec] --Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar From 16699214c6d2e27b0698e0481778360b14907440 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Tue, 20 Mar 2018 21:10:18 +1000 Subject: [PATCH 79/87] fix using -DskipTests not skipping tests #2359 Signed-off-by: olivier lamy use -DskipTests Signed-off-by: olivier lamy --- Jenkinsfile | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 79 ++++++++++++++++-------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index a2d6e8da43b..57685b5fda3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -43,7 +43,7 @@ def getFullBuild(jdk, os) { publisherStrategy: 'EXPLICIT', globalMavenSettingsConfig: 'oss-settings.xml', mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") { - sh "mvn -V -B clean install -Dtest=None -T6" + sh "mvn -V -B clean install -DskipTests -T6" } } diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 88310a81aad..88d59ec7162 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -17,6 +17,7 @@ 4.11.0 2.5.2 1.0 + true @@ -424,31 +425,17 @@ - - - maven-surefire-plugin - - true - - ${settings.localRepository} - - - - - org.apache.servicemix.tooling - depends-maven-plugin - - - generate-depends-file - - generate-depends-file - - - - - + + maven-surefire-plugin + + ${skipTests} + + ${settings.localRepository} + + + org.eclipse.m2e @@ -476,6 +463,20 @@ + + + org.apache.servicemix.tooling + depends-maven-plugin + + + generate-depends-file + + generate-depends-file + + + + + @@ -515,20 +516,23 @@ test + + false + - - maven-surefire-plugin - - false - - **/TestJettyOSGiBootHTTP2JDK9* - - - - -Dmortbay-alpn-boot=${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar - - + + maven-surefire-plugin + + + + **/TestJettyOSGiBootHTTP2JDK9* + + + + -Dmortbay-alpn-boot=${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar + + @@ -569,12 +573,15 @@ test + + false + maven-surefire-plugin - false + ${skipTests} **/TestJettyOSGiBootHTTP2 From 1f8159b1e4a42d3f79997021ea1609f2fbac6de5 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 20 Mar 2018 07:18:24 -0500 Subject: [PATCH 80/87] Updating to version 9.4.9.v20180320 --- VERSION.txt | 92 +++++++++++- aggregates/jetty-all-compact3/pom.xml | 2 +- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 132 +++++++++--------- jetty-cdi/cdi-2/pom.xml | 2 +- jetty-cdi/cdi-core/pom.xml | 2 +- jetty-cdi/cdi-full-servlet/pom.xml | 2 +- jetty-cdi/cdi-servlet/pom.xml | 2 +- jetty-cdi/cdi-websocket/pom.xml | 2 +- jetty-cdi/pom.xml | 2 +- jetty-cdi/test-cdi-webapp/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-home/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-alpn-tests/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- .../jetty-memcached-sessions/pom.xml | 2 +- jetty-memcached/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-unixsocket/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client-impl/pom.xml | 2 +- .../javax-websocket-server-impl/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-api/pom.xml | 2 +- jetty-websocket/websocket-client/pom.xml | 2 +- jetty-websocket/websocket-common/pom.xml | 2 +- jetty-websocket/websocket-server/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-continuation/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-sessions/test-file-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-sessions/test-hash-sessions/pom.xml | 2 +- .../test-hazelcast-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-memcached-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- tests/test-webapps/test-http2-webapp/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- 128 files changed, 283 insertions(+), 193 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index ee6dd5306ba..b11160e5611 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,4 +1,94 @@ -jetty-9.4.9-SNAPSHOT +jetty-9.4.9.v20180320 - 20 March 2018 + + 347 Avoid sending request using a connection that is idle timing out + + 1416 GzipHandler generated ETag suffix has problems with If-Match header + logic + + 1602 WebAppContext is started twice, once by deployer, again by lifecycle + + 1614 AbstractNCSARequestLog does not extract the user from the http header + when it has not been authenticated + + 1770 SniX509ExtendedKeyManager.chooseServerAlias() throws + NullPointerException when socket is null + + 1797 JEP 238 - Multi-Release JAR files break bytecode scanning + + 1832 Bad HTTP Close prevents proper TCP close + + 1918 Scalable scheduler implementation + + 1933 Use CLASSPATH for scanning java9 system classes + + 1940 Embedded CDI: SessionScoped gives a NPE + + 1949 Client-side problems with digest authentication + + 1956 Store and report build information of Jetty + + 1966 HttpMethod case sensitive + + 1970 ManagedSelector can lose selector thread under high concurrent load + + 1973 Implement minimum response data rate + + 1983 Improve warning for incompatible ALPN processor + + 1986 ServletContextHandler.Context addListener() methods support + session listeners + + 2003 Do not submit blocking tasks as managed selector actions + + 2006 ServletInputStream.isReady not registering interest when it should + + 2010 SniX509ExtendedKeyManager causes exception: "FIPS mode: only SunJSSE + KeyManagers may be used" + + 2014 Support unix domain sockets in HttpClient + + 2015 jetty-alpn-conscrypt-server needs appropriate osgi headers in manifest + + 2016 jetty-alpn-openjdk8-server needs correct osgi headers in manifest + + 2019 Expose HttpClientTransport in JMX + + 2020 Introduce a name for `HttpClient` instances + + 2022 Fine grained RFC HTTP Compliance modes: including OWS prior to field + colon + + 2028 Add osgi headers for alpn-java client and server + + 2030 NPE in AnnotationConfiguration with DEBUG enabled + + 2033 Improve HTTP/2 session and stream stall times report + + 2034 Improve HTTP2Session dump + + 2035 FlowControlStrategy keeps around reset streams + + 2037 HTTP/2 stream reset leaves stream frames in the flusher + + 2038 FileSessionDataStore.deleteAllFiles(File, String) can become slow + + 2043 ConcurrentModificationException during annotation parsing + + 2046 Server.stop not closing connections + + 2050 Clarify ObjectMBean getObject[Name|Context]Basis() methods + + 2079 Upgrade to apache jasper 8.5.24 + + 2080 Exclude more maven machinery dependencies from the jetty-maven-plugin + server path + + 2081 No idle timeout exception when dispatch is delayed + + 2088 Recycle HTTP/2 channels on the client + + 2090 Jetty fails to start on OpenJDK 9: "Invalid Java version 9.0.1.3" + + 2093 Correcting Bom managed dependencies that do not exist + + 2114 Fix NPE in JettyHttpServerProvider + + 2117 Allow to configure HttpClient default request Content-Type + + 2130 Introduce thread pool module for simpler configuration of thread pool + in standalone + + 2131 Introduce a monitored thread pool + + 2136 maven & jetty-maven-plugin & offline + error:java.net.UnknownHostException: www.eclipse.org + + 2148 Limit BufferUtil.toDetailString() raw character display to USASCII + 7-bit printable characters + + 2152 Produce jetty-home-source artifacts for Eclipse Jetty source jars + + 2160 Digest authentication should use absolute path + + 2164 Ensure all jetty modules that use ServiceLoader have correct OSGi + manifest headers + + 2190 HTTP/2 close and GOAWAY behavior + + 2203 Use GlobalWebAppConfigBinding rather than special methods on + DeploymentManager/WebAppProvider + + 2209 jetty-maven-plugin deploy-war silently fails (unless the pom has war + packaging) + + 2210 NPE at org.eclipse.jetty.client.HttpDestination.newExchangeQueue + + 2218 Adding workaround for Windows NIO Selector Bug + + 2232 Dependency Conflict: Conflicting JARs org.apache.maven:maven-project + + 2255 Notify SSL handshake failures on write failures + + 2275 jetty.server.ResourceService.doGet() + RequestDispatcher INCLUDE + + 2278 Could not find artifact + org.eclipse.jetty.tests:test-webapps-parent:pom:9.4.8.v20171121 + + 2279 Jetty 9.4.x start.jar: "?=" in [ini] defeats Issue #1139 functionality + + 2280 Default application/json to utf-8 encoding in encoding.properties + + 2284 NPE from start.jar during JVM version parsing + + 2288 Cleanup the statistics classes + + 2291 Expose HTTP/2 close reason in dumps + + 2293 HTTP/2 client multiplexed connection pool creates too many connections + + 2297 HTTP/2 client transport should honor HttpClient.connectBlocking + + 2298 Override the processor number with an environment variable + + 2307 Error page can have null charset in content type + + 2308 Type change in MonitorTask - int cannot be converted to + ThreadPoolExecutor + + 2312 HTTP/2 Connection.Listener notified after first request + + 2313 Dump HTTP/2 channel state + + 2318 HttpParser.Listener.onBadMessage() should take BadMessageException + + 2346 Missing stack traces in HTTPChannel.onException + + 2358 Add ALPN module file for JDK 10 jetty-9.4.8.v20171121 - 21 November 2017 + 212 HttpClient should support pluggable AuthenticationStore diff --git a/aggregates/jetty-all-compact3/pom.xml b/aggregates/jetty-all-compact3/pom.xml index 059c0f353f5..555c98741e8 100644 --- a/aggregates/jetty-all-compact3/pom.xml +++ b/aggregates/jetty-all-compact3/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../../pom.xml 4.0.0 diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index 8509ffc3a9d..1b37c201dab 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index dccce7f3010..527b3f7d74e 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 apache-jsp diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index ec0c756b469..490602ba3f2 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 apache-jstl diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index 53687ba0b3d..8858314f30c 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 5256abd7606..018760087e8 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index cfe244bf01a..33b2bbc765f 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index 05a5c71af74..9223d75ebef 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index c5b5f3f698d..11fc937e12d 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml org.eclipse.jetty.examples diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index a91883265a2..e5aabd618ca 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml index fe103f88cfd..db49d7d0e92 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml index e8b6fa6101c..fc57d37f65b 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index 3b4e1c7718a..c9e4bc6ef16 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index 24480d7ba3c..eed95926bd4 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml index 73c2d9b1150..f80cce3cc14 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml index f2c0ec6cb23..7dd11b299a7 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 3354fa42539..da584d670ab 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index 2d27f3e648d..01b869699a3 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 2bc7353e0d8..35353b71852 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-annotations diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index be3373af1dd..b2d33ff7efa 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 9248c4ea8fc..2ddb83bbc90 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty 4.0.0 jetty-bom - 9.4.9-SNAPSHOT + 9.4.9.v20180320 Jetty :: Bom Jetty BOM artifact http://www.eclipse.org/jetty @@ -94,331 +94,331 @@ org.eclipse.jetty apache-jsp - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty apache-jstl - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-java-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-java-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-openjdk8-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-openjdk8-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-conscrypt-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-conscrypt-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-alpn-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-annotations - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-ant - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.cdi cdi-core - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.cdi cdi-servlet - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-continuation - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-deploy - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-distribution - 9.4.9-SNAPSHOT + 9.4.9.v20180320 zip org.eclipse.jetty jetty-distribution - 9.4.9-SNAPSHOT + 9.4.9.v20180320 tar.gz org.eclipse.jetty.fcgi fcgi-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.fcgi fcgi-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-home - 9.4.9-SNAPSHOT + 9.4.9.v20180320 zip org.eclipse.jetty jetty-home - 9.4.9-SNAPSHOT + 9.4.9.v20180320 tar.gz org.eclipse.jetty jetty-http - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.http2 http2-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.http2 http2-common - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.http2 http2-hpack - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.http2 http2-http-client-transport - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.http2 http2-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-http-spi - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-infinispan - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-hazelcast - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-io - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-jaas - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-jaspi - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-jmx - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-jndi - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.memcached jetty-memcached-sessions - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-nosql - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.osgi jetty-osgi-boot - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.osgi jetty-httpservice - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-plus - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-proxy - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-quickstart - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-rewrite - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-security - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-servlet - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-servlets - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-spring - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-unixsocket - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-util - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-util-ajax - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-webapp - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket javax-websocket-client-impl - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket javax-websocket-server-impl - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket websocket-api - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket websocket-client - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket websocket-common - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket websocket-server - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty.websocket websocket-servlet - 9.4.9-SNAPSHOT + 9.4.9.v20180320 org.eclipse.jetty jetty-xml - 9.4.9-SNAPSHOT + 9.4.9.v20180320 diff --git a/jetty-cdi/cdi-2/pom.xml b/jetty-cdi/cdi-2/pom.xml index 44f1cede850..6389f971d30 100644 --- a/jetty-cdi/cdi-2/pom.xml +++ b/jetty-cdi/cdi-2/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 cdi-2 diff --git a/jetty-cdi/cdi-core/pom.xml b/jetty-cdi/cdi-core/pom.xml index a7ba32699c0..a9cad873db0 100644 --- a/jetty-cdi/cdi-core/pom.xml +++ b/jetty-cdi/cdi-core/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 cdi-core diff --git a/jetty-cdi/cdi-full-servlet/pom.xml b/jetty-cdi/cdi-full-servlet/pom.xml index 5d1190ba820..879690a1cc1 100644 --- a/jetty-cdi/cdi-full-servlet/pom.xml +++ b/jetty-cdi/cdi-full-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 cdi-full-servlet diff --git a/jetty-cdi/cdi-servlet/pom.xml b/jetty-cdi/cdi-servlet/pom.xml index 0a7d26fd709..9c1e1f17d3d 100644 --- a/jetty-cdi/cdi-servlet/pom.xml +++ b/jetty-cdi/cdi-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 cdi-servlet diff --git a/jetty-cdi/cdi-websocket/pom.xml b/jetty-cdi/cdi-websocket/pom.xml index 1282d7b86e9..6c5e96071c2 100644 --- a/jetty-cdi/cdi-websocket/pom.xml +++ b/jetty-cdi/cdi-websocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 cdi-websocket diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index 448b8533e33..01935f5301b 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 org.eclipse.jetty.cdi diff --git a/jetty-cdi/test-cdi-webapp/pom.xml b/jetty-cdi/test-cdi-webapp/pom.xml index e6b8bd7a9a2..d49215a3392 100644 --- a/jetty-cdi/test-cdi-webapp/pom.xml +++ b/jetty-cdi/test-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 test-cdi-webapp diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 1ce996662f1..634e5024f06 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index f51494c0667..020c1996e4e 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 171688bf532..845a0949e0d 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 32a051f13e7..7a4986a2064 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index 43479053336..b4333b1ff60 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 jetty-documentation Jetty :: Documentation diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index 7027f8b2af5..e35a1124c65 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index 7979c80ee32..ef2329caed5 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 6c109dda687..5a62941224e 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 6633cbd6ec8..9b3557b2b5b 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 5f867dd79fc..4cd36c435cc 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index edfc34442b6..3168dede162 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index b661cb1cb18..c56283b6756 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-home diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index 9c5208d0f1f..e75257de189 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 2d0b5735314..556023bfe3b 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-http diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml index 0e5acd688b5..d5c8da871ca 100644 --- a/jetty-http2/http2-alpn-tests/pom.xml +++ b/jetty-http2/http2-alpn-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 862fb6694e6..83a139a8876 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 224ddec4bae..33c8dd3d494 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 3a047ab1819..985dd6c2535 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index af8175afb1a..d40525ffc1a 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index cac2bfb73fa..c8542c52987 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 24ffa4ba878..83d0d79ba84 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index 14141ae0645..d15763a6826 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-infinispan diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index 42d3da264fc..60c0d32c79f 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -2,7 +2,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 33e69ba38ff..9ee0073e67c 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-jaas diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index b101a3b62d7..60fbb17edd1 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index fe68ee5c275..cb539af5f9b 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index e38f6dd6865..3b0f2679289 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-jndi diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index a67d3f7eda9..9e74d4aa9dc 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 0317e5c6ffc..1ece9440739 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-maven-plugin diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml index 1c89cad06f5..4c7a46391c1 100644 --- a/jetty-memcached/jetty-memcached-sessions/pom.xml +++ b/jetty-memcached/jetty-memcached-sessions/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-memcached/pom.xml b/jetty-memcached/pom.xml index e4496d22708..85cbf738c9f 100644 --- a/jetty-memcached/pom.xml +++ b/jetty-memcached/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index e085bb4a290..76bf6179c6c 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-nosql diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index da2030cb447..d1b9e0e1d7b 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-osgi-alpn diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index d385c2199f6..dc00a45b1a8 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 2ab3d29ebaf..a191fb6cd1a 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 15e2c1e72a4..01330595c6c 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index a7eea3517ac..08e6e4e23b0 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index 2f46d71bd83..442c7829add 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 508819547e7..03ab8a61c74 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index 37a3bfc23e5..5fc0fd73188 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index 8eef0d3414e..89b6285c57e 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index b6fe7565661..bf0fb272b40 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 88310a81aad..39dc85d56d9 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index f579e4f55fd..3d91da34782 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-plus diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index a336103a832..53d6a14033f 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-proxy diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index e448d4700de..a2dc9cc8437 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 org.eclipse.jetty diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 00300c48d2a..7a313a9f57d 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-rewrite diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 13778da970c..99fbd43a868 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index f9e7941c42f..f3f818d0baf 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index e79329a2b8e..ad34db3b893 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index bd48e1c1dd3..726ca18158f 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 46e2ca5ceac..c4b9c016b12 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-servlets diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index d0e6b0df7f9..db4b19c0e46 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-spring diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 33d3b9d6e67..f472de10644 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-start diff --git a/jetty-unixsocket/pom.xml b/jetty-unixsocket/pom.xml index e968db1f764..dc6216625aa 100644 --- a/jetty-unixsocket/pom.xml +++ b/jetty-unixsocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-unixsocket diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index e641d83ba62..7c81d74e1f8 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index e5b8143e6ef..39ae3fc9b10 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 74652244be3..ab386240e10 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-webapp diff --git a/jetty-websocket/javax-websocket-client-impl/pom.xml b/jetty-websocket/javax-websocket-client-impl/pom.xml index d5690833dc5..282ee1b5c16 100644 --- a/jetty-websocket/javax-websocket-client-impl/pom.xml +++ b/jetty-websocket/javax-websocket-client-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/javax-websocket-server-impl/pom.xml b/jetty-websocket/javax-websocket-server-impl/pom.xml index 2ac246aede8..c55c7de509e 100644 --- a/jetty-websocket/javax-websocket-server-impl/pom.xml +++ b/jetty-websocket/javax-websocket-server-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index f0a6806cae8..7e7b7f724ba 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml index c12f1b50a02..b8be92436af 100644 --- a/jetty-websocket/websocket-api/pom.xml +++ b/jetty-websocket/websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 74db3b95ff8..9f32d1e2764 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index a3340c7c432..c3ec7c70926 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml index 1cffed0b955..8359f6d8987 100644 --- a/jetty-websocket/websocket-server/pom.xml +++ b/jetty-websocket/websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index 058325260fd..0b30ff744e0 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index 07b63b1a13a..7182985a3ce 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index d1b0edd14a0..eafc52c5988 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 Jetty :: Project The Eclipse Jetty Project pom diff --git a/tests/pom.xml b/tests/pom.xml index 48288692731..34d0d05e5b9 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml index 45891a9fc50..aeb5b0136d5 100644 --- a/tests/test-continuation/pom.xml +++ b/tests/test-continuation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index f86e362cade..8a263d14ecf 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 6e5cc58e119..18c9e5f7366 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index 60f2994d26d..f15bad978c3 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 66ffb6db176..09c501a933e 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index 21ee3e8a440..dc2b495041e 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 4ba211f80c2..09021de8ce6 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index f33f2d5eccb..287eea690b3 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 40380a0b367..40159078dc1 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml index 3698a4e89e1..d01ba7d81c4 100644 --- a/tests/test-sessions/test-file-sessions/pom.xml +++ b/tests/test-sessions/test-file-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-file-sessions Jetty Tests :: Sessions :: File diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index f8cceae737f..52bf3f58fb2 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index ef362ac21e7..9d91e357545 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-hash-sessions Jetty Tests :: Sessions :: Hash diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index 9ad03019564..0846d8de7c2 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index 8039e09077c..9a8b413d88a 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 026a3758c10..a970e339783 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index 55f7ebc9020..c1b48e31463 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-memcached-sessions Jetty Tests :: Sessions :: Memcached diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index 0b8d05d50ff..f7d71778760 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 1d529731c35..0e314d0dbb5 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 8532cc3d32f..1d6e6823b4b 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-http2-webapp/pom.xml b/tests/test-webapps/test-http2-webapp/pom.xml index 94faf572d9d..53fb7544ebd 100644 --- a/tests/test-webapps/test-http2-webapp/pom.xml +++ b/tests/test-webapps/test-http2-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 4.0.0 diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 6aec106719c..ee39ccbbdc1 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index c5e908928c4..d5181e6c27e 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index f0ceb2e7c30..41b86785398 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index b5158794e4c..070ed63da8c 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index b9712db8d09..7fad1c69e67 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index 0de94384c9c..2cbcb0ae9fd 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index 3f4930bfd19..5c829e85a39 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index 7ed612bf720..9c8f47c965b 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 254488cf871..212453df575 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 39c85650cfb..32cea24d9e0 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9-SNAPSHOT + 9.4.9.v20180320 test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 From c3cc138a3bce9c549eb53d79855f3297755dfad6 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 20 Mar 2018 08:25:59 -0500 Subject: [PATCH 81/87] Updating to version 9.4.10-SNAPSHOT --- VERSION.txt | 2 + aggregates/jetty-all-compact3/pom.xml | 2 +- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-client/pom.xml | 2 +- .../jetty-alpn-conscrypt-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-openjdk8-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 132 +++++++++--------- jetty-cdi/cdi-2/pom.xml | 2 +- jetty-cdi/cdi-core/pom.xml | 2 +- jetty-cdi/cdi-full-servlet/pom.xml | 2 +- jetty-cdi/cdi-servlet/pom.xml | 2 +- jetty-cdi/cdi-websocket/pom.xml | 2 +- jetty-cdi/pom.xml | 2 +- jetty-cdi/test-cdi-webapp/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-home/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-alpn-tests/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- .../jetty-memcached-sessions/pom.xml | 2 +- jetty-memcached/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-server/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-unixsocket/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client-impl/pom.xml | 2 +- .../javax-websocket-server-impl/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-api/pom.xml | 2 +- jetty-websocket/websocket-client/pom.xml | 2 +- jetty-websocket/websocket-common/pom.xml | 2 +- jetty-websocket/websocket-server/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-continuation/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-sessions/test-file-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-sessions/test-hash-sessions/pom.xml | 2 +- .../test-hazelcast-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-memcached-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- tests/test-webapps/test-http2-webapp/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- 128 files changed, 194 insertions(+), 192 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index b11160e5611..bf992933391 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,5 @@ +jetty-9.4.10-SNAPSHOT + jetty-9.4.9.v20180320 - 20 March 2018 + 347 Avoid sending request using a connection that is idle timing out + 1416 GzipHandler generated ETag suffix has problems with If-Match header diff --git a/aggregates/jetty-all-compact3/pom.xml b/aggregates/jetty-all-compact3/pom.xml index 555c98741e8..c12e028dc5f 100644 --- a/aggregates/jetty-all-compact3/pom.xml +++ b/aggregates/jetty-all-compact3/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index 1b37c201dab..ceb4083ea8b 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index 527b3f7d74e..a1ab5358c27 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 apache-jsp diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index 490602ba3f2..e70296fff4a 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 apache-jstl diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index 8858314f30c..379f98494d6 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 018760087e8..0e8d8ae1e6f 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index 33b2bbc765f..ac3ebcadb5b 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index 9223d75ebef..c7eba48e688 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 11fc937e12d..0a3d061e799 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml org.eclipse.jetty.examples diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index e5aabd618ca..42538e42ac5 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml index db49d7d0e92..ba3283adb5d 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml index fc57d37f65b..e614bf87b45 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml +++ b/jetty-alpn/jetty-alpn-conscrypt-server/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index c9e4bc6ef16..105690ebca6 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index eed95926bd4..b33daf0e8a5 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml index f80cce3cc14..6b37ebee43d 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml index 7dd11b299a7..c9dda63e2e0 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml +++ b/jetty-alpn/jetty-alpn-openjdk8-server/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index da584d670ab..d5fd398857a 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index 01b869699a3..7777d36dc9a 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 35353b71852..ffa4dd80b8d 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-annotations diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index b2d33ff7efa..69769fba84d 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 2ddb83bbc90..a04d3a5dbb0 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty 4.0.0 jetty-bom - 9.4.9.v20180320 + 9.4.10-SNAPSHOT Jetty :: Bom Jetty BOM artifact http://www.eclipse.org/jetty @@ -94,331 +94,331 @@ org.eclipse.jetty apache-jsp - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty apache-jstl - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-java-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-java-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-openjdk8-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-openjdk8-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-conscrypt-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-conscrypt-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-alpn-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-annotations - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-ant - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.cdi cdi-core - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.cdi cdi-servlet - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-continuation - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-deploy - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-distribution - 9.4.9.v20180320 + 9.4.10-SNAPSHOT zip org.eclipse.jetty jetty-distribution - 9.4.9.v20180320 + 9.4.10-SNAPSHOT tar.gz org.eclipse.jetty.fcgi fcgi-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.fcgi fcgi-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.gcloud jetty-gcloud-session-manager - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-home - 9.4.9.v20180320 + 9.4.10-SNAPSHOT zip org.eclipse.jetty jetty-home - 9.4.9.v20180320 + 9.4.10-SNAPSHOT tar.gz org.eclipse.jetty jetty-http - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.http2 http2-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.http2 http2-common - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.http2 http2-hpack - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.http2 http2-http-client-transport - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.http2 http2-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-http-spi - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-infinispan - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-hazelcast - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-io - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-jaas - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-jaspi - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-jmx - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-jndi - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.memcached jetty-memcached-sessions - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-nosql - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot-jsp - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.osgi jetty-osgi-boot-warurl - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.osgi jetty-httpservice - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-plus - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-proxy - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-quickstart - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-rewrite - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-security - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-servlet - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-servlets - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-spring - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-unixsocket - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-util - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-util-ajax - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-webapp - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-client-impl - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket javax-websocket-server-impl - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket websocket-api - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket websocket-client - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket websocket-common - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket websocket-server - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty.websocket websocket-servlet - 9.4.9.v20180320 + 9.4.10-SNAPSHOT org.eclipse.jetty jetty-xml - 9.4.9.v20180320 + 9.4.10-SNAPSHOT diff --git a/jetty-cdi/cdi-2/pom.xml b/jetty-cdi/cdi-2/pom.xml index 6389f971d30..fc7311b4247 100644 --- a/jetty-cdi/cdi-2/pom.xml +++ b/jetty-cdi/cdi-2/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 cdi-2 diff --git a/jetty-cdi/cdi-core/pom.xml b/jetty-cdi/cdi-core/pom.xml index a9cad873db0..b32a000bbd4 100644 --- a/jetty-cdi/cdi-core/pom.xml +++ b/jetty-cdi/cdi-core/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 cdi-core diff --git a/jetty-cdi/cdi-full-servlet/pom.xml b/jetty-cdi/cdi-full-servlet/pom.xml index 879690a1cc1..8f9513aadfe 100644 --- a/jetty-cdi/cdi-full-servlet/pom.xml +++ b/jetty-cdi/cdi-full-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 cdi-full-servlet diff --git a/jetty-cdi/cdi-servlet/pom.xml b/jetty-cdi/cdi-servlet/pom.xml index 9c1e1f17d3d..07052968677 100644 --- a/jetty-cdi/cdi-servlet/pom.xml +++ b/jetty-cdi/cdi-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 cdi-servlet diff --git a/jetty-cdi/cdi-websocket/pom.xml b/jetty-cdi/cdi-websocket/pom.xml index 6c5e96071c2..8766711968a 100644 --- a/jetty-cdi/cdi-websocket/pom.xml +++ b/jetty-cdi/cdi-websocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 cdi-websocket diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index 01935f5301b..57aad9962f7 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 org.eclipse.jetty.cdi diff --git a/jetty-cdi/test-cdi-webapp/pom.xml b/jetty-cdi/test-cdi-webapp/pom.xml index d49215a3392..34b8bcfbb44 100644 --- a/jetty-cdi/test-cdi-webapp/pom.xml +++ b/jetty-cdi/test-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 test-cdi-webapp diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index 634e5024f06..c4916788198 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index 020c1996e4e..66fb726535b 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 845a0949e0d..b938e5cbec6 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 7a4986a2064..12d05af28f1 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index b4333b1ff60..be6d3c34ac1 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT jetty-documentation Jetty :: Documentation diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index e35a1124c65..9d8d5a92032 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index ef2329caed5..ca16ba32c4e 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 5a62941224e..67efe339bf9 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index 9b3557b2b5b..4267b9acd2b 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 4cd36c435cc..5858d879412 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 3168dede162..98b9f812bd5 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index c56283b6756..2c8233342fb 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-home diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index e75257de189..9276e5d0a5a 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 556023bfe3b..20370e45b77 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-http diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml index d5c8da871ca..474f4cb4499 100644 --- a/jetty-http2/http2-alpn-tests/pom.xml +++ b/jetty-http2/http2-alpn-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 83a139a8876..14d18446266 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 33c8dd3d494..378d17c47e6 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 985dd6c2535..879d4b0f099 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index d40525ffc1a..918f81a61b1 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index c8542c52987..5e2e1410971 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 83d0d79ba84..e7225bd139d 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index d15763a6826..aaf3b4b8db4 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-infinispan diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index 60c0d32c79f..7dfeb37f7f2 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -2,7 +2,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 9ee0073e67c..d1f8c65c10a 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-jaas diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 60fbb17edd1..7286039ea04 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index cb539af5f9b..dba6053c37c 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 3b0f2679289..8303baf2f66 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-jndi diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 9e74d4aa9dc..29b842bad83 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 1ece9440739..0361181500f 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-maven-plugin diff --git a/jetty-memcached/jetty-memcached-sessions/pom.xml b/jetty-memcached/jetty-memcached-sessions/pom.xml index 4c7a46391c1..6cfedf22d2e 100644 --- a/jetty-memcached/jetty-memcached-sessions/pom.xml +++ b/jetty-memcached/jetty-memcached-sessions/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.memcached memcached-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-memcached/pom.xml b/jetty-memcached/pom.xml index 85cbf738c9f..9bc6ce5afa7 100644 --- a/jetty-memcached/pom.xml +++ b/jetty-memcached/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 76bf6179c6c..e0f26a52079 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-nosql diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index d1b9e0e1d7b..45416caaa5a 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-osgi-alpn diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index dc00a45b1a8..67d38349569 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index a191fb6cd1a..5ffcf5064a6 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index 01330595c6c..362cf816d09 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 08e6e4e23b0..fa6248c2784 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index 442c7829add..997148a5b7e 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 03ab8a61c74..1232b165c1c 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index 5fc0fd73188..094df02ac14 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-server/pom.xml b/jetty-osgi/test-jetty-osgi-server/pom.xml index 89b6285c57e..d18e197d0c6 100644 --- a/jetty-osgi/test-jetty-osgi-server/pom.xml +++ b/jetty-osgi/test-jetty-osgi-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index bf0fb272b40..7e864e5909a 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 39dc85d56d9..9e0289909fd 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 3d91da34782..6e6cfce27df 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-plus diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index 53d6a14033f..a6b33bd73f0 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-proxy diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index a2dc9cc8437..944729c57bf 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 org.eclipse.jetty diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 7a313a9f57d..322b5f3505e 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-rewrite diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 99fbd43a868..f453d05084f 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index f3f818d0baf..f72821c49e6 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index ad34db3b893..47536d32e76 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index 726ca18158f..79951eee943 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index c4b9c016b12..b7a076e51be 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-servlets diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index db4b19c0e46..be52a191c4a 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-spring diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index f472de10644..f7276c59bc4 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-start diff --git a/jetty-unixsocket/pom.xml b/jetty-unixsocket/pom.xml index dc6216625aa..48040450aec 100644 --- a/jetty-unixsocket/pom.xml +++ b/jetty-unixsocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-unixsocket diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 7c81d74e1f8..c215c0d143f 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 39ae3fc9b10..5813e02d52b 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index ab386240e10..e62cac02439 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-webapp diff --git a/jetty-websocket/javax-websocket-client-impl/pom.xml b/jetty-websocket/javax-websocket-client-impl/pom.xml index 282ee1b5c16..7f99e781abd 100644 --- a/jetty-websocket/javax-websocket-client-impl/pom.xml +++ b/jetty-websocket/javax-websocket-client-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-server-impl/pom.xml b/jetty-websocket/javax-websocket-server-impl/pom.xml index c55c7de509e..79394cccb9f 100644 --- a/jetty-websocket/javax-websocket-server-impl/pom.xml +++ b/jetty-websocket/javax-websocket-server-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 7e7b7f724ba..f00ab8feb75 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml index b8be92436af..dfbc15fd5a4 100644 --- a/jetty-websocket/websocket-api/pom.xml +++ b/jetty-websocket/websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index 9f32d1e2764..24b13f22219 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index c3ec7c70926..03876342b28 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml index 8359f6d8987..4c83c0df631 100644 --- a/jetty-websocket/websocket-server/pom.xml +++ b/jetty-websocket/websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index 0b30ff744e0..964ecc6d33a 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index 7182985a3ce..15cefddcaab 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index eafc52c5988..808c4cecab6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT Jetty :: Project The Eclipse Jetty Project pom diff --git a/tests/pom.xml b/tests/pom.xml index 34d0d05e5b9..aec4748f54b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml index aeb5b0136d5..ab068242280 100644 --- a/tests/test-continuation/pom.xml +++ b/tests/test-continuation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index 8a263d14ecf..3693d3a3ff7 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 18c9e5f7366..ae08b31ae15 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index f15bad978c3..ef12e9069f9 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 09c501a933e..0419ab414d2 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index dc2b495041e..053dd470020 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 09021de8ce6..f6c407a671e 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 287eea690b3..6901d7af87e 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 40159078dc1..5f420cc4d76 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml index d01ba7d81c4..2398cbb4e2d 100644 --- a/tests/test-sessions/test-file-sessions/pom.xml +++ b/tests/test-sessions/test-file-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-file-sessions Jetty Tests :: Sessions :: File diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index 52bf3f58fb2..916e05ac4bf 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index 9d91e357545..a754d6bac9b 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-hash-sessions Jetty Tests :: Sessions :: Hash diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index 0846d8de7c2..13c9cc376f9 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index 9a8b413d88a..d0a7d14009c 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index a970e339783..d133e3d450a 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-memcached-sessions/pom.xml b/tests/test-sessions/test-memcached-sessions/pom.xml index c1b48e31463..12a21c5486d 100644 --- a/tests/test-sessions/test-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-memcached-sessions Jetty Tests :: Sessions :: Memcached diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index f7d71778760..b6db6e4f89e 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 0e314d0dbb5..9e204f3c14b 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 1d6e6823b4b..4c1f148ccd1 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-http2-webapp/pom.xml b/tests/test-webapps/test-http2-webapp/pom.xml index 53fb7544ebd..d28e48437bc 100644 --- a/tests/test-webapps/test-http2-webapp/pom.xml +++ b/tests/test-webapps/test-http2-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT 4.0.0 diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index ee39ccbbdc1..48609e4e91c 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index d5181e6c27e..d97db564d4e 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index 41b86785398..0725054c4ab 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index 070ed63da8c..b8adfdb0713 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index 7fad1c69e67..a71110a51df 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index 2cbcb0ae9fd..2462a879138 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index 5c829e85a39..8e975a2f1bd 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index 9c8f47c965b..2c505050276 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 212453df575..86b54cb965f 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 32cea24d9e0..6e8d92d01d3 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.4.9.v20180320 + 9.4.10-SNAPSHOT test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 From 9c68b141ba692256681bd205550117bed6bbf8fd Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 20 Mar 2018 09:30:31 -0500 Subject: [PATCH 82/87] Issue #2361 - CachingWebAppClassLoader using cache properly Signed-off-by: Joakim Erdfelt --- .../eclipse/jetty/webapp/CachingWebAppClassLoader.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java index 569068ca5ed..02ce7a33e58 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/CachingWebAppClassLoader.java @@ -64,23 +64,26 @@ public class CachingWebAppClassLoader extends WebAppClassLoader } URL url = _cache.get(name); - - if (name==null) + + if (url == null) { + // Not found in cache, try parent url = super.getResource(name); if (url==null) { + // Still not found, cache the not-found result if (LOG.isDebugEnabled()) LOG.debug("Caching not found resource {}",name); _notFound.add(name); } else { + // Cache the new result _cache.putIfAbsent(name,url); } } - + return url; } From ad3035385a5366f3c7db743805ae2bc906866205 Mon Sep 17 00:00:00 2001 From: WalkerWatch Date: Tue, 20 Mar 2018 11:23:40 -0400 Subject: [PATCH 83/87] Updated Conscrypt documentation to note it works with client. Provided links to server and client examples. Resolves #1830 --- .../asciidoc/configuring/connectors/configuring-ssl.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc index 14534ce8886..41408190c55 100644 --- a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc +++ b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc @@ -719,10 +719,10 @@ This is _not_ a recommended usage. ____ [[conscrypt]] -===== Conscrypt SSL +==== Conscrypt SSL -Jetty also includes support for Google's https://github.com/google/conscrypt/[Conscrypt SSL], which is built on their fork of https://www.openssl.org/[OpenSSL], https://boringssl.googlesource.com/boringssl/[BoringSSL]. -Implementing Conscrypt is very straightforward process - simply instantiate an instance of Conscrypt's `OpenSSLProvider` and set `Conscrypt` as a provider for Jetty's `SslContextFactory`: +Jetty includes support for Google's https://github.com/google/conscrypt/[Conscrypt SSL], which is built on their fork of https://www.openssl.org/[OpenSSL], https://boringssl.googlesource.com/boringssl/[BoringSSL]. +Implementing Conscrypt for the link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2Server.java[server] or link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java[client] is very straightforward process - simply instantiate an instance of Conscrypt's `OpenSSLProvider` and set `Conscrypt` as a provider for Jetty's `SslContextFactory`: [source, java, subs="{sub-order}"] ---- From 6f14b22a9267657905954bbf30e98e83f922e301 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 21 Mar 2018 17:26:09 +1000 Subject: [PATCH 84/87] jacoco fixed for jdk 10 Signed-off-by: olivier lamy --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1b0edd14a0..931d7d5baa9 100644 --- a/pom.xml +++ b/pom.xml @@ -1015,12 +1015,13 @@ + org.jacoco jacoco-maven-plugin 0.8.1-SNAPSHOT - true + false From 5286fb808164a79fab6572f18b8cc520383a32f0 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Wed, 21 Mar 2018 21:11:16 +1000 Subject: [PATCH 85/87] [WIP] add it test for jspc plugin so we can test it with jdk10 (#2363) * add it test for jspc plugin so we can test it with jdk10 Signed-off-by: olivier lamy * record maven invoker results Signed-off-by: olivier lamy * seems to be require as a dependency Signed-off-by: olivier lamy * no need of install Signed-off-by: olivier lamy * remove invoker as it do not support well parallel Signed-off-by: olivier lamy --- Jenkinsfile | 1 + jetty-jspc-maven-plugin/pom.xml | 46 +++++++++++++++++++ jetty-jspc-maven-plugin/src/it/settings.xml | 36 +++++++++++++++ .../src/it/simple-jsp-fail/invoker.properties | 3 ++ .../src/it/simple-jsp-fail/pom.xml | 43 +++++++++++++++++ .../src/it/simple-jsp-fail/postbuild.groovy | 3 ++ .../it/simple-jsp-fail/src/main/jsp/foo.jsp | 23 ++++++++++ .../src/it/simple-jsp/invoker.properties | 2 + .../src/it/simple-jsp/pom.xml | 39 ++++++++++++++++ .../src/it/simple-jsp/postbuild.groovy | 3 ++ .../src/it/simple-jsp/src/main/webapp/foo.jsp | 23 ++++++++++ jetty-maven-plugin/pom.xml | 13 ------ pom.xml | 5 ++ 13 files changed, 227 insertions(+), 13 deletions(-) create mode 100644 jetty-jspc-maven-plugin/src/it/settings.xml create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp-fail/invoker.properties create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp-fail/pom.xml create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp-fail/postbuild.groovy create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp-fail/src/main/jsp/foo.jsp create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp/invoker.properties create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp/pom.xml create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp/postbuild.groovy create mode 100644 jetty-jspc-maven-plugin/src/it/simple-jsp/src/main/webapp/foo.jsp diff --git a/Jenkinsfile b/Jenkinsfile index 57685b5fda3..d24aac9ba18 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -85,6 +85,7 @@ def getFullBuild(jdk, os) { maven: 'maven3', jdk: "$jdk", publisherStrategy: 'EXPLICIT', + //options: [invokerPublisher(disabled: false)], globalMavenSettingsConfig: 'oss-settings.xml', mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") { // diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index a67d3f7eda9..f74998db1cb 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -10,6 +10,7 @@ Jetty :: Jetty JSPC Maven Plugin ${project.groupId}.jspc.plugin + false @@ -96,6 +97,12 @@ apache-jstl ${project.version} + + org.eclipse.jetty + jetty-servlets + ${project.version} + test + @@ -120,4 +127,43 @@ + + + run-its + + + + org.apache.maven.plugins + maven-invoker-plugin + + + integration-test + + integration-test + verify + + + + + ${it.debug} + true + src/it + ${project.build.directory}/it + + */pom.xml + + ${project.build.directory}/local-repo + src/it/settings.xml + + ${surefireVersion} + + + clean + + + + + + + diff --git a/jetty-jspc-maven-plugin/src/it/settings.xml b/jetty-jspc-maven-plugin/src/it/settings.xml new file mode 100644 index 00000000000..d64bdb89034 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/settings.xml @@ -0,0 +1,36 @@ + + + + + + it-repo + + true + + + + local.central + @localRepositoryUrl@ + + true + + + true + + + + + + local.central + @localRepositoryUrl@ + + true + + + true + + + + + + diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/invoker.properties b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/invoker.properties new file mode 100644 index 00000000000..8a7cae8ef84 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/invoker.properties @@ -0,0 +1,3 @@ +invoker.goals = test -fae +invoker.buildResult = failure +invoker.debug = true diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/pom.xml b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/pom.xml new file mode 100644 index 00000000000..f6c1416e8e8 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + org.eclipse.jetty.its.jspc + simple-jsp-fail + 0.0.1-SNAPSHOT + pom + + Jetty :: Simple Jsp Fail + + + UTF-8 + UTF-8 + 1.8 + 3.0.0 + @project.version@ + + + + + + + org.eclipse.jetty + jetty-jspc-maven-plugin + ${jetty.version} + + + + jspc + + compile + + src/main/jsp + + + + + + + + diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/postbuild.groovy b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/postbuild.groovy new file mode 100644 index 00000000000..f7e5d5e8bc1 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/postbuild.groovy @@ -0,0 +1,3 @@ + + +System.out.println( "running postbuild.groovy" ) diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/src/main/jsp/foo.jsp b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/src/main/jsp/foo.jsp new file mode 100644 index 00000000000..00b636ccd93 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp-fail/src/main/jsp/foo.jsp @@ -0,0 +1,23 @@ + +<%@ page import="java.util.Enumeration" %> + +

    JSP Dump

    + + + + + + +<% + Enumeration e =request.getParameterNames(); + while(e.hasMoreElements()) + { + String name = (String)e.nextElement(); +%> + + + +<% } %> + +
    Request URI:<%= request.getFoo() %>
    ServletPath:<%= request.getServletPath() %>
    PathInfo:<%= request.getPathInfo() %>
    getParameter("<%= name %>")<%= request.getParameter(name) %>
    + diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp/invoker.properties b/jetty-jspc-maven-plugin/src/it/simple-jsp/invoker.properties new file mode 100644 index 00000000000..df6cbf2d0bc --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = test -fae +invoker.debug = true diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp/pom.xml b/jetty-jspc-maven-plugin/src/it/simple-jsp/pom.xml new file mode 100644 index 00000000000..5b1bb09a31b --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + org.eclipse.jetty.its.jspc + simple-jsp + 0.0.1-SNAPSHOT + pom + + Jetty :: Simple Jsp + + + UTF-8 + UTF-8 + 1.8 + @project.version@ + + + + + + + org.eclipse.jetty + jetty-jspc-maven-plugin + ${jetty.version} + + + + jspc + + compile + + + + + + + diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp/postbuild.groovy b/jetty-jspc-maven-plugin/src/it/simple-jsp/postbuild.groovy new file mode 100644 index 00000000000..f7e5d5e8bc1 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp/postbuild.groovy @@ -0,0 +1,3 @@ + + +System.out.println( "running postbuild.groovy" ) diff --git a/jetty-jspc-maven-plugin/src/it/simple-jsp/src/main/webapp/foo.jsp b/jetty-jspc-maven-plugin/src/it/simple-jsp/src/main/webapp/foo.jsp new file mode 100644 index 00000000000..fb73b0b0002 --- /dev/null +++ b/jetty-jspc-maven-plugin/src/it/simple-jsp/src/main/webapp/foo.jsp @@ -0,0 +1,23 @@ + +<%@ page import="java.util.Enumeration" %> + +

    JSP Dump

    + + + + + + +<% + Enumeration e =request.getParameterNames(); + while(e.hasMoreElements()) + { + String name = (String)e.nextElement(); +%> + + + +<% } %> + +
    Request URI:<%= request.getRequestURI() %>
    ServletPath:<%= request.getServletPath() %>
    PathInfo:<%= request.getPathInfo() %>
    getParameter("<%= name %>")<%= request.getParameter(name) %>
    + diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 0317e5c6ffc..4b9a73fdcf7 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -211,7 +211,6 @@ org.apache.maven.plugins maven-invoker-plugin - 3.0.1 integration-test @@ -265,18 +264,6 @@
    - - - apache.snaphots - https://repository.apache.org/content/repositories/snapshots - - false - - - true - - - diff --git a/pom.xml b/pom.xml index 931d7d5baa9..9a6370a3196 100644 --- a/pom.xml +++ b/pom.xml @@ -442,6 +442,11 @@ maven-failsafe-plugin ${surefireVersion} + + org.apache.maven.plugins + maven-invoker-plugin + 3.0.1 + org.apache.maven.plugins maven-jar-plugin From 8251ed5a128b5093ee32f0df74eb8737c151a144 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 21 Mar 2018 16:25:18 +0100 Subject: [PATCH 86/87] Fixes #2311 - TimeoutException when server sends unexpected content. (#2324) Now exiting the parse loop when the response is complete; if there are bytes remaining in the buffer, then it's cleared out. Signed-off-by: Simone Bordet --- .../client/http/HttpReceiverOverHTTP.java | 24 +++++-- .../eclipse/jetty/client/HttpClientTest.java | 64 +++++++++++++++++++ .../HttpClientTransportOverHTTP2Test.java | 29 +++++++++ 3 files changed, 112 insertions(+), 5 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java index 6886a39b230..bdae896e13b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java @@ -42,6 +42,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res private final HttpParser parser; private ByteBuffer buffer; private boolean shutdown; + private boolean complete; public HttpReceiverOverHTTP(HttpChannelOverHTTP channel) { @@ -168,13 +169,22 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res { while (true) { - // Must parse even if the buffer is fully consumed, to allow the - // parser to advance from asynchronous content to response complete. boolean handle = parser.parseNext(buffer); + boolean complete = this.complete; + this.complete = false; if (LOG.isDebugEnabled()) LOG.debug("Parsed {}, remaining {} {}", handle, buffer.remaining(), parser); - if (handle || !buffer.hasRemaining()) - return handle; + if (handle) + return true; + if (!buffer.hasRemaining()) + return false; + if (complete) + { + if (LOG.isDebugEnabled()) + LOG.debug("Discarding unexpected content after response: {}", BufferUtil.toDetailString(buffer)); + BufferUtil.clear(buffer); + return false; + } } } @@ -298,11 +308,15 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res if (exchange == null) return false; + int status = exchange.getResponse().getStatus(); + + if (status != HttpStatus.CONTINUE_100) + complete = true; + boolean proceed = responseSuccess(exchange); if (!proceed) return true; - int status = exchange.getResponse().getStatus(); if (status == HttpStatus.SWITCHING_PROTOCOLS_101) return true; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java index 220408a58fa..a363f90438f 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java @@ -1648,6 +1648,70 @@ public class HttpClientTest extends AbstractHttpClientServerTest Assert.assertEquals(200, response.getStatus()); } + @Test + public void test204WithContent() throws Exception + { + // This test only works with clear-text HTTP. + Assume.assumeTrue(sslContextFactory == null); + + try (ServerSocket server = new ServerSocket(0)) + { + startClient(); + client.setMaxConnectionsPerDestination(1); + int idleTimeout = 2000; + client.setIdleTimeout(idleTimeout); + + Request request = client.newRequest("localhost", server.getLocalPort()) + .scheme(scheme) + .timeout(5, TimeUnit.SECONDS); + FutureResponseListener listener = new FutureResponseListener(request); + request.send(listener); + + try (Socket socket = server.accept()) + { + socket.setSoTimeout(idleTimeout / 2); + + InputStream input = socket.getInputStream(); + consume(input, false); + + // Send a bad response. + String httpResponse = "" + + "HTTP/1.1 204 No Content\r\n" + + "\r\n" + + "No Content"; + OutputStream output = socket.getOutputStream(); + output.write(httpResponse.getBytes(StandardCharsets.UTF_8)); + output.flush(); + + ContentResponse response = listener.get(5, TimeUnit.SECONDS); + Assert.assertEquals(204, response.getStatus()); + + byte[] responseContent = response.getContent(); + Assert.assertNotNull(responseContent); + Assert.assertEquals(0, responseContent.length); + + // Send another request to verify we have handled the wrong response correctly. + request = client.newRequest("localhost", server.getLocalPort()) + .scheme(scheme) + .timeout(5, TimeUnit.SECONDS); + listener = new FutureResponseListener(request); + request.send(listener); + + consume(input, false); + + httpResponse = "" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "\r\n"; + output.write(httpResponse.getBytes(StandardCharsets.UTF_8)); + output.flush(); + + response = listener.get(5, TimeUnit.SECONDS); + Assert.assertEquals(200, response.getStatus()); + } + } + } + private void assertCopyRequest(Request original) { Request copy = client.copyRequest((HttpRequest) original, original.getURI()); diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java index 4504744cf5c..e08ee60b539 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java @@ -25,6 +25,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -534,6 +535,34 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest } } + @Test + public void test204WithContent() throws Exception + { + byte[] bytes = "No Content".getBytes(StandardCharsets.UTF_8); + start(new ServerSessionListener.Adapter() + { + @Override + public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) + { + int streamId = stream.getId(); + MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.NO_CONTENT_204, new HttpFields()); + HeadersFrame responseFrame = new HeadersFrame(streamId, response, null, false); + Callback.Completable callback = new Callback.Completable(); + stream.headers(responseFrame, callback); + callback.thenRun(() -> stream.data(new DataFrame(streamId, ByteBuffer.wrap(bytes), true), Callback.NOOP)); + return null; + } + }); + + ContentResponse response = client.newRequest("localhost", connector.getLocalPort()) + .timeout(5, TimeUnit.SECONDS) + .send(); + + Assert.assertEquals(HttpStatus.NO_CONTENT_204, response.getStatus()); + // No logic on the client to discard content for no-content status codes. + Assert.assertArrayEquals(bytes, response.getContent()); + } + @Ignore @Test public void testExternalServer() throws Exception From e651d2d69b3dcb29afbae684010cd5a5aaff5c08 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 21 Mar 2018 16:29:30 +0100 Subject: [PATCH 87/87] Fixes #2350 - Support multiplexing in RoundRobinConnectionPool. (#2352) Introduced ConnectionPool.Multiplexable for connection pools that support multiplexing. Reworked RoundRobinConnectionPool to support multiplexing. Moved tests to test RoundRobinConnectionPool with both HTTP/1.1 and HTTP/2. Signed-off-by: Simone Bordet --- .../eclipse/jetty/client/ConnectionPool.java | 16 ++ .../org/eclipse/jetty/client/HttpChannel.java | 10 +- .../jetty/client/MultiplexConnectionPool.java | 4 +- .../client/MultiplexHttpDestination.java | 8 +- .../client/RoundRobinConnectionPool.java | 75 ++++--- .../client/RoundRobinConnectionPoolTest.java | 99 ---------- .../jetty/http/client/AbstractTest.java | 4 +- .../client/RoundRobinConnectionPoolTest.java | 185 ++++++++++++++++++ 8 files changed, 268 insertions(+), 133 deletions(-) delete mode 100644 jetty-client/src/test/java/org/eclipse/jetty/client/RoundRobinConnectionPoolTest.java create mode 100644 tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java index 57aa3d66917..d2895b64fd8 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java @@ -91,4 +91,20 @@ public interface ConnectionPool extends Closeable */ ConnectionPool newConnectionPool(HttpDestination destination); } + + /** + * Marks a connection pool as supporting multiplexed connections. + */ + interface Multiplexable + { + /** + * @return the max number of requests multiplexable on a single connection + */ + int getMaxMultiplex(); + + /** + * @param maxMultiplex the max number of requests multiplexable on a single connection + */ + void setMaxMultiplex(int maxMultiplex); + } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java index 6d7f84b5304..37230b902ec 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpChannel.java @@ -70,10 +70,14 @@ public abstract class HttpChannel } if (abort) + { exchange.getRequest().abort(new UnsupportedOperationException("Pipelined requests not supported")); - - if (LOG.isDebugEnabled()) - LOG.debug("{} associated {} to {}", exchange, result, this); + } + else + { + if (LOG.isDebugEnabled()) + LOG.debug("{} associated {} to {}", exchange, result, this); + } return result; } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java index 6f2f73ad708..179d66e9ca3 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java @@ -36,7 +36,7 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Sweeper; -public class MultiplexConnectionPool extends AbstractConnectionPool implements Sweeper.Sweepable +public class MultiplexConnectionPool extends AbstractConnectionPool implements ConnectionPool.Multiplexable, Sweeper.Sweepable { private static final Logger LOG = Log.getLogger(MultiplexConnectionPool.class); @@ -80,6 +80,7 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements S lock.unlock(); } + @Override public int getMaxMultiplex() { lock(); @@ -93,6 +94,7 @@ public class MultiplexConnectionPool extends AbstractConnectionPool implements S } } + @Override public void setMaxMultiplex(int maxMultiplex) { lock(); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java index ee1ceb30cca..44c264a36cf 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexHttpDestination.java @@ -28,15 +28,15 @@ public abstract class MultiplexHttpDestination extends HttpDestination public int getMaxRequestsPerConnection() { ConnectionPool connectionPool = getConnectionPool(); - if (connectionPool instanceof MultiplexConnectionPool) - return ((MultiplexConnectionPool)connectionPool).getMaxMultiplex(); + if (connectionPool instanceof ConnectionPool.Multiplexable) + return ((ConnectionPool.Multiplexable)connectionPool).getMaxMultiplex(); return 1; } public void setMaxRequestsPerConnection(int maxRequestsPerConnection) { ConnectionPool connectionPool = getConnectionPool(); - if (connectionPool instanceof MultiplexConnectionPool) - ((MultiplexConnectionPool)connectionPool).setMaxMultiplex(maxRequestsPerConnection); + if (connectionPool instanceof ConnectionPool.Multiplexable) + ((ConnectionPool.Multiplexable)connectionPool).setMaxMultiplex(maxRequestsPerConnection); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java b/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java index b33929254f7..f69cbf63eea 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java @@ -29,17 +29,42 @@ import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; @ManagedObject -public class RoundRobinConnectionPool extends AbstractConnectionPool +public class RoundRobinConnectionPool extends AbstractConnectionPool implements ConnectionPool.Multiplexable { private final List entries; + private int maxMultiplex; private int index; public RoundRobinConnectionPool(Destination destination, int maxConnections, Callback requester) + { + this(destination, maxConnections, requester, 1); + } + + public RoundRobinConnectionPool(Destination destination, int maxConnections, Callback requester, int maxMultiplex) { super(destination, maxConnections, requester); entries = new ArrayList<>(maxConnections); for (int i = 0; i < maxConnections; ++i) entries.add(new Entry()); + this.maxMultiplex = maxMultiplex; + } + + @Override + public int getMaxMultiplex() + { + synchronized (this) + { + return maxMultiplex; + } + } + + @Override + public void setMaxMultiplex(int maxMultiplex) + { + synchronized (this) + { + this.maxMultiplex = maxMultiplex; + } } @Override @@ -78,10 +103,10 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool if (entry.connection == null) break; - if (!entry.active) + if (entry.active < getMaxMultiplex()) { - entry.active = true; - entry.used++; + ++entry.active; + ++entry.used; connection = entry.connection; index += offset + 1; if (index >= capacity) @@ -103,7 +128,7 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool for (Entry entry : entries) { if (entry.connection == connection) - return entry.active; + return entry.active > 0; } return false; } @@ -112,56 +137,60 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool @Override public boolean release(Connection connection) { - boolean active = false; + boolean found = false; + boolean idle = false; synchronized (this) { for (Entry entry : entries) { if (entry.connection == connection) { - entry.active = false; - active = true; + found = true; + int active = --entry.active; + idle = active == 0; break; } } } - if (active) - released(connection); - return idle(connection, isClosed()); + if (!found) + return false; + released(connection); + if (idle) + return idle(connection, isClosed()); + return true; } @Override public boolean remove(Connection connection) { - boolean active = false; - boolean removed = false; + boolean found = false; synchronized (this) { for (Entry entry : entries) { if (entry.connection == connection) { - active = entry.active; + found = true; entry.reset(); - removed = true; break; } } } - if (active) + if (found) + { released(connection); - if (removed) removed(connection); - return removed; + } + return found; } @Override public void dump(Appendable out, String indent) throws IOException { - List connections = new ArrayList<>(); + List connections; synchronized (this) { - connections.addAll(entries); + connections = new ArrayList<>(entries); } ContainerLifeCycle.dumpObject(out, this); ContainerLifeCycle.dump(out, indent, connections); @@ -179,7 +208,7 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool if (entry.connection != null) { ++present; - if (entry.active) + if (entry.active > 0) ++active; } } @@ -196,13 +225,13 @@ public class RoundRobinConnectionPool extends AbstractConnectionPool private static class Entry { private Connection connection; - private boolean active; + private int active; private long used; private void reset() { connection = null; - active = false; + active = 0; used = 0; } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/RoundRobinConnectionPoolTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/RoundRobinConnectionPoolTest.java deleted file mode 100644 index ac8a1ea9a25..00000000000 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/RoundRobinConnectionPoolTest.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 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.client; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.hamcrest.Matchers; -import org.junit.Assert; -import org.junit.Test; - -public class RoundRobinConnectionPoolTest extends AbstractHttpClientServerTest -{ - public RoundRobinConnectionPoolTest(SslContextFactory sslContextFactory) - { - super(sslContextFactory); - } - - @Test - public void testRoundRobin() throws Exception - { - AtomicBoolean record = new AtomicBoolean(); - List remotePorts = new ArrayList<>(); - start(new EmptyServerHandler() - { - @Override - protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - if (record.get()) - remotePorts.add(request.getRemotePort()); - } - }); - - int maxConnections = 3; - client.getTransport().setConnectionPoolFactory(destination -> new RoundRobinConnectionPool(destination, maxConnections, destination)); - - // Prime the connections, so that they are all opened - // before we actually test the round robin behavior. - String host = "localhost"; - int port = connector.getLocalPort(); - for (int i = 0; i < maxConnections; ++i) - { - ContentResponse response = client.newRequest(host, port) - .scheme(scheme) - .timeout(5, TimeUnit.SECONDS) - .send(); - Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); - } - - record.set(true); - int requests = 2 * maxConnections - 1; - for (int i = 0; i < requests; ++i) - { - ContentResponse response = client.newRequest(host, port) - .scheme(scheme) - .timeout(5, TimeUnit.SECONDS) - .send(); - Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); - } - - Assert.assertThat(remotePorts.size(), Matchers.equalTo(requests)); - for (int i = 0; i < requests; ++i) - { - int base = i % maxConnections; - int expected = remotePorts.get(base); - int candidate = remotePorts.get(i); - Assert.assertThat(client.dump() + System.lineSeparator() + remotePorts.toString(), expected, Matchers.equalTo(candidate)); - if (i > 0) - Assert.assertThat(remotePorts.get(i - 1), Matchers.not(Matchers.equalTo(candidate))); - } - } -} diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java index 2a8e6e10e3f..2b49fc678c6 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AbstractTest.java @@ -312,9 +312,7 @@ public abstract class AbstractTest protected String newURI() { if (connector instanceof ServerConnector) - { - return getScheme() + "://localhost:" + ServerConnector.class.cast( connector ).getLocalPort(); - } + return getScheme() + "://localhost:" + ServerConnector.class.cast(connector).getLocalPort(); return getScheme() + "://localhost"; } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java new file mode 100644 index 00000000000..e1c56314d30 --- /dev/null +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java @@ -0,0 +1,185 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.client; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.RoundRobinConnectionPool; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Request; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; + +public class RoundRobinConnectionPoolTest extends AbstractTest +{ + public RoundRobinConnectionPoolTest(Transport transport) + { + super(transport); + } + + @Test + public void testRoundRobin() throws Exception + { + AtomicBoolean record = new AtomicBoolean(); + List remotePorts = new ArrayList<>(); + start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + if (record.get()) + remotePorts.add(request.getRemotePort()); + } + }); + + int maxConnections = 3; + client.getTransport().setConnectionPoolFactory(destination -> new RoundRobinConnectionPool(destination, maxConnections, destination)); + + // Prime the connections, so that they are all opened + // before we actually test the round robin behavior. + for (int i = 0; i < maxConnections; ++i) + { + ContentResponse response = client.newRequest(newURI()) + .timeout(5, TimeUnit.SECONDS) + .send(); + Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); + } + + record.set(true); + int requests = 2 * maxConnections - 1; + for (int i = 0; i < requests; ++i) + { + ContentResponse response = client.newRequest(newURI()) + .timeout(5, TimeUnit.SECONDS) + .send(); + Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); + } + + Assert.assertThat(remotePorts.size(), Matchers.equalTo(requests)); + for (int i = 0; i < requests; ++i) + { + int base = i % maxConnections; + int expected = remotePorts.get(base); + int candidate = remotePorts.get(i); + Assert.assertThat(client.dump() + System.lineSeparator() + remotePorts.toString(), expected, Matchers.equalTo(candidate)); + if (i > 0) + Assert.assertThat(remotePorts.get(i - 1), Matchers.not(Matchers.equalTo(candidate))); + } + } + + @Test + public void testMultiplex() throws Exception + { + int multiplex = 1; + if (transport == Transport.H2C || transport == Transport.H2) + multiplex = 4; + int maxMultiplex = multiplex; + + int maxConnections = 3; + int count = maxConnections * maxMultiplex; + + AtomicBoolean record = new AtomicBoolean(); + List remotePorts = new ArrayList<>(); + AtomicReference requestLatch = new AtomicReference<>(); + CountDownLatch serverLatch = new CountDownLatch(count); + CyclicBarrier barrier = new CyclicBarrier(count + 1); + start(new EmptyServerHandler() + { + @Override + protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + try + { + if (record.get()) + { + remotePorts.add(request.getRemotePort()); + requestLatch.get().countDown(); + serverLatch.countDown(); + barrier.await(); + } + } + catch (Exception x) + { + throw new RuntimeException(x); + } + } + }); + + client.getTransport().setConnectionPoolFactory(destination -> new RoundRobinConnectionPool(destination, maxConnections, destination, maxMultiplex)); + + // Prime the connections, so that they are all opened + // before we actually test the round robin behavior. + for (int i = 0; i < maxConnections; ++i) + { + ContentResponse response = client.newRequest(newURI()) + .timeout(5, TimeUnit.SECONDS) + .send(); + Assert.assertEquals(HttpStatus.OK_200, response.getStatus()); + } + + record.set(true); + CountDownLatch clientLatch = new CountDownLatch(count); + AtomicInteger requests = new AtomicInteger(); + for (int i = 0; i < count; ++i) + { + CountDownLatch latch = new CountDownLatch(1); + requestLatch.set(latch); + client.newRequest(newURI()) + .path("/" + i) + .onRequestQueued(request -> requests.incrementAndGet()) + .onRequestBegin(request -> requests.decrementAndGet()) + .timeout(5, TimeUnit.SECONDS) + .send(result -> + { + if (result.getResponse().getStatus() == HttpStatus.OK_200) + clientLatch.countDown(); + }); + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + + Assert.assertTrue(serverLatch.await(5, TimeUnit.SECONDS)); + Assert.assertEquals(0, requests.get()); + + barrier.await(); + + Assert.assertTrue(clientLatch.await(5, TimeUnit.SECONDS)); + Assert.assertThat(remotePorts.size(), Matchers.equalTo(count)); + for (int i = 0; i < count; ++i) + { + int base = i % maxConnections; + int expected = remotePorts.get(base); + int candidate = remotePorts.get(i); + Assert.assertThat(client.dump() + System.lineSeparator() + remotePorts.toString(), expected, Matchers.equalTo(candidate)); + if (i > 0) + Assert.assertThat(remotePorts.get(i - 1), Matchers.not(Matchers.equalTo(candidate))); + } + } +}