SuccessConsole Output

Skipping 23,271 KB.. Full Log
ou don't want to achieve your goal by other means - WebSocket
         Extension is very powerful and can easily break your application when not used with care or enough expertise.
-        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">WebSocket frame used in ExtendedExtension:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1217">  1 public class Frame {
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">WebSocket frame used in ExtendedExtension:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1265">  1 public class Frame {
   2 
   3     public boolean isFin() { .. }
   4     public boolean isRsv1() { .. }
@@ -1050,7 +1123,7 @@
  29     public Builder maskingKey(int maskingKey) { .. }
  30     public Builder payloadData(byte[] payloadData) { .. }
  31 }</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Frame is immutable, so if you want to create new one, you need to create new builder, modify what you want
-        and build it:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1221">  1 Frame newFrame = Frame.builder(originalFrame).rsv1(true).build();</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Note that there is only one convenience method: isControlFrame. Other information about frame type etc needs
+        and build it:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1269">  1 Frame newFrame = Frame.builder(originalFrame).rsv1(true).build();</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Note that there is only one convenience method: isControlFrame. Other information about frame type etc needs
             to be evaluated directly from opcode, simply because there might not be enough information to get the correct
             outcome or the information itself would not be very useful. For example: opcode 0×00 means continuation frame,
             but you don’t have any chance to get the information about actual type (text or binary) without intercepting
@@ -1060,7 +1133,7 @@
             unanswered ping messages.</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">ExtendedExtension representation needs to be able to handle extension parameter negotiation and actual processing
         of incoming and outgoing frames. It also should be compatible with existing javax.websocket.Extension class, since we
         want to re-use existing registration API and be able to return new extension instance included in response
-        from List&lt;Extension&gt; Session.getNegotiatedExtensions() call. Consider following:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1227">  1 public interface ExtendedExtension extends Extension {
+        from List&lt;Extension&gt; Session.getNegotiatedExtensions() call. Consider following:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1275">  1 public interface ExtendedExtension extends Extension {
   2 
   3     Frame processIncoming(ExtensionContext context, Frame frame);
   4     Frame processOutgoing(ExtensionContext context, Frame frame);
@@ -1095,7 +1168,7 @@
             message content, you need to make sure it is properly encoded in relation to other messages, because encoding/decoding
             process is stateful – remainder after UTF-8 coding is used as input to coding process for next message. If you
             want just test this feature and save yourself some headaches, don’t modify text message content or try binary
-            messages instead.</fo:block><fo:block id="d0e1235"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">ExtendedExtension sample</fo:marker><fo:block font-size="17.28pt">8.6.1. ExtendedExtension sample</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Let’s say we want to create extension which will encrypt and decrypt first byte of every binary message. Assume we have a key (one byte) and our symmetrical cipher will be XOR. (Just for simplicity (a XOR key XOR key) = a, so encrypt() and decrypt() functions are the same).</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1240">  1 public class CryptoExtension implements ExtendedExtension {
+            messages instead.</fo:block><fo:block id="d0e1283"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">ExtendedExtension sample</fo:marker><fo:block font-size="17.28pt">8.6.1. ExtendedExtension sample</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Let’s say we want to create extension which will encrypt and decrypt first byte of every binary message. Assume we have a key (one byte) and our symmetrical cipher will be XOR. (Just for simplicity (a XOR key XOR key) = a, so encrypt() and decrypt() functions are the same).</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1288">  1 public class CryptoExtension implements ExtendedExtension {
   2 
   3     @Override
   4     public Frame processIncoming(ExtensionContext context, Frame frame) {
@@ -1157,7 +1230,7 @@
             implementation. Real world case is usually more complicated.</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Now when we have our CryptoExtension implemented, we want to use it. There is nothing new compared to standard
             WebSocket Java API, feel free to skip this part if you are already familiar with it. Only programmatic version
             will be demonstrated. It is possible to do it for annotated version as well, but it is little bit more complicated
-            on the server side and I want to keep the code as compact as possible.</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Client registration</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1248">  1 ArrayList extensions = new ArrayList();
+            on the server side and I want to keep the code as compact as possible.</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Client registration</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1296">  1 ArrayList extensions = new ArrayList();
   2 extensions.add(new CryptoExtension());
   3 
   4 final ClientEndpointConfig clientConfiguration =
@@ -1170,7 +1243,7 @@
  11     public void onOpen(Session session, EndpointConfig config) {
  12         // ...
  13     }
- 14 }, clientConfiguration, URI.create(/* ... */));</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Server registration:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1252">  1 public class CryptoExtensionApplicationConfig implements ServerApplicationConfig {
+ 14 }, clientConfiguration, URI.create(/* ... */));</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Server registration:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1300">  1 public class CryptoExtensionApplicationConfig implements ServerApplicationConfig {
   2 
   3     @Override
   4     public Set getEndpointConfigs(Set&lt;Class&lt;? extends Endpoint&gt;&gt; endpointClasses) {
@@ -1195,13 +1268,13 @@
  23         // ...
  24     }
  25 }</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">CryptoExtensionApplicationConfig will be found by servlets scanning mechanism and automatically used for
-                application configuration, no need to add anything (or even have) web.xml.</fo:block></fo:block><fo:block id="d0e1256"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Per Message Deflate Extension</fo:marker><fo:block font-size="17.28pt">8.6.2. Per Message Deflate Extension</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">The original goal of whole extension support was to implement Permessage extension as defined in
+                application configuration, no need to add anything (or even have) web.xml.</fo:block></fo:block><fo:block id="d0e1304"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Per Message Deflate Extension</fo:marker><fo:block font-size="17.28pt">8.6.2. Per Message Deflate Extension</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">The original goal of whole extension support was to implement Permessage extension as defined in
                 draft-ietf-hybi-permessage-compression-15 and we were able to achieve that goal. Well, not completely, current
                 implementation ignores parameters. But it seems like it does not matter much, it was tested with Chrome and it
                 works fine. Also it passes newest version of Autobahn test suite, which includes tests for this extension.</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">see PerMessageDeflateExtension.java (compatible with draft-ietf-hybi-permessage-compression-15, autobahn test suite) and
                 XWebKitDeflateExtension.java (compatible with Chrome and Firefox – same as previous, just different extension name)
-                </fo:block></fo:block></fo:block><fo:block id="d0e1263"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client reconnect</fo:marker><fo:block font-size="20.735999999999997pt">8.7. Client reconnect</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">If you need semi-persistent client connection, you can always implement some reconnect logic by yourself,
-        but Tyrus Client offers useful feature which should be much easier to use. See short sample code:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1268">  1 ClientManager client = ClientManager.createClient();
+                </fo:block></fo:block></fo:block><fo:block id="d0e1311"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client reconnect</fo:marker><fo:block font-size="20.735999999999997pt">8.7. Client reconnect</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">If you need semi-persistent client connection, you can always implement some reconnect logic by yourself,
+        but Tyrus Client offers useful feature which should be much easier to use. See short sample code:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1316">  1 ClientManager client = ClientManager.createClient();
   2 ClientManager.ReconnectHandler reconnectHandler = new ClientManager.ReconnectHandler() {
   3 
   4   private int counter = 0;
@@ -1230,12 +1303,587 @@
  27       return false;
  28     }
  29   }
- 30 };
- 31 
- 32 client.getProperties().put(ClientManager.RECONNECT_HANDLER, reconnectHandler);
- 33 
- 34 client.connectToServer(...)</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">As you can see, ReconnectHandler contains two methods, onDisconnect and onConnectFailure. First will be executed
+ 30 
+ 31   @Override
+ 32   public long getDelay() {
+ 33     return 1;
+ 34   }
+ 35 };
+ 36 
+ 37 client.getProperties().put(ClientProperties.RECONNECT_HANDLER, reconnectHandler);
+ 38 
+ 39 client.connectToServer(...)</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">ReconnectHandler contains three methods, onDisconnect, onConnectFailure and getDelay. First will be executed
         whenever @OnClose annotated method (or Endpoint.onClose(..)) is executed on client side - this should happen when
         established connection is lost for any reason. You can find the reason in methods parameter. Other one, called
         onConnectFailure is invoked when client fails to connect to remote endpoint, for example due to temporary network
