Merge remote-tracking branch 'origin/jetty-10.0.x' into jetty-10.0.x-4407-JavaxAnnotatedConfigDefault

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2019-12-17 10:55:07 +11:00
commit 1e884c2497
33 changed files with 746 additions and 558 deletions

View File

@ -510,21 +510,12 @@ public class HttpRequest implements Request
@Override
public Request onResponseContent(final Response.ContentListener listener)
{
this.responseListeners.add(new Response.DemandedContentListener()
this.responseListeners.add(new Response.ContentListener()
{
@Override
public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback)
public void onContent(Response response, ByteBuffer content)
{
try
{
listener.onContent(response, content);
callback.succeeded();
demand.accept(1);
}
catch (Throwable x)
{
callback.failed(x);
}
listener.onContent(response, content);
}
});
return this;
@ -533,16 +524,12 @@ public class HttpRequest implements Request
@Override
public Request onResponseContentAsync(final Response.AsyncContentListener listener)
{
this.responseListeners.add(new Response.DemandedContentListener()
this.responseListeners.add(new Response.AsyncContentListener()
{
@Override
public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback)
public void onContent(Response response, ByteBuffer content, Callback callback)
{
listener.onContent(response, content, Callback.from(() ->
{
callback.succeeded();
demand.accept(1);
}, callback::failed));
listener.onContent(response, content, callback);
}
});
return this;

View File

@ -85,14 +85,14 @@ public interface Response
/**
* Common, empty, super-interface for response listeners
*/
public interface ResponseListener extends EventListener
interface ResponseListener extends EventListener
{
}
/**
* Listener for the response begin event.
*/
public interface BeginListener extends ResponseListener
interface BeginListener extends ResponseListener
{
/**
* Callback method invoked when the response line containing HTTP version,
@ -102,13 +102,13 @@ public interface Response
*
* @param response the response containing the response line data
*/
public void onBegin(Response response);
void onBegin(Response response);
}
/**
* Listener for a response header event.
*/
public interface HeaderListener extends ResponseListener
interface HeaderListener extends ResponseListener
{
/**
* Callback method invoked when a response header has been received and parsed,
@ -118,20 +118,20 @@ public interface Response
* @param field the header received
* @return true to process the header, false to skip processing of the header
*/
public boolean onHeader(Response response, HttpField field);
boolean onHeader(Response response, HttpField field);
}
/**
* Listener for the response headers event.
*/
public interface HeadersListener extends ResponseListener
interface HeadersListener extends ResponseListener
{
/**
* Callback method invoked when all the response headers have been received and parsed.
*
* @param response the response containing the response line data and the headers
*/
public void onHeaders(Response response);
void onHeaders(Response response);
}
/**
@ -139,7 +139,7 @@ public interface Response
*
* @see AsyncContentListener
*/
public interface ContentListener extends ResponseListener
interface ContentListener extends AsyncContentListener
{
/**
* Callback method invoked when the response content has been received, parsed and there is demand.
@ -149,7 +149,21 @@ public interface Response
* @param response the response containing the response line data and the headers
* @param content the content bytes received
*/
public void onContent(Response response, ByteBuffer content);
void onContent(Response response, ByteBuffer content);
@Override
default void onContent(Response response, ByteBuffer content, Callback callback)
{
try
{
onContent(response, content);
callback.succeeded();
}
catch (Throwable x)
{
callback.failed(x);
}
}
}
/**
@ -157,7 +171,7 @@ public interface Response
*
* @see DemandedContentListener
*/
public interface AsyncContentListener extends ResponseListener
interface AsyncContentListener extends DemandedContentListener
{
/**
* Callback method invoked when the response content has been received, parsed and there is demand.
@ -168,13 +182,23 @@ public interface Response
* @param content the content bytes received
* @param callback the callback to call when the content is consumed and to demand more content
*/
public void onContent(Response response, ByteBuffer content, Callback callback);
void onContent(Response response, ByteBuffer content, Callback callback);
@Override
default void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback)
{
onContent(response, content, Callback.from(() ->
{
callback.succeeded();
demand.accept(1);
}, callback::failed));
}
}
/**
* Asynchronous listener for the response content events.
*/
public interface DemandedContentListener extends ResponseListener
interface DemandedContentListener extends ResponseListener
{
/**
* Callback method invoked before response content events.
@ -186,7 +210,7 @@ public interface Response
* @param response the response containing the response line data and the headers
* @param demand the object that allows to demand content buffers
*/
public default void onBeforeContent(Response response, LongConsumer demand)
default void onBeforeContent(Response response, LongConsumer demand)
{
demand.accept(1);
}
@ -203,26 +227,26 @@ public interface Response
* @param content the content bytes received
* @param callback the callback to call when the content is consumed
*/
public void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback);
void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback);
}
/**
* Listener for the response succeeded event.
*/
public interface SuccessListener extends ResponseListener
interface SuccessListener extends ResponseListener
{
/**
* Callback method invoked when the whole response has been successfully received.
*
* @param response the response containing the response line data and the headers
*/
public void onSuccess(Response response);
void onSuccess(Response response);
}
/**
* Listener for the response failure event.
*/
public interface FailureListener extends ResponseListener
interface FailureListener extends ResponseListener
{
/**
* Callback method invoked when the response has failed in the process of being received
@ -230,13 +254,13 @@ public interface Response
* @param response the response containing data up to the point the failure happened
* @param failure the failure happened
*/
public void onFailure(Response response, Throwable failure);
void onFailure(Response response, Throwable failure);
}
/**
* Listener for the request and response completed event.
*/
public interface CompleteListener extends ResponseListener
interface CompleteListener extends ResponseListener
{
/**
* Callback method invoked when the request <em><b>and</b></em> the response have been processed,
@ -252,13 +276,13 @@ public interface Response
*
* @param result the result of the request / response exchange
*/
public void onComplete(Result result);
void onComplete(Result result);
}
/**
* Listener for all response events.
*/
public interface Listener extends BeginListener, HeaderListener, HeadersListener, ContentListener, AsyncContentListener, DemandedContentListener, SuccessListener, FailureListener, CompleteListener
interface Listener extends BeginListener, HeaderListener, HeadersListener, ContentListener, SuccessListener, FailureListener, CompleteListener
{
@Override
public default void onBegin(Response response)
@ -276,41 +300,11 @@ public interface Response
{
}
@Override
public default void onBeforeContent(Response response, LongConsumer demand)
{
demand.accept(1);
}
@Override
public default void onContent(Response response, ByteBuffer content)
{
}
@Override
public default void onContent(Response response, ByteBuffer content, Callback callback)
{
try
{
onContent(response, content);
callback.succeeded();
}
catch (Throwable x)
{
callback.failed(x);
}
}
@Override
public default void onContent(Response response, LongConsumer demand, ByteBuffer content, Callback callback)
{
onContent(response, content, Callback.from(() ->
{
callback.succeeded();
demand.accept(1);
}, callback::failed));
}
@Override
public default void onSuccess(Response response)
{
@ -329,7 +323,7 @@ public interface Response
/**
* An empty implementation of {@link Listener}
*/
public static class Adapter implements Listener
class Adapter implements Listener
{
}
}

View File

@ -18,6 +18,7 @@
package org.eclipse.jetty.client;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -84,6 +85,7 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.toolchain.test.Net;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.IO;
@ -1784,6 +1786,57 @@ public class HttpClientTest extends AbstractHttpClientServerTest
}
}
@ParameterizedTest
@ArgumentsSource(ScenarioProvider.class)
public void testContentListenerAsCompleteListener(Scenario scenario) throws Exception
{
byte[] bytes = new byte[1024];
new Random().nextBytes(bytes);
start(scenario, new AbstractHandler()
{
@Override
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
ServletOutputStream output = response.getOutputStream();
output.write(bytes);
}
});
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CountDownLatch latch = new CountDownLatch(1);
class L implements Response.ContentListener, Response.CompleteListener
{
@Override
public void onContent(Response response, ByteBuffer content)
{
try
{
BufferUtil.writeTo(content, baos);
}
catch (IOException x)
{
baos.reset();
x.printStackTrace();
}
}
@Override
public void onComplete(Result result)
{
if (result.isSucceeded())
latch.countDown();
}
}
client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme())
.send(new L());
assertTrue(latch.await(5, TimeUnit.SECONDS));
assertArrayEquals(bytes, baos.toByteArray());
}
private void assertCopyRequest(Request original)
{
Request copy = client.copyRequest((HttpRequest)original, original.getURI());

View File

@ -18,101 +18,41 @@
package org.eclipse.jetty.websocket.javax.client;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.ClientEndpoint;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Extension;
import org.eclipse.jetty.websocket.javax.common.ClientEndpointConfigWrapper;
import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException;
public class AnnotatedClientEndpointConfig implements ClientEndpointConfig
public class AnnotatedClientEndpointConfig extends ClientEndpointConfigWrapper
{
private final ClientEndpoint annotation;
private final List<Class<? extends Decoder>> decoders;
private final List<Class<? extends Encoder>> encoders;
private final List<Extension> extensions;
private final List<String> preferredSubprotocols;
private final Configurator configurator;
private Map<String, Object> userProperties;
public AnnotatedClientEndpointConfig(ClientEndpoint anno)
{
this.annotation = anno;
this.decoders = Collections.unmodifiableList(Arrays.asList(anno.decoders()));
this.encoders = Collections.unmodifiableList(Arrays.asList(anno.encoders()));
this.preferredSubprotocols = Collections.unmodifiableList(Arrays.asList(anno.subprotocols()));
// no extensions declared in annotation
this.extensions = Collections.emptyList();
// no userProperties in annotation
this.userProperties = new HashMap<>();
if (anno.configurator() == null)
Configurator configurator;
try
{
this.configurator = EmptyConfigurator.INSTANCE;
configurator = anno.configurator().getDeclaredConstructor().newInstance();
}
else
catch (Exception e)
{
try
{
this.configurator = anno.configurator().getDeclaredConstructor().newInstance();
}
catch (Exception e)
{
StringBuilder err = new StringBuilder();
err.append("Unable to instantiate ClientEndpoint.configurator() of ");
err.append(anno.configurator().getName());
err.append(" defined as annotation in ");
err.append(anno.getClass().getName());
throw new InvalidWebSocketException(err.toString(), e);
}
StringBuilder err = new StringBuilder();
err.append("Unable to instantiate ClientEndpoint.configurator() of ");
err.append(anno.configurator().getName());
err.append(" defined as annotation in ");
err.append(anno.getClass().getName());
throw new InvalidWebSocketException(err.toString(), e);
}
}
public ClientEndpoint getAnnotation()
{
return annotation;
}
ClientEndpointConfig build = Builder.create()
.encoders(List.of(anno.encoders()))
.decoders(List.of(anno.decoders()))
.preferredSubprotocols(List.of(anno.subprotocols()))
.extensions(Collections.emptyList())
.configurator(configurator)
.build();
@Override
public Configurator getConfigurator()
{
return configurator;
}
@Override
public List<Class<? extends Decoder>> getDecoders()
{
return decoders;
}
@Override
public List<Class<? extends Encoder>> getEncoders()
{
return encoders;
}
@Override
public List<Extension> getExtensions()
{
return extensions;
}
@Override
public List<String> getPreferredSubprotocols()
{
return preferredSubprotocols;
}
@Override
public Map<String, Object> getUserProperties()
{
return userProperties;
init(build);
}
}

View File

@ -0,0 +1,29 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.client;
import org.eclipse.jetty.websocket.javax.common.ClientEndpointConfigWrapper;
public class BasicClientEndpointConfig extends ClientEndpointConfigWrapper
{
public BasicClientEndpointConfig()
{
init(Builder.create().configurator(EmptyConfigurator.INSTANCE).build());
}
}

View File

@ -1,84 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Extension;
public class EmptyClientEndpointConfig implements ClientEndpointConfig
{
private final List<Class<? extends Decoder>> decoders;
private final List<Class<? extends Encoder>> encoders;
private final List<Extension> extensions;
private final List<String> preferredSubprotocols;
private final Configurator configurator;
private Map<String, Object> userProperties;
public EmptyClientEndpointConfig()
{
this.decoders = new ArrayList<>();
this.encoders = new ArrayList<>();
this.preferredSubprotocols = new ArrayList<>();
this.extensions = new ArrayList<>();
this.userProperties = new HashMap<>();
this.configurator = EmptyConfigurator.INSTANCE;
}
@Override
public Configurator getConfigurator()
{
return configurator;
}
@Override
public List<Class<? extends Decoder>> getDecoders()
{
return decoders;
}
@Override
public List<Class<? extends Encoder>> getEncoders()
{
return encoders;
}
@Override
public List<Extension> getExtensions()
{
return extensions;
}
@Override
public List<String> getPreferredSubprotocols()
{
return preferredSubprotocols;
}
@Override
public Map<String, Object> getUserProperties()
{
return userProperties;
}
}

View File

@ -215,7 +215,7 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
{
ClientEndpointConfig config = providedConfig;
if (config == null)
config = new EmptyClientEndpointConfig();
config = new BasicClientEndpointConfig();
ConfiguredEndpoint instance = new ConfiguredEndpoint(endpoint, config);
return connect(instance, path);

View File

@ -39,6 +39,12 @@ public class JavaxWebSocketClientFrameHandlerFactory extends JavaxWebSocketFrame
super(container, InvokerUtils.PARAM_IDENTITY);
}
@Override
public EndpointConfig newDefaultEndpointConfig(Class<?> endpointClass, String path)
{
return new BasicClientEndpointConfig();
}
@Override
public JavaxWebSocketFrameHandlerMetadata createMetadata(Class<?> endpointClass, EndpointConfig endpointConfig)
{

View File

@ -0,0 +1,61 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.common;
import java.util.List;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.Extension;
public class ClientEndpointConfigWrapper extends EndpointConfigWrapper implements ClientEndpointConfig
{
private ClientEndpointConfig _endpointConfig;
public ClientEndpointConfigWrapper()
{
}
public ClientEndpointConfigWrapper(ClientEndpointConfig endpointConfig)
{
init(endpointConfig);
}
public void init(ClientEndpointConfig endpointConfig)
{
_endpointConfig = endpointConfig;
super.init(endpointConfig);
}
@Override
public List<String> getPreferredSubprotocols()
{
return _endpointConfig.getPreferredSubprotocols();
}
@Override
public List<Extension> getExtensions()
{
return _endpointConfig.getExtensions();
}
@Override
public Configurator getConfigurator()
{
return _endpointConfig.getConfigurator();
}
}

View File

@ -19,44 +19,57 @@
package org.eclipse.jetty.websocket.javax.common;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;
/**
* Basic EndpointConfig (used when no EndpointConfig is provided or discovered)
*/
public class BasicEndpointConfig implements EndpointConfig
public abstract class EndpointConfigWrapper implements EndpointConfig, PathParamProvider
{
private List<Class<? extends Decoder>> decoders;
private List<Class<? extends Encoder>> encoders;
private Map<String, Object> userProperties;
private EndpointConfig _endpointConfig;
private Map<String, String> _pathParameters;
public BasicEndpointConfig()
public EndpointConfigWrapper()
{
decoders = Collections.emptyList();
encoders = Collections.emptyList();
userProperties = new HashMap<>();
}
@Override
public List<Class<? extends Decoder>> getDecoders()
public EndpointConfigWrapper(EndpointConfig endpointConfig)
{
return decoders;
init(endpointConfig);
}
public void init(EndpointConfig endpointConfig)
{
_endpointConfig = endpointConfig;
if (endpointConfig instanceof PathParamProvider)
_pathParameters = ((PathParamProvider)endpointConfig).getPathParams();
else
_pathParameters = Collections.emptyMap();
}
@Override
public List<Class<? extends Encoder>> getEncoders()
{
return encoders;
return _endpointConfig.getEncoders();
}
@Override
public List<Class<? extends Decoder>> getDecoders()
{
return _endpointConfig.getDecoders();
}
@Override
public Map<String, Object> getUserProperties()
{
return userProperties;
return _endpointConfig.getUserProperties();
}
@Override
public Map<String, String> getPathParams()
{
return _pathParameters;
}
}

View File

@ -28,11 +28,13 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.CloseReason;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.PongMessage;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
@ -97,7 +99,7 @@ public class JavaxWebSocketFrameHandler implements FrameHandler
private UpgradeRequest upgradeRequest;
private UpgradeResponse upgradeResponse;
private final EndpointConfig endpointConfig;
private EndpointConfig endpointConfig;
private MessageSink textSink;
private MessageSink binarySink;
private MessageSink activeMessageSink;
@ -155,9 +157,12 @@ public class JavaxWebSocketFrameHandler implements FrameHandler
@Override
public void onOpen(CoreSession coreSession, Callback callback)
{
this.coreSession = coreSession;
try
{
this.coreSession = coreSession;
// Rewire EndpointConfig to call CoreSession setters if Jetty specific properties are set.
endpointConfig = getWrappedEndpointConfig();
session = new JavaxWebSocketSession(container, coreSession, this, endpointConfig);
openHandle = InvokerUtils.bindTo(openHandle, session, endpointConfig);
@ -206,6 +211,48 @@ public class JavaxWebSocketFrameHandler implements FrameHandler
}
}
private EndpointConfig getWrappedEndpointConfig()
{
final Map<String, Object> listenerMap = new PutListenerMap(this.endpointConfig.getUserProperties(), this::configListener);
EndpointConfig wrappedConfig;
if (endpointConfig instanceof ServerEndpointConfig)
{
wrappedConfig = new ServerEndpointConfigWrapper((ServerEndpointConfig)endpointConfig)
{
@Override
public Map<String, Object> getUserProperties()
{
return listenerMap;
}
};
}
else if (endpointConfig instanceof ClientEndpointConfig)
{
wrappedConfig = new ClientEndpointConfigWrapper((ClientEndpointConfig)endpointConfig)
{
@Override
public Map<String, Object> getUserProperties()
{
return listenerMap;
}
};
}
else
{
wrappedConfig = new EndpointConfigWrapper(endpointConfig)
{
@Override
public Map<String, Object> getUserProperties()
{
return listenerMap;
}
};
}
return wrappedConfig;
}
@Override
public void onFrame(Frame frame, Callback callback)
{
@ -623,4 +670,29 @@ public class JavaxWebSocketFrameHandler implements FrameHandler
{
return upgradeResponse;
}
private void configListener(String key, Object value)
{
if (!key.startsWith("org.eclipse.jetty.websocket."))
return;
switch (key)
{
case "org.eclipse.jetty.websocket.autoFragment":
coreSession.setAutoFragment((Boolean)value);
break;
case "org.eclipse.jetty.websocket.maxFrameSize":
coreSession.setMaxFrameSize((Long)value);
break;
case "org.eclipse.jetty.websocket.outputBufferSize":
coreSession.setOutputBufferSize((Integer)value);
break;
case "org.eclipse.jetty.websocket.inputBufferSize":
coreSession.setInputBufferSize((Integer)value);
break;
}
}
}

View File

@ -104,6 +104,8 @@ public abstract class JavaxWebSocketFrameHandlerFactory
return metadata;
}
public abstract EndpointConfig newDefaultEndpointConfig(Class<?> endpointClass, String path);
public abstract JavaxWebSocketFrameHandlerMetadata createMetadata(Class<?> endpointClass, EndpointConfig endpointConfig);
public JavaxWebSocketFrameHandler newJavaxWebSocketFrameHandler(Object endpointInstance, UpgradeRequest upgradeRequest)
@ -120,7 +122,8 @@ public abstract class JavaxWebSocketFrameHandlerFactory
else
{
endpoint = endpointInstance;
config = new BasicEndpointConfig();
String path = (upgradeRequest.getRequestURI() == null) ? null : upgradeRequest.getRequestURI().getPath();
config = newDefaultEndpointConfig(endpoint.getClass(), path);
}
JavaxWebSocketFrameHandlerMetadata metadata = getMetadata(endpoint.getClass(), config);

View File

@ -76,8 +76,7 @@ public class JavaxWebSocketSession implements javax.websocket.Session
this.container = container;
this.coreSession = coreSession;
this.frameHandler = frameHandler;
this.config = endpointConfig == null ? new BasicEndpointConfig() : endpointConfig;
this.config = Objects.requireNonNull(endpointConfig);
this.availableDecoders = new AvailableDecoders(this.config);
this.availableEncoders = new AvailableEncoders(this.config);
@ -92,7 +91,12 @@ public class JavaxWebSocketSession implements javax.websocket.Session
this.pathParameters = Collections.emptyMap();
}
this.userProperties = new HashMap<>(this.config.getUserProperties());
this.userProperties = this.config.getUserProperties();
}
public FrameHandler.CoreSession getCoreSession()
{
return coreSession;
}
/**

View File

@ -0,0 +1,118 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.common;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
public class PutListenerMap implements Map<String, Object>
{
private Map<String, Object> map;
private BiConsumer<String, Object> listener;
public PutListenerMap(Map<String, Object> map, BiConsumer<String, Object> listener)
{
this.map = map;
this.listener = listener;
// Notify listener for any existing entries in the Map.
for (Map.Entry<String, Object> entry : map.entrySet())
{
listener.accept(entry.getKey(), entry.getValue());
}
}
@Override
public int size()
{
return map.size();
}
@Override
public boolean isEmpty()
{
return map.isEmpty();
}
@Override
public boolean containsKey(Object key)
{
return map.containsKey(key);
}
@Override
public boolean containsValue(Object value)
{
return map.containsValue(value);
}
@Override
public Object get(Object key)
{
return map.get(key);
}
@Override
public Object put(String key, Object value)
{
listener.accept(key, value);
return map.put(key, value);
}
@Override
public Object remove(Object key)
{
return map.remove(key);
}
@Override
public void putAll(Map<? extends String, ?> m)
{
for (Map.Entry<String, Object> entry : map.entrySet())
{
put(entry.getKey(), entry.getValue());
}
}
@Override
public void clear()
{
map.clear();
}
@Override
public Set<String> keySet()
{
return map.keySet();
}
@Override
public Collection<Object> values()
{
return map.values();
}
@Override
public Set<Entry<String, Object>> entrySet()
{
return map.entrySet();
}
}

View File

@ -16,69 +16,58 @@
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.server.internal;
package org.eclipse.jetty.websocket.javax.common;
import java.util.List;
import java.util.Map;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Extension;
import javax.websocket.server.ServerEndpointConfig;
public abstract class ServerEndpointConfigWrapper implements ServerEndpointConfig
public class ServerEndpointConfigWrapper extends EndpointConfigWrapper implements ServerEndpointConfig
{
private final ServerEndpointConfig delegate;
private ServerEndpointConfig _endpointConfig;
public ServerEndpointConfigWrapper(ServerEndpointConfig delegate)
public ServerEndpointConfigWrapper()
{
this.delegate = delegate;
}
@Override
public List<Class<? extends Encoder>> getEncoders()
public ServerEndpointConfigWrapper(ServerEndpointConfig endpointConfig)
{
return delegate.getEncoders();
init(endpointConfig);
}
@Override
public List<Class<? extends Decoder>> getDecoders()
public void init(ServerEndpointConfig endpointConfig)
{
return delegate.getDecoders();
}
@Override
public Map<String, Object> getUserProperties()
{
return delegate.getUserProperties();
_endpointConfig = endpointConfig;
super.init(endpointConfig);
}
@Override
public Class<?> getEndpointClass()
{
return delegate.getEndpointClass();
return _endpointConfig.getEndpointClass();
}
@Override
public String getPath()
{
return delegate.getPath();
return _endpointConfig.getPath();
}
@Override
public List<String> getSubprotocols()
{
return delegate.getSubprotocols();
return _endpointConfig.getSubprotocols();
}
@Override
public List<Extension> getExtensions()
{
return delegate.getExtensions();
return _endpointConfig.getExtensions();
}
@Override
public Configurator getConfigurator()
{
return delegate.getConfigurator();
return _endpointConfig.getConfigurator();
}
}

View File

@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.javax.common;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.EndpointConfig;
import org.eclipse.jetty.websocket.core.FrameHandler;
@ -53,7 +54,7 @@ public abstract class AbstractJavaxWebSocketFrameHandlerTest
public AbstractJavaxWebSocketFrameHandlerTest()
{
endpointConfig = new BasicEndpointConfig();
endpointConfig = ClientEndpointConfig.Builder.create().build();
encoders = new AvailableEncoders(endpointConfig);
decoders = new AvailableDecoders(endpointConfig);
uriParams = new HashMap<>();
@ -62,12 +63,8 @@ public abstract class AbstractJavaxWebSocketFrameHandlerTest
protected JavaxWebSocketFrameHandler newJavaxFrameHandler(Object websocket)
{
JavaxWebSocketFrameHandlerFactory factory = container.getFrameHandlerFactory();
BasicEndpointConfig config = new BasicEndpointConfig();
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket, config);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket, endpointConfig);
UpgradeRequest upgradeRequest = new UpgradeRequestAdapter();
JavaxWebSocketFrameHandler localEndpoint = factory.newJavaxWebSocketFrameHandler(endpoint, upgradeRequest);
return localEndpoint;
return factory.newJavaxWebSocketFrameHandler(endpoint, upgradeRequest);
}
}

View File

@ -40,7 +40,8 @@ public abstract class AbstractSessionTest
UpgradeRequest upgradeRequest = new UpgradeRequestAdapter();
JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(websocketPojo, upgradeRequest);
FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty();
session = new JavaxWebSocketSession(container, coreSession, frameHandler, null);
session = new JavaxWebSocketSession(container, coreSession, frameHandler, container.getFrameHandlerFactory()
.newDefaultEndpointConfig(websocketPojo.getClass(), null));
}
@AfterAll

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.websocket.javax.common;
import javax.websocket.ClientEndpoint;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
@ -31,6 +32,12 @@ public class DummyFrameHandlerFactory extends JavaxWebSocketFrameHandlerFactory
super(container, InvokerUtils.PARAM_IDENTITY);
}
@Override
public EndpointConfig newDefaultEndpointConfig(Class<?> endpointClass, String path)
{
return ClientEndpointConfig.Builder.create().build();
}
@Override
public JavaxWebSocketFrameHandlerMetadata createMetadata(Class<?> endpointClass, EndpointConfig endpointConfig)
{

View File

@ -19,107 +19,83 @@
package org.eclipse.jetty.websocket.javax.server.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.Decoder;
import javax.websocket.DeploymentException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;
import javax.websocket.Extension;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer;
import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper;
import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator;
public class AnnotatedServerEndpointConfig implements ServerEndpointConfig
public class AnnotatedServerEndpointConfig extends ServerEndpointConfigWrapper
{
private final Class<?> endpointClass;
private final String path;
private final List<Class<? extends Decoder>> decoders;
private final List<Class<? extends Encoder>> encoders;
private final ServerEndpointConfig.Configurator configurator;
private final List<String> subprotocols;
private Map<String, Object> userProperties;
private List<Extension> extensions;
public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class<?> endpointClass, ServerEndpoint anno) throws DeploymentException
{
this(containerScope, endpointClass, anno, null);
}
public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class<?> endpointClass, ServerEndpoint anno, EndpointConfig baseConfig)
throws DeploymentException
public AnnotatedServerEndpointConfig(JavaxWebSocketContainer containerScope, Class<?> endpointClass, ServerEndpoint anno, EndpointConfig baseConfig) throws DeploymentException
{
// Provided Base EndpointConfig.
ServerEndpointConfig baseServerConfig = null;
if (baseConfig instanceof ServerEndpointConfig)
{
baseServerConfig = (ServerEndpointConfig)baseConfig;
}
// Decoders (favor provided config over annotation)
// Decoders (favor provided config over annotation).
List<Class<? extends Decoder>> decoders;
if (baseConfig != null && baseConfig.getDecoders() != null && baseConfig.getDecoders().size() > 0)
{
this.decoders = Collections.unmodifiableList(baseConfig.getDecoders());
}
decoders = baseConfig.getDecoders();
else
{
this.decoders = Collections.unmodifiableList(Arrays.asList(anno.decoders()));
}
decoders = List.of(anno.decoders());
// AvailableEncoders (favor provided config over annotation)
// AvailableEncoders (favor provided config over annotation).
List<Class<? extends Encoder>> encoders;
if (baseConfig != null && baseConfig.getEncoders() != null && baseConfig.getEncoders().size() > 0)
{
this.encoders = Collections.unmodifiableList(baseConfig.getEncoders());
}
encoders = baseConfig.getEncoders();
else
{
this.encoders = Collections.unmodifiableList(Arrays.asList(anno.encoders()));
}
encoders = List.of(anno.encoders());
// Sub Protocols (favor provided config over annotation)
// Sub Protocols (favor provided config over annotation).
List<String> subprotocols;
if (baseServerConfig != null && baseServerConfig.getSubprotocols() != null && baseServerConfig.getSubprotocols().size() > 0)
{
this.subprotocols = Collections.unmodifiableList(baseServerConfig.getSubprotocols());
}
subprotocols = baseServerConfig.getSubprotocols();
else
{
this.subprotocols = Collections.unmodifiableList(Arrays.asList(anno.subprotocols()));
}
subprotocols = List.of(anno.subprotocols());
// Path (favor provided config over annotation)
// Path (favor provided config over annotation).
String path;
if (baseServerConfig != null && baseServerConfig.getPath() != null && baseServerConfig.getPath().length() > 0)
{
this.path = baseServerConfig.getPath();
}
path = baseServerConfig.getPath();
else
{
this.path = anno.value();
}
// supplied by init lifecycle
this.extensions = new ArrayList<>();
// always what is passed in
this.endpointClass = endpointClass;
// UserProperties in annotation
this.userProperties = new HashMap<>();
if (baseConfig != null && baseConfig.getUserProperties() != null && baseConfig.getUserProperties().size() > 0)
{
userProperties.putAll(baseConfig.getUserProperties());
}
path = anno.value();
// Make sure all Configurators obtained are decorated.
ServerEndpointConfig.Configurator rawConfigurator = getConfigurator(baseServerConfig, anno);
ServerEndpointConfig.Configurator configurator = containerScope.getObjectFactory().decorate(rawConfigurator);
// Make sure all Configurators obtained are decorated
this.configurator = containerScope.getObjectFactory().decorate(rawConfigurator);
// Build a ServerEndpointConfig with the Javax API builder to wrap.
ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder.create(endpointClass, path)
.configurator(configurator)
.encoders(encoders)
.decoders(decoders)
.extensions(new ArrayList<>())
.subprotocols(subprotocols)
.build();
// Set the UserProperties from annotation into the new EndpointConfig.
if (baseConfig != null && baseConfig.getUserProperties() != null && baseConfig.getUserProperties().size() > 0)
endpointConfig.getUserProperties().putAll(baseConfig.getUserProperties());
init(endpointConfig);
}
private Configurator getConfigurator(ServerEndpointConfig baseServerConfig, ServerEndpoint anno) throws DeploymentException
private static Configurator getConfigurator(ServerEndpointConfig baseServerConfig, ServerEndpoint anno) throws DeploymentException
{
Configurator ret = null;
@ -159,95 +135,4 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig
return ret;
}
@Override
public ServerEndpointConfig.Configurator getConfigurator()
{
return configurator;
}
@Override
public List<Class<? extends Decoder>> getDecoders()
{
return decoders;
}
@Override
public List<Class<? extends Encoder>> getEncoders()
{
return encoders;
}
@Override
public Class<?> getEndpointClass()
{
return endpointClass;
}
@Override
public List<Extension> getExtensions()
{
return extensions;
}
@Override
public String getPath()
{
return path;
}
@Override
public List<String> getSubprotocols()
{
return subprotocols;
}
@Override
public Map<String, Object> getUserProperties()
{
return userProperties;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
AnnotatedServerEndpointConfig that = (AnnotatedServerEndpointConfig)o;
if (endpointClass != null ? !endpointClass.equals(that.endpointClass) : that.endpointClass != null)
return false;
return path != null ? path.equals(that.path) : that.path == null;
}
@Override
public int hashCode()
{
int result = endpointClass != null ? endpointClass.hashCode() : 0;
result = 31 * result + (path != null ? path.hashCode() : 0);
return result;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("AnnotatedServerEndpointConfig[endpointClass=");
builder.append(endpointClass);
builder.append(",path=");
builder.append(path);
builder.append(",decoders=");
builder.append(decoders);
builder.append(",encoders=");
builder.append(encoders);
builder.append(",subprotocols=");
builder.append(subprotocols);
builder.append(",extensions=");
builder.append(extensions);
builder.append("]");
return builder.toString();
}
}

View File

@ -0,0 +1,47 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.server.internal;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper;
import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator;
public class BasicServerEndpointConfig extends ServerEndpointConfigWrapper
{
private final String _path;
public BasicServerEndpointConfig(Class<?> endpointClass, String path)
{
ServerEndpointConfig config = Builder.create(endpointClass, "/")
.configurator(new ContainerDefaultConfigurator())
.build();
_path = path;
init(config);
}
@Override
public String getPath()
{
if (_path == null)
throw new RuntimeException("Path is undefined");
return _path;
}
}

View File

@ -38,6 +38,7 @@ import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
import org.eclipse.jetty.websocket.javax.common.ConfiguredEndpoint;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketExtension;
import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;

View File

@ -159,7 +159,6 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer
return frameHandlerFactory;
}
@Override
public void addEndpoint(Class<?> endpointClass) throws DeploymentException
{
if (endpointClass == null)

View File

@ -38,6 +38,12 @@ public class JavaxWebSocketServerFrameHandlerFactory extends JavaxWebSocketClien
super(container, new PathParamIdentifier());
}
@Override
public EndpointConfig newDefaultEndpointConfig(Class<?> endpointClass, String path)
{
return new BasicServerEndpointConfig(endpointClass, path);
}
@Override
public JavaxWebSocketFrameHandlerMetadata createMetadata(Class<?> endpointClass, EndpointConfig endpointConfig)
{

View File

@ -25,6 +25,7 @@ import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.http.pathmap.UriTemplatePathSpec;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.websocket.javax.common.PathParamProvider;
import org.eclipse.jetty.websocket.javax.common.ServerEndpointConfigWrapper;
/**
* Make {@link javax.websocket.server.PathParam} information from the incoming request available

View File

@ -1,100 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.server.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.websocket.Decoder;
import javax.websocket.Encoder;
import javax.websocket.Extension;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.websocket.javax.server.config.ContainerDefaultConfigurator;
public class UndefinedServerEndpointConfig implements ServerEndpointConfig
{
private final List<Class<? extends Decoder>> decoders;
private final List<Class<? extends Encoder>> encoders;
private final List<Extension> extensions;
private final List<String> subprotocols;
private final ServerEndpointConfig.Configurator configurator;
private final Class<?> endpointClass;
private Map<String, Object> userProperties;
public UndefinedServerEndpointConfig(Class<?> endpointClass)
{
this.endpointClass = endpointClass;
this.decoders = new ArrayList<>();
this.encoders = new ArrayList<>();
this.subprotocols = new ArrayList<>();
this.extensions = new ArrayList<>();
this.userProperties = new HashMap<>();
this.configurator = new ContainerDefaultConfigurator();
}
@Override
public List<Class<? extends Encoder>> getEncoders()
{
return encoders;
}
@Override
public List<Class<? extends Decoder>> getDecoders()
{
return decoders;
}
@Override
public Map<String, Object> getUserProperties()
{
return userProperties;
}
@Override
public Class<?> getEndpointClass()
{
return endpointClass;
}
@Override
public String getPath()
{
throw new RuntimeException("Using an UndefinedServerEndpointConfig");
}
@Override
public List<String> getSubprotocols()
{
return subprotocols;
}
@Override
public List<Extension> getExtensions()
{
return extensions;
}
@Override
public ServerEndpointConfig.Configurator getConfigurator()
{
return configurator;
}
}

View File

@ -23,6 +23,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
@ -35,23 +36,26 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ServerEndpoint("/")
@ClientEndpoint
@ClientEndpoint()
public class EventSocket
{
private static final Logger LOG = Log.getLogger(EventSocket.class);
public Session session;
public EndpointConfig endpointConfig;
public BlockingQueue<String> messageQueue = new BlockingArrayQueue<>();
public volatile Throwable error = null;
public volatile CloseReason closeReason = null;
public CountDownLatch openLatch = new CountDownLatch(1);
public CountDownLatch closeLatch = new CountDownLatch(1);
@OnOpen
public void onOpen(Session session)
public void onOpen(Session session, EndpointConfig endpointConfig)
{
this.session = session;
this.endpointConfig = endpointConfig;
if (LOG.isDebugEnabled())
LOG.debug("{} onOpen(): {}", toString(), session);
openLatch.countDown();
@ -70,6 +74,8 @@ public class EventSocket
{
if (LOG.isDebugEnabled())
LOG.debug("{} onClose(): {}", toString(), reason);
closeReason = reason;
closeLatch.countDown();
}

View File

@ -0,0 +1,152 @@
//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.javax.tests;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.EndpointConfig;
import javax.websocket.HandshakeResponse;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketSession;
import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class JettySpecificConfigTest
{
private Server _server;
private ServerConnector _connector;
private ServletContextHandler _context;
@ServerEndpoint(value = "/", configurator = JettyServerConfigurator.class)
public static class EchoParamSocket
{
private Session session;
@OnOpen
public void onOpen(Session session)
{
this.session = session;
JavaxWebSocketSession javaxSession = (JavaxWebSocketSession)session;
assertThat(javaxSession.getCoreSession().isAutoFragment(), is(false));
assertThat(javaxSession.getCoreSession().getMaxFrameSize(), is(1337L));
}
@OnMessage
public void onMessage(String message) throws IOException
{
session.getBasicRemote().sendText(message);
}
}
public static class JettyServerConfigurator extends ServerEndpointConfig.Configurator
{
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
{
Map<String, Object> userProperties = sec.getUserProperties();
userProperties.put("org.eclipse.jetty.websocket.autoFragment", false);
userProperties.put("org.eclipse.jetty.websocket.maxFrameSize", 1337L);
}
}
@ClientEndpoint
public static class ClientConfigSocket extends EventSocket
{
@Override
public void onOpen(Session session, EndpointConfig endpointConfig)
{
super.onOpen(session, endpointConfig);
Map<String, Object> userProperties = session.getUserProperties();
userProperties.put("org.eclipse.jetty.websocket.autoFragment", false);
userProperties.put("org.eclipse.jetty.websocket.maxFrameSize", 1337L);
}
}
@BeforeEach
public void startContainer() throws Exception
{
_server = new Server();
_connector = new ServerConnector(_server);
_server.addConnector(_connector);
_context = new ServletContextHandler(ServletContextHandler.SESSIONS);
_context.setContextPath("/");
_server.setHandler(_context);
JavaxWebSocketServletContainerInitializer.configure(_context,
(context, container) -> container.addEndpoint(EchoParamSocket.class));
_server.start();
}
@AfterEach
public void stopContainer() throws Exception
{
_server.stop();
}
@Test
public void testJettySpecificConfig() throws Exception
{
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
EventSocket clientEndpoint = new ClientConfigSocket();
URI serverUri = URI.create("ws://localhost:"+ _connector.getLocalPort());
Session session = container.connectToServer(clientEndpoint, serverUri);
// Check correct client config is set.
JavaxWebSocketSession javaxSession = (JavaxWebSocketSession)session;
assertThat(javaxSession.getCoreSession().isAutoFragment(), is(false));
assertThat(javaxSession.getCoreSession().getMaxFrameSize(), is(1337L));
// Send and receive an echo.
session.getBasicRemote().sendText("echo");
String resp = clientEndpoint.messageQueue.poll(1, TimeUnit.SECONDS);
assertThat("Response echo", resp, is("echo"));
// Close the Session.
session.close();
assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS));
assertThat(clientEndpoint.closeReason.getCloseCode(), is(CloseReason.CloseCodes.NO_STATUS_CODE));
assertNull(clientEndpoint.error);
}
}

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.websocket.javax.tests.client;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.javax.client.BasicClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler;
@ -43,7 +44,7 @@ public abstract class AbstractClientSessionTest
UpgradeRequest upgradeRequest = new UpgradeRequestAdapter();
JavaxWebSocketFrameHandler frameHandler = container.newFrameHandler(websocketPojo, upgradeRequest);
FrameHandler.CoreSession coreSession = new FrameHandler.CoreSession.Empty();
session = new JavaxWebSocketSession(container, coreSession, frameHandler, null);
session = new JavaxWebSocketSession(container, coreSession, frameHandler, new BasicClientEndpointConfig());
}
@AfterAll

View File

@ -27,7 +27,7 @@ import javax.websocket.ClientEndpointConfig;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.CloseStatus;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.BasicClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer;
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandler;
import org.eclipse.jetty.websocket.javax.common.UpgradeRequest;
@ -96,7 +96,7 @@ public class OnCloseTest
{
WSEventTracker endpoint = (WSEventTracker)testcase.closeClass.getConstructor().newInstance();
ClientEndpointConfig config = new EmptyClientEndpointConfig();
ClientEndpointConfig config = new BasicClientEndpointConfig();
// TODO: use ConfiguredEndpoint here?
JavaxWebSocketClientContainer container = new JavaxWebSocketClientContainer();

View File

@ -30,7 +30,7 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.websocket.core.Frame;
import org.eclipse.jetty.websocket.core.FrameHandler;
import org.eclipse.jetty.websocket.core.OpCode;
import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.BasicClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer;
import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientFrameHandlerFactory;
import org.eclipse.jetty.websocket.javax.common.ConfiguredEndpoint;
@ -71,7 +71,7 @@ public class SessionAddMessageHandlerTest
// Container
container = new JavaxWebSocketClientContainer();
container.start();
ClientEndpointConfig endpointConfig = new EmptyClientEndpointConfig();
ClientEndpointConfig endpointConfig = new BasicClientEndpointConfig();
ConfiguredEndpoint ei = new ConfiguredEndpoint(new DummyEndpoint(), endpointConfig);
UpgradeRequest handshakeRequest = new UpgradeRequestAdapter();

View File

@ -28,7 +28,7 @@ import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;
import org.eclipse.jetty.toolchain.test.Hex;
import org.eclipse.jetty.websocket.javax.common.BasicEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.BasicClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException;
import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders;
import org.eclipse.jetty.websocket.javax.common.decoders.IntegerDecoder;
@ -49,7 +49,7 @@ public class AvailableDecodersTest
@BeforeAll
public static void initConfig()
{
testConfig = new BasicEndpointConfig();
testConfig = new BasicClientEndpointConfig();
}
private AvailableDecoders decoders = new AvailableDecoders(testConfig);

View File

@ -30,7 +30,7 @@ import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;
import org.eclipse.jetty.toolchain.test.Hex;
import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.BasicClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException;
import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders;
import org.eclipse.jetty.websocket.javax.common.encoders.IntegerEncoder;
@ -50,7 +50,7 @@ public class AvailableEncodersTest
@BeforeAll
public static void initConfig()
{
testConfig = new EmptyClientEndpointConfig();
testConfig = new BasicClientEndpointConfig();
}
private AvailableEncoders encoders = new AvailableEncoders(testConfig);

View File

@ -24,7 +24,7 @@ import javax.websocket.EndpointConfig;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.javax.client.EmptyClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.client.BasicClientEndpointConfig;
import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders;
import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders;
import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer;
@ -62,7 +62,7 @@ public abstract class AbstractJavaxWebSocketServerFrameHandlerTest
public AbstractJavaxWebSocketServerFrameHandlerTest()
{
endpointConfig = new EmptyClientEndpointConfig();
endpointConfig = new BasicClientEndpointConfig();
encoders = new AvailableEncoders(endpointConfig);
decoders = new AvailableDecoders(endpointConfig);
uriParams = new HashMap<>();