-        issue or current high server load.</fo:block></fo:block></fo:flow></fo:page-sequence></fo:root>
\ No newline at end of file
+        issue or current high server load. Method getDelay is called after any of previous methods returns <fo:inline font-family="monospace">true</fo:inline>
+        and the returned value will be used to determine delay before next connection attempt. Default value is 5 seconds.</fo:block></fo:block><fo:block id="d0e1323"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client behind proxy</fo:marker><fo:block font-size="20.735999999999997pt">8.8. Client behind proxy</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Tyrus client supports traversing proxies, but it is Tyrus specific feature and its configuration is shown
+            in the following code sample:
+            <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1328">  1 
+  2 ClientManager client = ClientManager.createClient();
+  3 client.getProperties().put(ClientProperties.PROXY_URI, "http://my.proxy.com:80");
+  4             </fo:block>
+            Value is expected to be proxy URI. Protocol part is currently ignored, but must be present.
+        </fo:block></fo:block><fo:block id="d0e1331"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">JDK 7 client</fo:marker><fo:block font-size="20.735999999999997pt">8.9. JDK 7 client</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            As has been said in previous chapters both Tyrus client and server were implemented on top of Grizzly NIO framework.
+            This still remains true, but an alternative Tyrus Websocket client implementation based on Java 7 Asynchronous Channel
+            API has been available since version 1.6. There are two options how to switch between client implementations.
+            If you do not mind using Tyrus specific API, the most straightforward way is to use:
+            <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1336">  1 
+  2 final ClientManager client = ClientManager.createClient(JdkClientContainer.class.getName());
+  3             </fo:block>
+            You just have to make sure that the dependency on JDK client is included in your project:
+            <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1339">
+&lt;dependency&gt;
+  &lt;groupId&gt;org.glassfish.tyrus&lt;/groupId&gt;
+  &lt;artifactId&gt;tyrus-container-jdk-client&lt;/artifactId&gt;
+  &lt;version&gt;1.17&lt;/version&gt;
+&lt;/dependency&gt;
+            </fo:block>
+            Grizzly client is the default option, so creating a client without any parameters will result in Grizzly client being used.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            There is also an option how to use JDK client with the standard Websocket API.
+            <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1344">  1 
+  2 final WebSocketContainer client = ContainerProvider.getWebSocketContainer();
+  3             </fo:block>
+            The code listed above will scan class path for Websocket client implementations. A slight problem with this
+            approach is that if there is more than one client on the classpath, the first one discovered will be used.
+            Therefore if you intend to use JDK client with the standard API, you have to make sure that there is not
+            a Grizzly client on the classpath as it might be used instead.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            The main reason why JDK client has been implemented is that it does not have any extra dependencies
+            except JDK 7 and of course some other Tyrus modules, which makes it considerable more lightweight compared
+            to Tyrus Grizzly client, which requires 1.4 MB of dependencies.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            It is also important to note that the JDK client has been implemented in a way similar to Grizzly client
+            shared container option, which means that there is one thread pool shared among all clients.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Proxy configuration for JDK client is the same as for Grizzly client shown above.
+        </fo:block><fo:block id="d0e1353"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">SSL configuration</fo:marker><fo:block font-size="17.28pt">8.9.1. SSL configuration</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Alike in case of Grizzly client, accessing "wss" URLs will cause Tyrus client to pick up whatever keystore
+                and trust store is actually set for the current JVM instance. However, specifying SSL parameters
+                to be used with JDK client instance is little different from Grizzly client, because Grizzly client supports
+                both
+                <fo:basic-link external-destination="url(https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLEngineConfigurator.html)"><fo:inline>SSLEngineConfigurator</fo:inline></fo:basic-link><fo:inline hyphenate="false"> [<fo:basic-link external-destination="url(https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLEngineConfigurator.html)">https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLEngineConfigurator.html</fo:basic-link>]</fo:inline>
+                end
+                <fo:basic-link external-destination="url(https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLContextConfigurator.html)"><fo:inline>SSLContextConfigurator</fo:inline></fo:basic-link><fo:inline hyphenate="false"> [<fo:basic-link external-destination="url(https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLContextConfigurator.html)">https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLContextConfigurator.html</fo:basic-link>]</fo:inline>
+                from Grizzly project and
+                <fo:basic-link external-destination="url(https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslEngineConfigurator.html)"><fo:inline>SslEngineConfigurator</fo:inline></fo:basic-link><fo:inline hyphenate="false"> [<fo:basic-link external-destination="url(https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslEngineConfigurator.html)">https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslEngineConfigurator.html</fo:basic-link>]</fo:inline>
+                and
+                <fo:basic-link external-destination="url(https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslContextConfigurator.html)"><fo:inline>SslContextConfigurator</fo:inline></fo:basic-link><fo:inline hyphenate="false"> [<fo:basic-link external-destination="url(https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslContextConfigurator.html)">https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslContextConfigurator.html</fo:basic-link>]</fo:inline>
+                from Tyrus project, but JDK client supports only the Tyrus version of these classes.
+                The following code sample shows an example of some SSL parameters configuration for the JDK client:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1370">  1 
+  2 SslContextConfigurator sslContextConfigurator = new SslContextConfigurator();
+  3 sslContextConfigurator.setTrustStoreFile("...");
+  4 sslContextConfigurator.setTrustStorePassword("...");
+  5 sslContextConfigurator.setTrustStoreType("...");
+  6 sslContextConfigurator.setKeyStoreFile("...");
+  7 sslContextConfigurator.setKeyStorePassword("...");
+  8 sslContextConfigurator.setKeyStoreType("...");
+  9 SslEngineConfigurator sslEngineConfigurator = new SslEngineConfigurator(sslContextConfigurator, true, false, false);
+ 10 
+ 11 client.getProperties().put(ClientProperties.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator);
+ 12                 </fo:block>
+            </fo:block></fo:block></fo:block><fo:block id="d0e1373"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Tracing support</fo:marker><fo:block font-size="20.735999999999997pt">8.10. Tracing support</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Apart from logging, Tyrus supports another useful means for debugging and diagnosing a deployed application which will
+            be referred to as tracing on the following lines. Tracing consists of including vital information about handshake
+            handling into a handshake response. The provided information includes among other things an insight into how Tyrus matches
+            handshake request URI against the URI of the deployed endpoints and how the best matching endpoint is selected.
+            The tracing information is included in a handshake response as a content of HTTP headers with
+            <fo:inline font-family="monospace">X-Tyrus-Tracing-</fo:inline> as the header names prefix.
+            All the tracing information will also be available in the server log if the appropriate logging level is set.
+            If it is still unclear, how Tyrus tracing works, please refer to the subsection with title Tracing Examples.
+        </fo:block><fo:block id="d0e1381"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Configuration</fo:marker><fo:block font-size="17.28pt">8.10.1. Configuration</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Tracing support is disabled by default. You can enable it either "globally" for all application handshake requests
+                or selectively per handshake request. The tracing support activation is controlled by setting the
+                <fo:inline font-family="monospace">org.glassfish.tyrus.server.tracingType</fo:inline> configuration property. The property value is expected to be one of the following:
+
+                <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1389"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1390"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>OFF - tracing support is disabled (default value).</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1393"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>ON_DEMAND - tracing support is in a stand-by mode; it is enabled selectively per handshake, via a special
+                            X-Tyrus-Tracing-Accept HTTP header in a handshake request.</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1396"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>ALL - tracing support is enabled for all handshake requests.</fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+
+                The level of detail of the information provided by Tyrus tracing facility - the tracing threshold - can be customized.
+                The tracing threshold can be set at the application level via <fo:inline font-family="monospace">org.glassfish.tyrus.server.tracingThreshold</fo:inline>
+                application configuration property in both Glassfish and Grizzly as will be shown in the following samples,
+                or at a request level, via X-Tyrus-Tracing-Threshold HTTP header in a handshake request. The request-level configuration
+                overrides any application level setting. There are 2 supported levels of detail for Tyrus tracing:
+
+                <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1403"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1404"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>SUMMARY - very basic summary information about handshake processing</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1407"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>TRACE - detailed information about  handshake processing (default threshold value).</fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+            </fo:block><fo:block id="d0e1411"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:block font-size="14.399999999999999pt">8.10.1.1. Global configuration examples</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                        As has been already said, tracing is disabled by default. The following code sample shows, how <fo:inline font-family="monospace">ON_DEMAND</fo:inline> tracing with
+                        level set to <fo:inline font-family="monospace">SUMMARY</fo:inline> can be enabled on Grizzly server:
+                        <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1422">  1 
+  2                             serverProperties.put(TyrusWebSocketEngine.TRACING_TYPE, ON_DEMAND);
+  3                             serverProperties.put(TyrusWebSocketEngine.TRACING_THRESHOLD, SUMMARY);
+  4                         </fo:block>
+                        Similarly <fo:inline font-family="monospace">ALL</fo:inline> tracing with level set to <fo:inline font-family="monospace">TRACE</fo:inline> (the default) can be enabled on Glassfish server in web.xml:
+                        <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1431">  1 &lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  2                 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;
+  3 
+  4     &lt;context-param&gt;
+  5         &lt;param-name&gt;org.glassfish.tyrus.server.tracingType&lt;/param-name&gt;
+  6         &lt;param-value&gt;ALL&lt;/param-value&gt;
+  7     &lt;/context-param&gt;
+  8 &lt;/web-app&gt;</fo:block>
+
+                        It has been also already mentioned that the tracing threshold configured on application level can be overridden per handshake request as
+                        will be shown in the following section.
+                    </fo:block></fo:block><fo:block id="d0e1434"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:block font-size="14.399999999999999pt">8.10.1.2. Configuring tracing via handshake request headers</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                    Whenever the tracing support is active (ON_DEMAND or ALL) you can customize the tracing behaviour by including one or more of the following request HTTP headers
+                    in the individual handshake requests:
+
+                    <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1439"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1440"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>X-Tyrus-Tracing-Accept - used to enable the tracing support for the particular request. It is applied only when the application-level tracing support is configured to
+                                ON_DEMAND mode. The value of the header is not used by the Tyrus tracing facility and as such it can be any arbitrary (even empty) string.</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1443"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>X-Tyrus-Tracing-Threshold - used to override the tracing threshold. Allowed values are: SUMMARY, TRACE.</fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+                </fo:block></fo:block></fo:block><fo:block id="d0e1447"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Tracing Examples</fo:marker><fo:block font-size="17.28pt">8.10.2. Tracing Examples</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                An example of a handshake request to a server in <fo:inline font-family="monospace">ON_DEMAND</fo:inline> tracing mode requesting <fo:inline font-family="monospace">SUMMARY</fo:inline> tracing information:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1458">  1 GET /endpoint/b HTTP/1.1
+  2 Connection: Upgrade
+  3 Host: localhost:8025
+  4 Origin: localhost:8025
+  5 Sec-WebSocket-Key: YrFldD8nhRW+6hJ2K/TMqw==
+  6 Sec-WebSocket-Version: 13
+  7 Upgrade: websocket
+  8 X-Tyrus-Tracing-Accept: Whatever
+  9 X-Tyrus-Tracing-Threshold: SUMMARY</fo:block>
+                An example of a possible response to the request above:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1461">  1 HTTP/1.1 404 Not found
+  2 x-tyrus-tracing-00 : [0 ms] Matching request URI /samples-debug/endpoint/b against /samples-debug/endpoint/{a}/b
+  3 x-tyrus-tracing-01 : [0 ms] URIs /samples-debug/endpoint/b and /samples-debug/endpoint/{a}/b have different length
+  4 x-tyrus-tracing-02 : [0 ms] Matching request URI /samples-debug/endpoint/b against /samples-debug/endpoint/{a}/{b}
+  5 x-tyrus-tracing-03 : [0 ms] URIs /samples-debug/endpoint/b and /samples-debug/endpoint/{a}/{b} have different length
+  6 x-tyrus-tracing-04 : [0 ms] Matching request URI /samples-debug/endpoint/b against /samples-debug/endpoint/a/b
+  7 x-tyrus-tracing-05 : [1 ms] URIs /samples-debug/endpoint/b and /samples-debug/endpoint/a/b have different length
+  8 x-tyrus-tracing-06 : [1 ms] Matching request URI /samples-debug/endpoint/b against /samples-debug/endpoint/a/a
+  9 x-tyrus-tracing-07 : [1 ms] URIs /samples-debug/endpoint/b and /samples-debug/endpoint/a/a have different length
+ 10 x-tyrus-tracing-08 : [1 ms] Matching request URI /samples-debug/endpoint/b against /samples-debug/endpoint/a
+ 11 x-tyrus-tracing-09 : [1 ms] Segment "a" does not match
+ 12 x-tyrus-tracing-10 : [1 ms] Matching request URI /samples-debug/endpoint/b against /samples-debug/endpoint/a/{b}
+ 13 x-tyrus-tracing-11 : [1 ms] URIs /samples-debug/endpoint/b and /samples-debug/endpoint/a/{b} have different length
+ 14 x-tyrus-tracing-12 : [3 ms] Endpoints matched to the request URI: []</fo:block>
+                The time in the square brackets in the sample above is the time since the handshake request has been received.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                An example of a possible handshake response from a server in <fo:inline font-family="monospace">ALL</fo:inline> tracing mode with tracing threshold set to <fo:inline font-family="monospace">TRACE</fo:inline>:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1472">  1 HTTP/1.1 101
+  2 connection: Upgrade
+  3 sec-websocket-accept: C8/QbF4Mx9sX31sihUcnI19yqto=
+  4 upgrade: websocket
+  5 x-tyrus-tracing-00 : [0 ms] Matching request URI /samples-debug/endpoint/a/b against /samples-debug/endpoint/{a}/b
+  6 x-tyrus-tracing-01 : [0 ms] Matching request URI /samples-debug/endpoint/a/b against /samples-debug/endpoint/{a}/{b}
+  7 x-tyrus-tracing-02 : [0 ms] Matching request URI /samples-debug/endpoint/a/b against /samples-debug/endpoint/a/b
+  8 x-tyrus-tracing-03 : [1 ms] Matching request URI /samples-debug/endpoint/a/b against /samples-debug/endpoint/a/a
+  9 x-tyrus-tracing-04 : [1 ms] Segment "a" does not match
+ 10 x-tyrus-tracing-05 : [1 ms] Matching request URI /samples-debug/endpoint/a/b against /samples-debug/endpoint/a
+ 11 x-tyrus-tracing-06 : [1 ms] URIs /samples-debug/endpoint/a/b and /samples-debug/endpoint/a have different length
+ 12 x-tyrus-tracing-07 : [1 ms] Matching request URI /samples-debug/endpoint/a/b against /samples-debug/endpoint/a/{b}
+ 13 x-tyrus-tracing-08 : [3 ms] Choosing better match from /samples-debug/endpoint/{a}/b and /samples-debug/endpoint/a/b
+ 14 x-tyrus-tracing-09 : [3 ms] /samples-debug/endpoint/a/b is an exact match
+ 15 x-tyrus-tracing-10 : [3 ms] Choosing better match from /samples-debug/endpoint/a/{b} and /samples-debug/endpoint/{a}/b
+ 16 x-tyrus-tracing-11 : [3 ms] /samples-debug/endpoint/a/{b} is a  better match, because it has longer exact path
+ 17 x-tyrus-tracing-12 : [3 ms] Choosing better match from /samples-debug/endpoint/a/{b} and /samples-debug/endpoint/{a}/b
+ 18 x-tyrus-tracing-13 : [3 ms] /samples-debug/endpoint/a/{b} is a  better match, because it has longer exact path
+ 19 x-tyrus-tracing-14 : [3 ms] Choosing better match from /samples-debug/endpoint/a/{b} and /samples-debug/endpoint/a/b
+ 20 x-tyrus-tracing-15 : [3 ms] /samples-debug/endpoint/a/b is an exact match
+ 21 x-tyrus-tracing-16 : [3 ms] Choosing better match from /samples-debug/endpoint/{a}/{b} and /samples-debug/endpoint/a/{b}
+ 22 x-tyrus-tracing-17 : [4 ms] /samples-debug/endpoint/a/{b} is a  better match, because it has longer exact path
+ 23 x-tyrus-tracing-18 : [4 ms] Choosing better match from /samples-debug/endpoint/{a}/{b} and /samples-debug/endpoint/{a}/b
+ 24 x-tyrus-tracing-19 : [4 ms] /samples-debug/endpoint/{a}/b is a  better match, because /samples-debug/endpoint/{a}/{b} has more variables
+ 25 x-tyrus-tracing-20 : [4 ms] Endpoints matched to the request URI: [/samples-debug/endpoint/a/b, /samples-debug/endpoint/a/{b}, /samples-debug/endpoint/{a}/b, /samples-debug/endpoint/{a}/{b}]
+ 26 x-tyrus-tracing-21 : [4 ms] Endpoint selected as a match to the handshake URI: /samples-debug/endpoint/a/b </fo:block>
+            </fo:block></fo:block></fo:block><fo:block id="d0e1475"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client handshake request and response logging</fo:marker><fo:block font-size="20.735999999999997pt">8.11. Client handshake request and response logging</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Tyrus client offers a possibility, how to enable printing of handshake requests and responses to standard output without having to configure Java logging,
+            which is essential when debugging a misbehaving websocket application. This feature is particularly useful with tracing enabled. The following sample shows,
+            how the handshake logging can be enabled:
+            <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1480">  1 
+  2                 ClientManager client = ClientManager.createClient();
+  3                 client.getProperties().put(ClientProperties.LOG_HTTP_UPGRADE, true);
+  4             </fo:block>
+        </fo:block></fo:block><fo:block id="d0e1483"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">JMX Monitoring</fo:marker><fo:block font-size="20.735999999999997pt">8.12. JMX Monitoring</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Tyrus allows monitoring and accessing some runtime properties and metrics at the server side using JMX (Java management extension technology).
+            The monitoring API has been available since version 1.6 and the following properties are available at runtime
+            through MXBeans. Number of open sessions, maximal number of open session since the start of monitoring and
+            list of deployed endpoint class names and paths are available for each application. Endpoint class name and path
+            the endpoint is registered on, number of open session and maximal number of open sessions are available for each
+            endpoint. Apart from that message as well as error statistics are collected both per application and per individual endpoint.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            The following message statistics are monitored for both sent and received messages:
+            <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1490"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1491"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>messages count</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1494"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>messages count per second</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1497"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>average message size</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1500"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>smallest message size</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1503"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>largest message size</fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+            Moreover all of them are collected separately for text, binary and control messages and apart from the statistics being available
+            for the three separate categories, total numbers summing up statistics from the three types of messages are also available.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            As has been already mentioned above, Tyrus also monitors errors on both application and endpoint level.
+            An error is identified by the Throwable class name that has been thrown. Statistics are collected about number of times each
+            Throwable has been thrown, so a list of errors together with a number of times each error occurred is available on both application and endpoint level.
+            The monitored errors correspond to invocation of @OnError method on an annotated endpoint or its equivalent on a programmatic endpoint
+            (The invocation of @OnError method is just an analogy and an error will be monitored even if no @OnError method is provided on the endpoint).
+            Errors that occur in @OnOpen, @OnClose methods and methods handling incoming messages are monitored. Errors that occurred during handshake
+            will not be among the monitored errors.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            The collected metrics as well as the endpoint properties mentioned above are accessible at runtime through Tyrus MXBeans.
+            As has been already mention the information is available on both application and endpoint level with each application
+            or endpoint being represented with four MXBeans. One of those MXBeans contains total message statistics for both sent and received
+            messages as well as any properties specific for applications or endpoints such as endpoint path in the case of an endpoint.
+            The other three MXBeans contain information about sent and received text, binary and control messages.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            When a user connects to a tyrus application MBean server using an JMX client such as JConsole, they will see
+            the following structure:
+            <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1513"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1514"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                        Application 1 - MXBean containing a list of deployed endpoint class names and paths, number of open sessions,
+                        maximal number of open sessions, error and total message statistics for the application.
+                    </fo:block><fo:list-block provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1517"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1518"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                message statistics - a directory containing message statistics MXBeans
+                            </fo:block><fo:list-block provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1521"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1522"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                        text - MXBean containing text message statistics
+                                    </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1525"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                        binary - MXBean containing binary message statistics
+                                    </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1528"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                        control -  MXBean containing control message statistics
+                                    </fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1531"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                endpoints - a directory containing application endpoint MXBeans
+                            </fo:block><fo:list-block provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1534"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1535"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                        Endpoint 1 - MXBean containing Endpoint 1 class name and path, number of open sessions,
+                                        maximal number of open sessions, error and total message statistics for the endpoint.
+                                    </fo:block><fo:list-block provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1538"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1539"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                                text - MXBean containing text message statistics
+                                            </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1542"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                                binary - MXBean containing binary message statistics
+                                            </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1545"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                                control -  MXBean containing control message statistics
+                                            </fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1548"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                                        Endpoint 2
+                                    </fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block></fo:block></fo:list-item-body></fo:list-item></fo:list-block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1551"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                        Application 2
+                    </fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            In fact the monitoring structure described above was a little bit simplistic, because there is an additional
+            monitoring level available, which causes message metrics being also available per session.
+            The monitoring structure is very similar to the one described above, with a small difference that there are
+            four MXBeans registered for each session, which contain text, binary, control and total message statistics.
+            In order to distinguish the two monitoring levels, they will be referred to as endpoint-level monitoring
+            and session-level monitoring.
+        </fo:block><fo:block id="d0e1557"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Configuration</fo:marker><fo:block font-size="17.28pt">8.12.1. Configuration</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                As has been already mentioned, monitoring is supported only on the server side and is disabled by default.
+                The following code sample shows, how endpoint-level monitoring can be enabled on Grizzly server:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1562">  1 
+  2 serverProperties.put(ApplicationEventListener.APPLICATION_EVENT_LISTENER, new SessionlessApplicationMonitor());
+  3                 </fo:block>
+                Similarly endpoint-level monitoring can be enabled on Grizzly server in the following way:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1565">  1 
+  2 serverProperties.put(ApplicationEventListener.APPLICATION_EVENT_LISTENER, new SessionAwareApplicationMonitor());
+  3                 </fo:block>
+                Monitoring can be configured on Glassfish in web.xml and the following code sample shows endpoint-level configuration:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1568">  1 &lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  2                     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;
+  3 
+  4     &lt;context-param&gt;
+  5         &lt;param-name&gt;org.glassfish.tyrus.core.monitoring.ApplicationEventListener&lt;/param-name&gt;
+  6         &lt;param-value&gt;org.glassfish.tyrus.ext.monitoring.jmx.SessionlessApplicationMonitor&lt;/param-value&gt;
+  7     &lt;/context-param&gt;
+  8 &lt;/web-app&gt;
+  9                 </fo:block>
+                Similarly session-level monitoring can be configured on Glassfish in web.xml in the following way:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1571">  1 &lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  2                     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;
+  3 
+  4     &lt;context-param&gt;
+  5         &lt;param-name&gt;org.glassfish.tyrus.core.monitoring.ApplicationEventListener&lt;/param-name&gt;
+  6         &lt;param-value&gt;org.glassfish.tyrus.ext.monitoring.jmx.SessionAwareApplicationMonitor&lt;/param-value&gt;
+  7     &lt;/context-param&gt;
+  8 &lt;/web-app&gt;
+  9                 </fo:block>
+            </fo:block></fo:block></fo:block><fo:block id="d0e1574"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Maximal number of open sessions on server-side</fo:marker><fo:block font-size="20.735999999999997pt">8.13. Maximal number of open sessions on server-side</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Tyrus offers a few ways to limit the number of open sessions, which can be used to save limited resources
+            on a server hosting system. The limits can be configured in several scopes:
+        </fo:block><fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1579"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1580"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>per whole application</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1583"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>per endpoint</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1586"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>per remote address (client IP address)</fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            If the number of simultaneously opened sessions exceeds any of these limits, Tyrus will close the session
+            with close code 1013 - Try Again Later.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Limits mentioned above can be combined together. For example, let's say we have
+            an application with two endpoints. Overall limit per application will be 1000 open sessions and the first
+            one, non-critical endpoint, will be limited to 75 open sessions at maximum. So we know that the second
+            endpoint can handle 925-1000 opened sessions, depends on how many open sessions are connected to
+            the first endpoint (0-75).
+        </fo:block><fo:block id="d0e1593"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Maximal number of open sessions per application</fo:marker><fo:block font-size="17.28pt">8.13.1. Maximal number of open sessions per application</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                This configuration property can be used to limit overall number of open sessions per whole application.
+                The main purpose of this configurable limit is to restrict how many resources the application can
+                consume.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                The number of open sessions per whole application can be configured by setting property
+                <fo:inline font-family="monospace">org.glassfish.tyrus.maxSessionsPerApp</fo:inline>. Property can be used as
+                <fo:inline font-family="monospace">&lt;context-param&gt;</fo:inline>
+                in
+                <fo:inline font-family="monospace">web.xml</fo:inline>
+                or as an entry in parameter map in (standalone) Server properties.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Note that only positive integer is allowed.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">This example will set maximal number of open sessions per whole application to 500:</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1613">
+
+&lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;
+    &lt;context-param&gt;
+        &lt;param-name&gt;org.glassfish.tyrus.maxSessionsPerApp&lt;/param-name&gt;
+        &lt;param-value&gt;500&lt;/param-value&gt;
+    &lt;/context-param&gt;
+&lt;/web-app&gt;
+
+            </fo:block></fo:block><fo:block id="d0e1615"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Maximal number of open sessions per remote address</fo:marker><fo:block font-size="17.28pt">8.13.2. Maximal number of open sessions per remote address</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                The number of open sessions per remote address can be configured by setting property
+                <fo:inline font-family="monospace">org.glassfish.tyrus.maxSessionsPerRemoteAddr</fo:inline>. Property can be used as
+                <fo:inline font-family="monospace">&lt;context-param&gt;</fo:inline>
+                in
+                <fo:inline font-family="monospace">web.xml</fo:inline>
+                or as an entry in parameter map in (standalone) Server properties.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                <fo:inline font-family="monospace">Remote address</fo:inline>
+                value is obtained from
+                <fo:basic-link external-destination="url(http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getRemoteAddr())"><fo:inline>
+                    ServletRequest#getRemoteAddr()
+                </fo:inline></fo:basic-link><fo:inline hyphenate="false"> [<fo:basic-link external-destination="url(http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getRemoteAddr())">http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getRemoteAddr()</fo:basic-link>]</fo:inline>
+                or its alternative when using Grizzly server implementation.
+                Beware that this method returns always the last node which sending HTTP request, so all clients
+                behind one proxy will be treated as clients from single remote address.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Note that only positive integer is allowed.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">This example will set maximal number of open sessions from unique IP address or last proxy to 5:
+            </fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1641">
+                
+&lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;
+    &lt;context-param&gt;
+        &lt;param-name&gt;org.glassfish.tyrus.maxSessionsPerRemoteAddr&lt;/param-name&gt;
+        &lt;param-value&gt;5&lt;/param-value&gt;
+    &lt;/context-param&gt;
+&lt;/web-app&gt;
+
+            </fo:block></fo:block><fo:block id="d0e1643"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Maximal number of open sessions per endpoint</fo:marker><fo:block font-size="17.28pt">8.13.3. Maximal number of open sessions per endpoint</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Set maximum number of sessions in annotated endpoint:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1648">  1 
+  2 import javax.websocket.OnOpen;
+  3 import javax.websocket.Session;
+  4 import javax.websocket.server.ServerEndpoint;
+  5 
+  6 import org.glassfish.tyrus.core.MaxSessions;
+  7 
+  8 /**
+  9  * Annotated endpoint.
+ 10  */
+ 11 @MaxSessions(100)
+ 12 @ServerEndpoint(value = "/limited-sessions-endpoint")
+ 13 public static class LimitedSessionsEndpoint {
+ 14     @OnOpen
+ 15     public void onOpen(Session s) {
+ 16         ...
+ 17     }
+ 18     ...
+ 19 }
+ 20                 </fo:block>
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Set maximum number of sessions for programmatic endpoint:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1653">  1 
+  2 TyrusServerEndpointConfig.Builder.create(LimitedSessionsEndpoint.class,
+  3   "/limited-sessions-endpoint").maxSessions(100).build();
+  4                 </fo:block>
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Note that only positive integer is allowed.
+            </fo:block></fo:block></fo:block><fo:block id="d0e1658"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client HTTP Authentication</fo:marker><fo:block font-size="20.735999999999997pt">8.14. Client HTTP Authentication</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            For server endpoints which is protected by HTTP authentication, Tyrus provides a mechanism to authenticate
+            client.
+            When client receives HTTP response status code<fo:inline font-family="monospace">401 - Unauthorized</fo:inline>, then Tyrus extracts required
+            scheme from
+            <fo:inline font-family="monospace">WWW-Authenticate</fo:inline>
+            challenge. Then it chooses an
+            authenticator from a map of registered authenticators and uses configured<fo:inline font-family="monospace">credentials</fo:inline>.
+            If no proper authenticator is found or credentials are missing, then
+            <fo:inline font-family="monospace">AuthenticationException</fo:inline>
+            is thrown before the handshake can be done.
+            There are implementations of the two most used authentication schemes in Tyrus: BASIC and DIGEST, but it is
+            also possible to implement your own authenticator and register it with a configuration builder
+            <fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.AuthConfig.Builder</fo:inline>
+            or even to override default BASIC or DIGEST
+            auth implementations.
+            If no
+            <fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.AuthConfig</fo:inline>
+            client property is set, then default
+            configuration is used. It is constructed as you can see bellow: BASIC and DIGEST internal implementations
+            are
+            enabled by default.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Please note that Basic Authentication scheme should be used over HTTPS connection only.
+        </fo:block><fo:block id="d0e1683"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Credentials</fo:marker><fo:block font-size="17.28pt">8.14.1. Credentials</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Credentials are required for both implemented authentication schemes in Tyrus. You can pass an instance
+                into ClientManager as a property:
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1688">  1 
+  2                     
+  3   client.getProperties().put(ClientProperties.CREDENTIALS, new Credentials("ws_user", "password".getBytes(AuthConfig.CHARACTER_SET));
+  4                     
+  5                 </fo:block>
+            </fo:block></fo:block><fo:block id="d0e1691"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Auth Configuration</fo:marker><fo:block font-size="17.28pt">8.14.2. Auth Configuration</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                <fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.AuthConfig</fo:inline>
+                provides a way to configure of HTTP authentication schemes.
+                Creating an instance of
+                <fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.AuthConfig</fo:inline>
+                is optional.
+                If you don't specify AuthConfig, then default instance will be created like in following code listing
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1704">  1 
+  2                     
+  3   AuthConfig authConfig = AuthConfig.Builder.create().build();
+  4   ClientManager client = ClientManager.createClient();
+  5   client.getProperties().put(ClientProperties.AUTH_CONFIG, authConfig);
+  6                     
+  7                 </fo:block>
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                If authentication is required after an initial upgrade request, Tyrus chooses a proper authentication
+                scheme based on a received challenge from server. There are two HTTP authentication scheme implemented
+                and registered
+                by default.
+            </fo:block></fo:block><fo:block id="d0e1709"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">User defined authenticator</fo:marker><fo:block font-size="17.28pt">8.14.3. User defined authenticator</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                Tyrus provides an option to implement your own client HTTP authenticator by extending
+                <fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.Authenticator</fo:inline>
+                and implementing<fo:inline font-family="monospace">generateAuthorizationHeader</fo:inline>.
+                Request URI,
+                <fo:inline font-family="monospace">WWW-Authenticate</fo:inline>
+                response header and provided
+                <fo:inline font-family="monospace">Credentials</fo:inline>
+                are
+                passed as parameters. Method must return response to authentication challenge as it is required by HTTP
+                server.
+                An instance of the implemented class must be passed to the Tyrus configuration with
+                <fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.AuthConfig.Builder#setAuthScheme(String scheme, Authenticator
+                    userDefinedAuthenticator)
+                </fo:inline>
+                and created
+                <fo:inline font-family="monospace">AuthConfig</fo:inline>
+                instance must be put into client properties.
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">Authenticator.java</fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1734">  1 
+  2                 
+  3 package org.glassfish.tyrus.client;
+  4 
+  5 import java.net.URI;
+  6 
+  7 /**
+  8  * Http Authentication provider.
+  9  * Class generates authorization token as a input for {@code Authorization} HTTP request header.
+ 10  *
+ 11  * @author Ondrej Kosatka (ondrej.kosatka at oracle.com)
+ 12  */
+ 13 public abstract class Authenticator {
+ 14 
+ 15     /**
+ 16      * Generates authorization tokens as a input for {@code Authorization} HTTP request header.
+ 17      * @param uri URI is needed for generating authorization tokens for some authentication scheme (DIGEST: {@link DigestAuthenticator})
+ 18      * @param wwwAuthenticateHeader a value of header {@code WWW-Authenticate} from HTTP response.
+ 19      * @param credentials credentials.
+ 20      * @return generated {@link String} value of {@code Authorization}.
+ 21      * @throws AuthenticationException if is not possible to create auth token.
+ 22      */
+ 23     public abstract String generateAuthorizationHeader(final URI uri, final String wwwAuthenticateHeader, final Credentials credentials) throws AuthenticationException;
+ 24 
+ 25 }
+ 26                 
+ 27             </fo:block></fo:block><fo:block id="d0e1736"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Examples</fo:marker><fo:block font-size="17.28pt">8.14.4. Examples</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                The simplest way to setup Tyrus authentication is by adding client property
+                <fo:inline font-family="monospace">ClientProperties.CREDENTIALS</fo:inline>
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1744">  1 
+  2                     
+  3   client.getProperties().put(ClientProperties.CREDENTIALS, new Credentials("ws_user", "password");
+  4                     
+  5                 </fo:block>
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                How to configure Tyrus with suppressing Basic authentication, even if server side challenges Basic
+                authentication scheme.
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1749">  1 
+  2                     
+  3   AuthConfig authConfig = AuthConfig.Builder.create().
+  4                                disableBasicAuth().
+  5                                build();
+  6   Credentials credentials = new Credentials("ws_user", "password");
+  7   client.getProperties().put(ClientProperties.AUTH_CONFIG, authConfig);
+  8   client.getProperties().put(ClientProperties.CREDENTIALS, credentials);
+  9                     
+ 10                 </fo:block>
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                How to configure Tyrus using user defined DIGEST authentication and Tyrus Basic authentication. User
+                defined
+                authentication provider
+                <fo:inline font-family="monospace">MyOwnDigestAuthenticator</fo:inline>
+                must extend<fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.Authenticator</fo:inline>.
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1760">  1 
+  2                     
+  3   AuthConfig authConfig = AuthConfig.Builder.create().
+  4                                putAuthProvider("Digest", new MyOwnDigestAuthenticator()).
+  5                                build();
+  6   Credentials credentials = new Credentials("ws_user", "password");
+  7   client.getProperties().put(ClientProperties.AUTH_CONFIG, authConfig);
+  8   client.getProperties().put(ClientProperties.CREDENTIALS, credentials);
+  9                 
+ 10                 </fo:block>
+            </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                How to configure Tyrus using user defined NTLM authentication and suppress Tyrus Basic authentication,
+                even if server side challenges Basic authentication scheme.. User defined
+                authentication provider
+                <fo:inline font-family="monospace">MyOwnNTLMAuthenticator</fo:inline>
+                must extend<fo:inline font-family="monospace">org.glassfish.tyrus.client.auth.Authenticator</fo:inline>.
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1771">  1 
+  2                     
+  3   AuthConfig authConfig = AuthConfig.Builder.create().
+  4                                disableBasicAuth().
+  5                                putAuthProvider("NTLM", new MyOwnNTLMAuthenticator()).
+  6                                build();
+  7   Credentials credentials = new Credentials("ws_user", "password");
+  8   client.getProperties().put(ClientProperties.AUTH_CONFIG, authConfig);
+  9   client.getProperties().put(ClientProperties.CREDENTIALS, credentials);
+ 10                 
+ 11                 </fo:block>
+            </fo:block></fo:block></fo:block><fo:block id="d0e1774"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client HTTP Redirect</fo:marker><fo:block font-size="20.735999999999997pt">8.15. Client HTTP Redirect</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Another Tyrus feature is HTTP redirect. If client received 3xx HTTP Redirect response code during a
+            handshake and HTTP Redirect is allowed (by <fo:inline font-family="monospace">ClientProperty.REDIRECT_ENABLED</fo:inline>
+            property) then client engine  transparently follows the URI contained in received HTTP response header
+            <fo:inline font-family="monospace">Location</fo:inline> and sends upgrade request to the new URI. Redirects can be chained up to limit set in
+            <fo:inline font-family="monospace">ClientProperty.REDIRECT_THRESHOLD</fo:inline>, whilst default value is 5.
+            If HTTP redirect failed by any reason, <fo:inline font-family="monospace">RedirectException</fo:inline> is thrown.
+        </fo:block><fo:block id="d0e1791"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Supported HTTP response codes</fo:marker><fo:block font-size="17.28pt">8.15.1. Supported HTTP response codes</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                List of 3xx HTTP response codes which can be automatically redirect
+                <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1796"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1797"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>300 - Multiple Choices</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1800"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>301 - Moved permanently</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1803"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>302 - Found</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1806"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>303 - See Other (since HTTP/1.1)</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1809"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>307 - Temporary Redirect (since HTTP/1.1)</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1812"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>308 - Permanent Redirect (Experimental RFC; RFC 7238)</fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+            </fo:block></fo:block><fo:block id="d0e1816"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Configuration</fo:marker><fo:block font-size="17.28pt">8.15.2. Configuration</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block id="d0e1819"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:block font-size="14.399999999999999pt">8.15.2.1. Enabling</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                    For enabling HTTP Redirect feature, <fo:inline font-family="monospace">ClientProperty.REDIRECT_ENABLED</fo:inline> must be explicitly set to
+                    <fo:inline font-family="monospace">true</fo:inline> (default value is<fo:inline font-family="monospace">false</fo:inline>), otherwise <fo:inline font-family="monospace">RedirectException</fo:inline>
+                    will be thrown, when any of supported HTTP Redirect response codes (see above).
+                </fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1836">
+                    client.getProperties().put(ClientProperties.REDIRECT_ENABLED, true);
+                </fo:block></fo:block><fo:block id="d0e1838"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:block font-size="14.399999999999999pt">8.15.2.2. Threshold</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                    <fo:inline font-family="monospace">ClientProperty.REDIRECT_THRESHOLD</fo:inline> is property which can be used to limit maximal
+                    number of chained redirect. Positive integer is expected and default value is 5.
+                </fo:block><fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1846">
+                    client.getProperties().put(ClientProperties.REDIRECT_THRESHOLD, 3);
+                </fo:block></fo:block></fo:block><fo:block id="d0e1848"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Exception handling</fo:marker><fo:block font-size="17.28pt">8.15.3. Exception handling</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                <fo:inline font-family="monospace">RedirectException</fo:inline>
+                is set as a cause of DeploymentException when any of the supported Redirection HTTP response
+                status codes (see above) was received and WebSocketContainer.connectToServer(...) fails
+                because of any of the following reasons:
+                <fo:list-block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" space-after.optimum="1em" space-after.minimum="0.8em" space-after.maximum="1.2em" provisional-label-separation="0.2em" provisional-distance-between-starts="1.0em" id="d0e1856"><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1857"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                            <fo:inline font-family="monospace">ClientProperties.REDIRECT_ENABLED</fo:inline> property is not set to true.
+                        </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1863"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                            Value of <fo:inline font-family="monospace">ClientProperties.REDIRECT_THRESHOLD</fo:inline> is not assignable to Integer.
+                        </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1869"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                            Number of chained redirection exceeds a value of <fo:inline font-family="monospace">ClientProperties.REDIRECT_THRESHOLD</fo:inline>
+                            (default value is 5).
+                        </fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1875"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>Infinite redirection loop is detected.</fo:block></fo:block></fo:list-item-body></fo:list-item><fo:list-item space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em" id="d0e1878"><fo:list-item-label end-indent="label-end()"><fo:block>•</fo:block></fo:list-item-label><fo:list-item-body start-indent="body-start()"><fo:block><fo:block>
+                            <fo:inline font-family="monospace">Location</fo:inline> response header is missing, is empty or does not contain a valid URI.
+                        </fo:block></fo:block></fo:list-item-body></fo:list-item></fo:list-block>
+            </fo:block></fo:block></fo:block><fo:block id="d0e1885"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Client support for HTTP status 503 - Service Unavailable with Retry-After header</fo:marker><fo:block font-size="20.735999999999997pt">8.16. Client support for HTTP status 503 - Service Unavailable with Retry-After header</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            Tyrus offers automatic handling of HTTP status code <fo:inline font-family="monospace">503 - Service Unavailable</fo:inline>, which can be
+            returned from server when temporarily overloaded or down for maintenance. When <fo:inline font-family="monospace">Retry-After</fo:inline>
+            header is included in the response, client will parse the value and schedule another reconnect attempt.
+        </fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">This feature is disabled by default.</fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+            The implementation limits connection attempts to 5, each with reconnect delay not bigger than 300
+            seconds. Other values or conditions can be handled by custom <fo:inline font-family="monospace">ReconnectHandler</fo:inline>
+            (see <fo:inline font-family="monospace">RetryAfterException</fo:inline>).
+        </fo:block><fo:block id="d0e1906"><fo:block><fo:block><fo:block keep-together.within-column="always" margin-left="0pt" font-family="sans-serif,Symbol,ZapfDingbats"><fo:block keep-with-next.within-column="always"><fo:block font-family="sans-serif,Symbol,ZapfDingbats" font-weight="bold" keep-with-next.within-column="always" space-before.minimum="0.8em" space-before.optimum="1.0em" space-before.maximum="1.2em" text-align="start" start-indent="0pt"><fo:marker marker-class-name="section.head.marker">Configuration</fo:marker><fo:block font-size="17.28pt">8.16.1. Configuration</fo:block></fo:block></fo:block></fo:block></fo:block></fo:block><fo:block space-before.optimum="1em" space-before.minimum="0.8em" space-before.maximum="1.2em">
+                <fo:block space-before.minimum="0.8em" space-before.optimum="1em" space-before.maximum="1.2em" space-after.minimum="0.8em" space-after.optimum="1em" space-after.maximum="1.2em" hyphenate="false" wrap-option="no-wrap" white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve" text-align="start" font-family="monospace" id="d0e1911">  1 
+  2                     
+  3             final ClientManager client = ClientManager.createClient();
+  4             client.getProperties().put(ClientProperties.RETRY_AFTER_SERVICE_UNAVAILABLE, true);
+  5 </fo:block>
+            </fo:block></fo:block></fo:block></fo:flow></fo:page-sequence></fo:root>
\ No newline at end of file
diff --git a/documentation/latest/user-guide.html b/documentation/latest/user-guide.html
index 4e20838..9497161 100644
--- a/documentation/latest/user-guide.html
+++ b/documentation/latest/user-guide.html
@@ -1,16 +1,16 @@
 <html><head>
       <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-   <title>Tyrus 1.13.1 User Guide</title><link rel="stylesheet" type="text/css" href="/documentation.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"></head><body class="contents"><div class="contents" bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div lang="en" class="book"><div class="titlepage"><div><div><h1 class="title"><a name="d0e2"></a>Tyrus 1.13.1 User Guide</h1></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="preface"><a href="#preface">Preface</a></span></dt><dt><span class="chapter"><a href="#getting-started">1. Getting Started</a></span></dt><dd><dl><dt><span class="section"><a href="#getting-started-wsapi-artifact">1.1. WebSocket Services Using Java API for WebSocket</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e34">1.1.1. Creating Annotated Server Endpoint</a></span></dt><dt><span class="section"><a href="#d0e78">1.1.2. Client Endpoint</a></span></dt><dt><span class="section"><a href="#websocket-programmatic-endpoint">1.1.3. Creating Server Endpoint Programmatically</a></span></dt><dt><span class="section"><a href="#standalone-mode">1.1.4. Tyrus in Standalone Mode</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#modules-and-dependencies">2. Tyrus Modules and Dependencies</a></span></dt><dt><span class="chapter"><a href="#deployment">3. Deploying WebSocket Endpoints</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e334">3.1. Deploying Endpoints as a WAR file</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e359">3.1.1. Deployment Algorithm</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e410">3.2. Deploying endpoints via <code class="code">javax.websocket.server.ServerContainer</code></a></span></dt></dl></dd><dt><span class="chapter"><a href="#websocket-api">4. WebSocket API Endpoints, Sessions and MessageHandlers</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e440">4.1. Endpoint Classes</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e464">4.1.1. javax.websocket.server.ServerEndpoint</a></span></dt><dt><span class="section"><a href="#d0e599">4.1.2. javax.websocket.ClientEndpoint</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e641">4.2. Endpoint method-level annotations</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e644">4.2.1. @OnOpen</a></span></dt><dt><span class="section"><a href="#d0e657">4.2.2. @OnClose</a></span></dt><dt><span class="section"><a href="#d0e670">4.2.3. @OnError</a></span></dt><dt><span class="section"><a href="#d0e683">4.2.4. @OnMessage</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e696">4.3. MessageHandlers</a></span></dt></dl></dd><dt><span class="chapter"><a href="#configurations">5. Configurations</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e785">5.1. <code class="code">javax.websocket.server.ServerEndpointConfig</code></a></span></dt><dt><span class="section"><a href="#d0e838">5.2. <code class="code">javax.websocket.ClientEndpointConfig</code></a></span></dt></dl></dd><dt><span class="chapter"><a href="#lifecycle">6. Endpoint Lifecycle, Sessions, Sending Messages</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e870">6.1. Endpoint Lifecycle</a></span></dt><dt><span class="section"><a href="#d0e890">6.2. <code class="code">javax.websocket.Session</code></a></span></dt><dt><span class="section"><a href="#d0e975">6.3. Sending Messages</a></span></dt><dt><span class="section"><a href="#d0e1007">6.4. RemoteEndpoint</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1021">6.4.1. <code class="code">javax.websocket.RemoteEndpoint.Basic</code></a></span></dt><dt><span class="section"><a href="#d0e1045">6.4.2. <code class="code">javax.websocket.RemoteEndpoint.Async</code></a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#injection">7. Injection Support</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1075">7.1. <code class="code">javax.inject.Inject</code> sample</a></span></dt><dt><span class="section"><a href="#d0e1102">7.2. EJB sample</a></span></dt></dl></dd><dt><span class="chapter"><a href="#tyrus-proprietary-config">8. Tyrus proprietary configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1128">8.1. Client-side SSL configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1149">8.1.1. Host verification</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1171">8.2. Asynchronous connectToServer methods</a></span></dt><dt><span class="section"><a href="#d0e1184">8.3. Optimized broadcast</a></span></dt><dt><span class="section"><a href="#d0e1197">8.4. Incoming buffer size</a></span></dt><dt><span class="section"><a href="#d0e1215">8.5. Shared client container</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1237">8.5.1. Custom masking key generator</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1258">8.6. WebSocket Extensions</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1283">8.6.1. ExtendedExtension sample</a></span></dt><dt><span class="section"><a href="#d0e1304">8.6.2. Per Message Deflate Extension</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1311">8.7. Client reconnect</a></span></dt><dt><span class="section"><a href="#d0e1323">8.8. Client behind proxy</a></span></dt><dt><span class="section"><a href="#d0e1331">8.9. JDK 7 client</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1353">8.9.1. SSL configuration</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1373">8.10. Tracing support</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1381">8.10.1. Configuration</a></span></dt><dt><span class="section"><a href="#d0e1447">8.10.2. Tracing Examples</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1475">8.11. Client handshake request and response logging</a></span></dt><dt><span class="section"><a href="#d0e1483">8.12. JMX Monitoring</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1557">8.12.1. Configuration</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1574">8.13. Maximal number of open sessions on server-side</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1593">8.13.1. Maximal number of open sessions per application</a></span></dt><dt><span class="section"><a href="#d0e1615">8.13.2. Maximal number of open sessions per remote address</a></span></dt><dt><span class="section"><a href="#d0e1643">8.13.3. Maximal number of open sessions per endpoint</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1658">8.14. Client HTTP Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1683">8.14.1. Credentials</a></span></dt><dt><span class="section"><a href="#d0e1691">8.14.2. Auth Configuration</a></span></dt><dt><span class="section"><a href="#d0e1709">8.14.3. User defined authenticator</a></span></dt><dt><span class="section"><a href="#d0e1736">8.14.4. Examples</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1774">8.15. Client HTTP Redirect</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1791">8.15.1. Supported HTTP response codes</a></span></dt><dt><span class="section"><a href="#d0e1816">8.15.2. Configuration</a></span></dt><dt><span class="section"><a href="#d0e1848">8.15.3. Exception handling</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1885">8.16. Client support for HTTP status 503 - Service Unavailable with Retry-After header</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1906">8.16.1. Configuration</a></span></dt></dl></dd></dl></dd></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>2.1. <a href="#dependencies-table-modules">Tyrus core modules</a></dt><dt>2.2. <a href="#dependencies-table-containers">Tyrus containers</a></dt></dl></div><div class="list-of-examples"><p><b>List of Examples</b></p><dl><dt>1.1. <a href="#websocket-annotated-echo-endpoint">Annotated Echo Endpoint</a></dt><dt>1.2. <a href="#websocket-client-endpoint">Client Endpoint</a></dt><dt>1.3. <a href="#websocket-programmatic-echo-endpoint">Programmatic Echo Endpoint</a></dt><dt>3.1. <a href="#deployment-serverapplicationconfig">Deployment of WAR containing several classes extending <code class="code">javax.websocket.server.ServerApplicationConfig</code></a></dt><dt>3.2. <a href="#deployment-servercontainer">Deployment of Annotated Endpoint Using ServerContainer</a></dt><dt>4.1. <a href="#endpoints-echo-endpoint">Echo sample server endpoint.</a></dt><dt>4.2. <a href="#endpoints-serverendpoint-annotation">javax.websocket.server.ServerEndpoint with all fields specified</a></dt><dt>4.3. <a href="#d0e510">Specifying URI path parameter</a></dt><dt>4.4. <a href="#d0e528">SampleDecoder</a></dt><dt>4.5. <a href="#d0e546">SampleEncoder</a></dt><dt>4.6. <a href="#d0e604">SampleClientEndpoint</a></dt><dt>4.7. <a href="#d0e651">@OnOpen with Session and EndpointConfig parameters.</a></dt><dt>4.8. <a href="#d0e664">@OnClose with Session and CloseReason parameters.</a></dt><dt>4.9. <a href="#d0e677">@OnError with Session and Throwable parameters.</a></dt><dt>4.10. <a href="#d0e690">@OnError with Session and Throwable parameters.</a></dt><dt>4.11. <a href="#d0e709">MessageHandler basic example</a></dt><dt>5.1. <a href="#d0e822">Configuration for EchoEndpoint Deployment</a></dt><dt>5.2. <a href="#d0e832">ServerEndpointConfigu built using Builder</a></dt><dt>5.3. <a href="#d0e861">ClientEndpointConfig built using Builder</a></dt><dt>6.1. <a href="#lifecycle-echo-sample">Lifecycle echo sample</a></dt><dt>6.2. <a href="#lifecycle-onmessage-sample">Sending message in @OnMessage</a></dt><dt>6.3. <a href="#lifecycle-remote-endpoint-sample">Sending message via RemoteEndpoint.Basic instance</a></dt><dt>6.4. <a href="#lifecycle-remote-endpoint-partial-sample">Method for sending partial text message</a></dt><dt>6.5. <a href="#lifecycle-remote-endpoint-async-future">Sending mesage the async way using Future</a></dt><dt>7.1. <a href="#cdi-simple-bean">Injecting bean into <code class="code">javax.websocket.server.ServerEndpoint</code></a></dt><dt>7.2. <a href="#cdi-singleton-bean">Echo sample server endpoint.</a></dt></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="preface"></a>Preface</h1></div></div></div><p>
-            This is user guide for Tyrus 1.13.1. We are trying to keep it up to date
+   <title>Tyrus 1.17 User Guide</title><link rel="stylesheet" type="text/css" href="/documentation.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"></head><body class="contents"><div class="contents" bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div lang="en" class="book"><div class="titlepage"><div><div><h1 class="title"><a name="d0e2"></a>Tyrus 1.17 User Guide</h1></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="preface"><a href="#preface">Preface</a></span></dt><dt><span class="chapter"><a href="#getting-started">1. Getting Started</a></span></dt><dd><dl><dt><span class="section"><a href="#getting-started-wsapi-artifact">1.1. WebSocket Services Using Java API for WebSocket</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e34">1.1.1. Creating Annotated Server Endpoint</a></span></dt><dt><span class="section"><a href="#d0e78">1.1.2. Client Endpoint</a></span></dt><dt><span class="section"><a href="#websocket-programmatic-endpoint">1.1.3. Creating Server Endpoint Programmatically</a></span></dt><dt><span class="section"><a href="#standalone-mode">1.1.4. Tyrus in Standalone Mode</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#modules-and-dependencies">2. Tyrus Modules and Dependencies</a></span></dt><dt><span class="chapter"><a href="#deployment">3. Deploying WebSocket Endpoints</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e334">3.1. Deploying Endpoints as a WAR file</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e359">3.1.1. Deployment Algorithm</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e410">3.2. Deploying endpoints via <code class="code">javax.websocket.server.ServerContainer</code></a></span></dt></dl></dd><dt><span class="chapter"><a href="#websocket-api">4. WebSocket API Endpoints, Sessions and MessageHandlers</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e440">4.1. Endpoint Classes</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e464">4.1.1. javax.websocket.server.ServerEndpoint</a></span></dt><dt><span class="section"><a href="#d0e599">4.1.2. javax.websocket.ClientEndpoint</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e641">4.2. Endpoint method-level annotations</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e644">4.2.1. @OnOpen</a></span></dt><dt><span class="section"><a href="#d0e657">4.2.2. @OnClose</a></span></dt><dt><span class="section"><a href="#d0e670">4.2.3. @OnError</a></span></dt><dt><span class="section"><a href="#d0e683">4.2.4. @OnMessage</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e696">4.3. MessageHandlers</a></span></dt></dl></dd><dt><span class="chapter"><a href="#configurations">5. Configurations</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e785">5.1. <code class="code">javax.websocket.server.ServerEndpointConfig</code></a></span></dt><dt><span class="section"><a href="#d0e838">5.2. <code class="code">javax.websocket.ClientEndpointConfig</code></a></span></dt></dl></dd><dt><span class="chapter"><a href="#lifecycle">6. Endpoint Lifecycle, Sessions, Sending Messages</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e870">6.1. Endpoint Lifecycle</a></span></dt><dt><span class="section"><a href="#d0e890">6.2. <code class="code">javax.websocket.Session</code></a></span></dt><dt><span class="section"><a href="#d0e975">6.3. Sending Messages</a></span></dt><dt><span class="section"><a href="#d0e1007">6.4. RemoteEndpoint</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1021">6.4.1. <code class="code">javax.websocket.RemoteEndpoint.Basic</code></a></span></dt><dt><span class="section"><a href="#d0e1045">6.4.2. <code class="code">javax.websocket.RemoteEndpoint.Async</code></a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#injection">7. Injection Support</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1075">7.1. <code class="code">javax.inject.Inject</code> sample</a></span></dt><dt><span class="section"><a href="#d0e1102">7.2. EJB sample</a></span></dt></dl></dd><dt><span class="chapter"><a href="#tyrus-proprietary-config">8. Tyrus proprietary configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1128">8.1. Client-side SSL configuration</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1149">8.1.1. Host verification</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1171">8.2. Asynchronous connectToServer methods</a></span></dt><dt><span class="section"><a href="#d0e1184">8.3. Optimized broadcast</a></span></dt><dt><span class="section"><a href="#d0e1197">8.4. Incoming buffer size</a></span></dt><dt><span class="section"><a href="#d0e1215">8.5. Shared client container</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1237">8.5.1. Custom masking key generator</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1258">8.6. WebSocket Extensions</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1283">8.6.1. ExtendedExtension sample</a></span></dt><dt><span class="section"><a href="#d0e1304">8.6.2. Per Message Deflate Extension</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1311">8.7. Client reconnect</a></span></dt><dt><span class="section"><a href="#d0e1323">8.8. Client behind proxy</a></span></dt><dt><span class="section"><a href="#d0e1331">8.9. JDK 7 client</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1353">8.9.1. SSL configuration</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1373">8.10. Tracing support</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1381">8.10.1. Configuration</a></span></dt><dt><span class="section"><a href="#d0e1447">8.10.2. Tracing Examples</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1475">8.11. Client handshake request and response logging</a></span></dt><dt><span class="section"><a href="#d0e1483">8.12. JMX Monitoring</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1557">8.12.1. Configuration</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1574">8.13. Maximal number of open sessions on server-side</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1593">8.13.1. Maximal number of open sessions per application</a></span></dt><dt><span class="section"><a href="#d0e1615">8.13.2. Maximal number of open sessions per remote address</a></span></dt><dt><span class="section"><a href="#d0e1643">8.13.3. Maximal number of open sessions per endpoint</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1658">8.14. Client HTTP Authentication</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1683">8.14.1. Credentials</a></span></dt><dt><span class="section"><a href="#d0e1691">8.14.2. Auth Configuration</a></span></dt><dt><span class="section"><a href="#d0e1709">8.14.3. User defined authenticator</a></span></dt><dt><span class="section"><a href="#d0e1736">8.14.4. Examples</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1774">8.15. Client HTTP Redirect</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1791">8.15.1. Supported HTTP response codes</a></span></dt><dt><span class="section"><a href="#d0e1816">8.15.2. Configuration</a></span></dt><dt><span class="section"><a href="#d0e1848">8.15.3. Exception handling</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e1885">8.16. Client support for HTTP status 503 - Service Unavailable with Retry-After header</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e1906">8.16.1. Configuration</a></span></dt></dl></dd></dl></dd></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>2.1. <a href="#dependencies-table-modules">Tyrus core modules</a></dt><dt>2.2. <a href="#dependencies-table-containers">Tyrus containers</a></dt></dl></div><div class="list-of-examples"><p><b>List of Examples</b></p><dl><dt>1.1. <a href="#websocket-annotated-echo-endpoint">Annotated Echo Endpoint</a></dt><dt>1.2. <a href="#websocket-client-endpoint">Client Endpoint</a></dt><dt>1.3. <a href="#websocket-programmatic-echo-endpoint">Programmatic Echo Endpoint</a></dt><dt>3.1. <a href="#deployment-serverapplicationconfig">Deployment of WAR containing several classes extending <code class="code">javax.websocket.server.ServerApplicationConfig</code></a></dt><dt>3.2. <a href="#deployment-servercontainer">Deployment of Annotated Endpoint Using ServerContainer</a></dt><dt>4.1. <a href="#endpoints-echo-endpoint">Echo sample server endpoint.</a></dt><dt>4.2. <a href="#endpoints-serverendpoint-annotation">javax.websocket.server.ServerEndpoint with all fields specified</a></dt><dt>4.3. <a href="#d0e510">Specifying URI path parameter</a></dt><dt>4.4. <a href="#d0e528">SampleDecoder</a></dt><dt>4.5. <a href="#d0e546">SampleEncoder</a></dt><dt>4.6. <a href="#d0e604">SampleClientEndpoint</a></dt><dt>4.7. <a href="#d0e651">@OnOpen with Session and EndpointConfig parameters.</a></dt><dt>4.8. <a href="#d0e664">@OnClose with Session and CloseReason parameters.</a></dt><dt>4.9. <a href="#d0e677">@OnError with Session and Throwable parameters.</a></dt><dt>4.10. <a href="#d0e690">@OnError with Session and Throwable parameters.</a></dt><dt>4.11. <a href="#d0e709">MessageHandler basic example</a></dt><dt>5.1. <a href="#d0e822">Configuration for EchoEndpoint Deployment</a></dt><dt>5.2. <a href="#d0e832">ServerEndpointConfigu built using Builder</a></dt><dt>5.3. <a href="#d0e861">ClientEndpointConfig built using Builder</a></dt><dt>6.1. <a href="#lifecycle-echo-sample">Lifecycle echo sample</a></dt><dt>6.2. <a href="#lifecycle-onmessage-sample">Sending message in @OnMessage</a></dt><dt>6.3. <a href="#lifecycle-remote-endpoint-sample">Sending message via RemoteEndpoint.Basic instance</a></dt><dt>6.4. <a href="#lifecycle-remote-endpoint-partial-sample">Method for sending partial text message</a></dt><dt>6.5. <a href="#lifecycle-remote-endpoint-async-future">Sending mesage the async way using Future</a></dt><dt>7.1. <a href="#cdi-simple-bean">Injecting bean into <code class="code">javax.websocket.server.ServerEndpoint</code></a></dt><dt>7.2. <a href="#cdi-singleton-bean">Echo sample server endpoint.</a></dt></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="preface"></a>Preface</h1></div></div></div><p>
+            This is user guide for Tyrus 1.17. We are trying to keep it up to date
             as we add new features. Please use also our API documentation linked
             from the
-            <a class="link" href="http://tyrus.java.net" target="_top">Tyrus</a> and
-            <a class="link" href="https://java.net/projects/websocket-spec" target="_top">Java API for WebSocket</a>
+            <a class="link" href="https://projects.eclipse.org/projects/ee4j.tyrus" target="_top">Tyrus</a> and
+            <a class="link" href="https://projects.eclipse.org/projects/ee4j.websocket" target="_top">Java API for WebSocket</a>
             home pages as an additional source of information about Tyrus features and API.
 
             If you would like to contribute to the guide or have questions
             on things not covered in our docs, please contact us at
-            <a class="link" href="mailto:users@tyrus.java.net" target="_top">users@tyrus.java.net</a>.
+            <a class="link" href="https://dev.eclipse.org/mailman/listinfo/tyrus-dev" target="_top">tyrus-dev@eclipse.org</a>.
         </p></div><div lang="en" class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="getting-started"></a>Chapter&nbsp;1.&nbsp;Getting Started</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#getting-started-wsapi-artifact">1.1. WebSocket Services Using Java API for WebSocket</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e34">1.1.1. Creating Annotated Server Endpoint</a></span></dt><dt><span class="section"><a href="#d0e78">1.1.2. Client Endpoint</a></span></dt><dt><span class="section"><a href="#websocket-programmatic-endpoint">1.1.3. Creating Server Endpoint Programmatically</a></span></dt><dt><span class="section"><a href="#standalone-mode">1.1.4. Tyrus in Standalone Mode</a></span></dt></dl></dd></dl></div><p>
         This chapter provides a quick introduction on how to get started building
         WebSocket services using Java API for WebSocket and Tyrus. The example described here presents how to implement
@@ -146,13 +146,13 @@ public class EchoEndpointAnnotated {
 </p><pre class="&#xA;    toolbar: false;&#xA;    brush: xml;&#xA;    gutter: false;">&lt;dependency&gt;
     &lt;groupId&gt;org.glassfish.tyrus&lt;/groupId&gt;
     &lt;artifactId&gt;tyrus-server&lt;/artifactId&gt;
-    &lt;version&gt;1.13.1&lt;/version&gt;
+    &lt;version&gt;1.17&lt;/version&gt;
 &lt;/dependency&gt;
 
 &lt;dependency&gt;
     &lt;groupId&gt;org.glassfish.tyrus&lt;/groupId&gt;
     &lt;artifactId&gt;tyrus-container-grizzly-server&lt;/artifactId&gt;
-    &lt;version&gt;1.13.1&lt;/version&gt;
+    &lt;version&gt;1.17&lt;/version&gt;
 &lt;/dependency&gt;</pre><p>
             </p><p>
                 Let's use the very same example like for Java API for WebSocket and deploy the <code class="code">EchoEndpointAnnotated</code> on the
@@ -183,49 +183,49 @@ public class EchoEndpointAnnotated {
         manage dependencies of their applications than developers using ant or other build technologies. The following
         table provides an overview of all Tyrus modules and their dependencies with links to the respective binaries.
     </p><div class="table"><a name="dependencies-table-modules"></a><p class="title"><b>Table&nbsp;2.1.&nbsp;Tyrus core modules</b></p><div class="table-contents"><table summary="Tyrus core modules" border="1"><colgroup><col width="14%" align="left" class="c1"><col width="35%" align="left" class="c2"><col width="51%" align="left" class="c3"></colgroup><thead><tr><th align="left">Module</th><th align="left">Dependencies</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-server|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-server|1.17|jar" target="_top">
                             tyrus-server
                         </a>
                     </td><td align="left">tyrus-core, tyrus-spi, tyrus-websocket-core</td><td align="left">Basic server functionality</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-core|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-core|1.17|jar" target="_top">
                             tyrus-core
                         </a>
                     </td><td align="left">tyrus-spi, tyrus-websocket-core</td><td align="left">Core Tyrus functionality</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-client|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-client|1.17|jar" target="_top">
                             tyrus-client
                         </a>
                     </td><td align="left">tyrus-core, tyrus-spi, tyrus-websocket-core</td><td align="left">Basic client functionality</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-documentation|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-documentation|1.17|jar" target="_top">
                             tyrus-documentation
                         </a>
                     </td><td align="left">[nothing]</td><td align="left">Project documentation</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-websocket-core|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-websocket-core|1.17|jar" target="_top">
                             tyrus-websocket-core
                         </a>
                     </td><td align="left">[nothing]</td><td align="left">The WebSocket protocol</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/remotecontent?filepath=org/glassfish/tyrus/bundles/tyrus-samples/1.13.1/tyrus-samples-1.13.1-all.zip" target="_top">
+                        <a class="link" href="http://search.maven.org/remotecontent?filepath=org/glassfish/tyrus/bundles/tyrus-samples/1.17/tyrus-samples-1.17-all.zip" target="_top">
                             tyrus-samples
                         </a>
                     </td><td align="left">tyrus-server, tyrus-client, tyrus-container-grizzly, tyrus-core, tyrus-spi,
                         tyrus-websocket-core
                     </td><td align="left">Samples of using Java API for WebSocket and Tyrus</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-spi|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-spi|1.17|jar" target="_top">
                             tyrus-spi
                         </a>
                     </td><td align="left">[nothing]</td><td align="left">SPI</td></tr></tbody></table></div></div><br class="table-break"><div class="table"><a name="dependencies-table-containers"></a><p class="title"><b>Table&nbsp;2.2.&nbsp;Tyrus containers</b></p><div class="table-contents"><table summary="Tyrus containers" border="1"><colgroup><col width="14%" align="left" class="c1"><col width="35%" align="left" class="c2"><col width="51%" align="left" class="c3"></colgroup><thead><tr><th align="left">Module</th><th align="left">Dependencies</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-glassfish-cdi|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-glassfish-cdi|1.17|jar" target="_top">
                             tyrus-container-glassfish-cdi
                         </a>
                     </td><td align="left">tyrus-spi</td><td align="left">CDI support</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-glassfish-ejb|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-glassfish-ejb|1.17|jar" target="_top">
                             tyrus-container-glassfish-ejb
                         </a>
                     </td><td align="left">tyrus-spi</td><td align="left">EJB support</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-grizzly|1.13.1|jar" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-grizzly|1.17|jar" target="_top">
                             tyrus-container-grizzly
                         </a>
                     </td><td align="left">tyrus-core, tyrus-spi, tyrus-websocket-core</td><td align="left">Grizzly integration for Tyrus client and standalone server usage</td></tr><tr><td align="left">
-                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-servlet|1.13.1|bundle" target="_top">
+                        <a class="link" href="http://search.maven.org/#artifactdetails|org.glassfish.tyrus|tyrus-container-servlet|1.17|bundle" target="_top">
                             tyrus-container-servlet
                         </a>
                     </td><td align="left">tyrus-server, tyrus-core, tyrus-spi, tyrus-websocket-core</td><td align="left">Servlet support for integration into web containers</td></tr></tbody></table></div></div><br class="table-break"></div><div lang="en" class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="deployment"></a>Chapter&nbsp;3.&nbsp;Deploying WebSocket Endpoints</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#d0e334">3.1. Deploying Endpoints as a WAR file</a></span></dt><dd><dl><dt><span class="section"><a href="#d0e359">3.1.1. Deployment Algorithm</a></span></dt></dl></dd><dt><span class="section"><a href="#d0e410">3.2. Deploying endpoints via <code class="code">javax.websocket.server.ServerContainer</code></a></span></dt></dl></div><p>
@@ -940,7 +940,7 @@ public class LoggingInterceptor {
     other WebSocket API implementation.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e1128"></a>8.1.&nbsp;Client-side SSL configuration</h2></div></div></div><p>When accessing "wss" URLs, Tyrus client will pick up whatever keystore and truststore is actually set for current JVM instance, but
             that might not be always convenient. WebSocket API does not have this feature (yet, see <a class="link" href="https://java.net/jira/browse/WEBSOCKET_SPEC-210" target="_top">WEBSOCKET_SPEC-210</a>),
             so Tyrus exposed two SSL configuration classes <a class="link" href="https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLEngineConfigurator.html" target="_top">SSLEngineConfigurator</a>
-            and <a class="link" href="https://tyrus.java.net/apidocs/1.13.1/org/glassfish/tyrus/client/SslEngineConfigurator.html" target="_top">SslEngineConfigurator</a>
+            and <a class="link" href="https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslEngineConfigurator.html" target="_top">SslEngineConfigurator</a>
             , which can be used for specifying all SSL parameters to be used with current client instance. The former configuration class
             belongs to Grizzly configuration API and therefore works only with Grizzly client. The latter configuration class
             works with both Grizzly and JDK client and offers some extensions over the Grizzly SSLEngineConfigurator
@@ -948,7 +948,7 @@ public class LoggingInterceptor {
             please refer to the following subsection dealing with host verification.
 
             Additionally, WebSocket API does not have anything like a client, only WebSocketContainer and it does not have any properties, so you need to use Tyrus specific class -
-            <a class="link" href="https://tyrus.java.net/apidocs/1.13.1/org/glassfish/tyrus/client/ClientManager.html" target="_top">ClientManager</a>.</p><pre class="&#xA;    toolbar: false;&#xA;    brush: java;&#xA;    ">final ClientManager client = ClientManager.createClient();
+            <a class="link" href="https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/ClientManager.html" target="_top">ClientManager</a>.</p><pre class="&#xA;    toolbar: false;&#xA;    brush: java;&#xA;    ">final ClientManager client = ClientManager.createClient();
 
 System.getProperties().put("javax.net.debug", "all");
 System.getProperties().put(SSLContextConfigurator.KEY_STORE_FILE, "...");
@@ -986,7 +986,7 @@ client.connectToServer(... , ClientEndpointConfig.Builder.create().build(),
                 to note that Grizzly specific
                 <a class="link" href="https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLEngineConfigurator.html" target="_top">SSLEngineConfigurator</a>
                 does not provide these options and for modifying the default host name verification policy
-                <a class="link" href="https://tyrus.java.net/apidocs/1.13.1/org/glassfish/tyrus/client/SslEngineConfigurator.html" target="_top">SslEngineConfigurator</a>
+                <a class="link" href="https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslEngineConfigurator.html" target="_top">SslEngineConfigurator</a>
                 must be used instead. The following sample shows how to disable host name verification:
                 </p><pre class="&#xA;    toolbar: false;&#xA;    brush: java;&#xA;    ">SslEngineConfigurator sslEngineConfigurator = new SslEngineConfigurator(new SslContextConfigurator());
 sslEngineConfigurator.setHostVerificationEnabled(false)
@@ -1340,7 +1340,7 @@ final ClientManager client = ClientManager.createClient(JdkClientContainer.class
 &lt;dependency&gt;
   &lt;groupId&gt;org.glassfish.tyrus&lt;/groupId&gt;
   &lt;artifactId&gt;tyrus-container-jdk-client&lt;/artifactId&gt;
-  &lt;version&gt;1.13.1&lt;/version&gt;
+  &lt;version&gt;1.17&lt;/version&gt;
 &lt;/dependency&gt;
             </pre><p>
             Grizzly client is the default option, so creating a client without any parameters will result in Grizzly client being used.
@@ -1371,9 +1371,9 @@ final WebSocketContainer client = ContainerProvider.getWebSocketContainer();
                 end
                 <a class="link" href="https://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/ssl/SSLContextConfigurator.html" target="_top">SSLContextConfigurator</a>
                 from Grizzly project and
-                <a class="link" href="https://tyrus.java.net/apidocs/1.13.1/org/glassfish/tyrus/client/SslEngineConfigurator.html" target="_top">SslEngineConfigurator</a>
+                <a class="link" href="https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslEngineConfigurator.html" target="_top">SslEngineConfigurator</a>
                 and
-                <a class="link" href="https://tyrus.java.net/apidocs/1.13.1/org/glassfish/tyrus/client/SslContextConfigurator.html" target="_top">SslContextConfigurator</a>
+                <a class="link" href="https://tyrus.java.net/apidocs/1.17/org/glassfish/tyrus/client/SslContextConfigurator.html" target="_top">SslContextConfigurator</a>
                 from Tyrus project, but JDK client supports only the Tyrus version of these classes.
                 The following code sample shows an example of some SSL parameters configuration for the JDK client:
                 </p><pre class="&#xA;    toolbar: false;&#xA;    brush: java;&#xA;    ">
diff --git a/documentation/latest/user-guide.pdf b/documentation/latest/user-guide.pdf
index b34d05c..bd74bfe 100644
Binary files a/documentation/latest/user-guide.pdf and b/documentation/latest/user-guide.pdf differ
+ git commit -m '[jenkins] automatic docbook update [1.17]'
[master 2b1e204] [jenkins] automatic docbook update [1.17]
 26 files changed, 7119 insertions(+), 245 deletions(-)
 create mode 100644 documentation/1.17/index/configurations.html
 create mode 100644 documentation/1.17/index/deployment.html
 create mode 100644 documentation/1.17/index/getting-started.html
 create mode 100644 documentation/1.17/index/index.html
 create mode 100644 documentation/1.17/index/injection.html
 create mode 100644 documentation/1.17/index/lifecycle.html
 create mode 100644 documentation/1.17/index/modules-and-dependencies.html
 create mode 100644 documentation/1.17/index/preface.html
 create mode 100644 documentation/1.17/index/tyrus-proprietary-config.html
 create mode 100644 documentation/1.17/index/websocket-api.html
 create mode 100644 documentation/1.17/user-guide.fo
 create mode 100644 documentation/1.17/user-guide.html
 create mode 100644 documentation/1.17/user-guide.pdf
 rewrite documentation/latest/index/index.html (81%)
+ git push origin master
Failed to add the RSA host key for IP address '140.82.114.3' to the list of known hosts (/home/jenkins/.ssh/known_hosts).
To github.com:eclipse-ee4j/tyrus-project.github.io.git
   e94cd18..2b1e204  master -> master
$ ssh-agent -k
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 62 killed;
[ssh-agent] Stopped.
Finished: SUCCESS