393473 - Add support for JSR-356 (javax.websocket) draft
+ Start of @WebSocketClient class/method scanning with tests
This commit is contained in:
parent
e27ad8ef5c
commit
2faba0bf4b
|
@ -1,75 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.endpoints;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.AbstractMethodAnnotationScanner;
|
||||
|
||||
/**
|
||||
* Cache for discovered javax.websocket {@link WebSocketEndpoint @WebSocketEndpoint} annotated websockets
|
||||
*/
|
||||
public class JavaxPojoAnnotationCache extends AbstractMethodAnnotationScanner<JavaxPojoMetadata>
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(JavaxPojoAnnotationCache.class);
|
||||
public static final JavaxPojoAnnotationCache INSTANCE = new JavaxPojoAnnotationCache();
|
||||
|
||||
public synchronized static JavaxPojoMetadata discover(Class<?> websocket)
|
||||
{
|
||||
// TODO: move to server side deployer
|
||||
// WebSocketEndpoint anno = websocket.getAnnotation(WebSocketEndpoint.class);
|
||||
// if (anno == null)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
JavaxPojoMetadata metadata = INSTANCE.cache.get(websocket);
|
||||
if (metadata == null)
|
||||
{
|
||||
metadata = new JavaxPojoMetadata();
|
||||
INSTANCE.scanMethodAnnotations(metadata,websocket);
|
||||
INSTANCE.cache.put(websocket,metadata);
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public static JavaxPojoMetadata discover(Object websocket)
|
||||
{
|
||||
return discover(websocket.getClass());
|
||||
}
|
||||
|
||||
private ConcurrentHashMap<Class<?>, JavaxPojoMetadata> cache;
|
||||
|
||||
public JavaxPojoAnnotationCache()
|
||||
{
|
||||
cache = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodAnnotation(JavaxPojoMetadata metadata, Class<?> pojo, Method method, Annotation annotation)
|
||||
{
|
||||
LOG.debug("onMethodAnnotation({}, {}, {}, {})",metadata,pojo,method,annotation);
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
|
@ -28,8 +28,12 @@ import org.eclipse.jetty.websocket.common.CloseInfo;
|
|||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
|
||||
public class JsrAnnotatedEventDriver implements EventDriver
|
||||
public class JsrAnnotatedClientEventDriver implements EventDriver
|
||||
{
|
||||
public JsrAnnotatedClientEventDriver(WebSocketPolicy policy, Object websocket, JsrAnnotatedMetadata metadata)
|
||||
{
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingError(WebSocketException e)
|
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.websocket.WebSocketClient;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriverImpl;
|
||||
|
||||
/**
|
||||
* {@link EventDriverImpl} for {@link WebSocketClient @WebSocketClient} annotated classes
|
||||
*/
|
||||
public class JsrAnnotatedClientImpl implements EventDriverImpl
|
||||
{
|
||||
private ConcurrentHashMap<Class<?>, JsrAnnotatedMetadata> cache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public EventDriver create(Object websocket, WebSocketPolicy policy)
|
||||
{
|
||||
Class<?> websocketClass = websocket.getClass();
|
||||
|
||||
WebSocketClient wsclient = websocketClass.getAnnotation(WebSocketClient.class);
|
||||
if (wsclient == null)
|
||||
{
|
||||
throw new InvalidWebSocketException("Cannot handle @WebSocketClient annotations here");
|
||||
}
|
||||
|
||||
JsrAnnotatedMetadata metadata = cache.get(websocketClass);
|
||||
if (metadata == null)
|
||||
{
|
||||
JsrAnnotatedClientScanner scanner = new JsrAnnotatedClientScanner(websocketClass);
|
||||
metadata = scanner.scan();
|
||||
cache.put(websocketClass,metadata);
|
||||
}
|
||||
|
||||
return new JsrAnnotatedClientEventDriver(policy,websocket,metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeRule()
|
||||
{
|
||||
return "class annotated with @" + WebSocketClient.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Object websocket)
|
||||
{
|
||||
return (websocket.getClass().getAnnotation(WebSocketClient.class) != null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.endpoints;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.EndpointConfiguration;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketClose;
|
||||
import javax.websocket.WebSocketError;
|
||||
import javax.websocket.WebSocketMessage;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.common.events.ParamList;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.AbstractMethodAnnotationScanner;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.CallableMethod;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.JsrMethodParameters.Param;
|
||||
|
||||
/**
|
||||
* Scanner for javax.websocket {@link WebSocketEndpoint @WebSocketEndpoint} and {@link WebSocketClient @WebSocketClient} annotated websockets
|
||||
*/
|
||||
public class JsrAnnotatedClientScanner extends AbstractMethodAnnotationScanner<JsrAnnotatedMetadata>
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(JsrAnnotatedClientScanner.class);
|
||||
|
||||
private static final ParamList validOpenParams;
|
||||
private static final ParamList validCloseParams;
|
||||
private static final ParamList validErrorParams;
|
||||
|
||||
static
|
||||
{
|
||||
validOpenParams = new ParamList();
|
||||
validOpenParams.addParams(Session.class);
|
||||
validOpenParams.addParams(EndpointConfiguration.class);
|
||||
|
||||
validCloseParams = new ParamList();
|
||||
validCloseParams.addParams(Session.class);
|
||||
validCloseParams.addParams(CloseReason.class);
|
||||
|
||||
validErrorParams = new ParamList();
|
||||
validErrorParams.addParams(Session.class);
|
||||
validErrorParams.addParams(Throwable.class);
|
||||
}
|
||||
|
||||
protected final Class<?> pojo;
|
||||
protected final Class<? extends Encoder> encoders[];
|
||||
protected final Class<? extends Decoder> decoders[];
|
||||
|
||||
public JsrAnnotatedClientScanner(Class<?> websocket)
|
||||
{
|
||||
this.pojo = websocket;
|
||||
|
||||
WebSocketClient anno = websocket.getAnnotation(WebSocketClient.class);
|
||||
if (anno == null)
|
||||
{
|
||||
throw new InvalidWebSocketException("Unsupported WebSocket object, missing @" + WebSocketClient.class + " annotation");
|
||||
}
|
||||
|
||||
this.encoders = anno.encoders();
|
||||
this.decoders = anno.decoders();
|
||||
}
|
||||
|
||||
private void assertValidJsrSignature(Method method, Class<? extends Annotation> annoClass, ParamList validParams)
|
||||
{
|
||||
JsrMethodParameters params = new JsrMethodParameters(method);
|
||||
|
||||
// First, find the path-mapping parameters
|
||||
for (Param param : params)
|
||||
{
|
||||
String varname = getPathMappingParameterVariable(param.type);
|
||||
if (varname != null)
|
||||
{
|
||||
param.setPathParamVariable(varname);
|
||||
}
|
||||
}
|
||||
|
||||
// Next find the valid parameter sets and flag them
|
||||
for (Class<?>[] paramSet : validParams)
|
||||
{
|
||||
// Each entry in validParams is a set of possible valid references.
|
||||
// If not all parts of the set are present, that set isn't valid for the provided parameters.
|
||||
|
||||
if (params.containsParameterSet(paramSet))
|
||||
{
|
||||
// flag as valid
|
||||
params.setValid(paramSet);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, ensure we identified all of the parameters
|
||||
for (Param param : params)
|
||||
{
|
||||
if (param.isValid() == false)
|
||||
{
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Encountered invalid/unhandled parameter <");
|
||||
err.append(param.type.getName());
|
||||
err.append("> (position ").append(param.index).append(") in method <");
|
||||
err.append(method.getName());
|
||||
err.append("> of object <");
|
||||
err.append(pojo.getName());
|
||||
err.append("> that doesn't fit the requirements for the @");
|
||||
err.append(annoClass.getSimpleName());
|
||||
err.append(" annotation");
|
||||
|
||||
throw new InvalidSignatureException(err.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getPathMappingParameterVariable(Class<?> type)
|
||||
{
|
||||
/* override to implement */
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodAnnotation(JsrAnnotatedMetadata metadata, Class<?> pojo, Method method, Annotation annotation)
|
||||
{
|
||||
LOG.debug("onMethodAnnotation({}, {}, {}, {})",metadata,pojo,method,annotation);
|
||||
|
||||
if (isAnnotation(annotation,WebSocketOpen.class))
|
||||
{
|
||||
assertIsPublicNonStatic(method);
|
||||
assertIsReturn(method,Void.TYPE);
|
||||
assertValidJsrSignature(method,WebSocketOpen.class,validOpenParams);
|
||||
assertUnset(metadata.onOpen,WebSocketOpen.class,method);
|
||||
metadata.onOpen = new CallableMethod(pojo,method);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAnnotation(annotation,WebSocketClose.class))
|
||||
{
|
||||
assertIsPublicNonStatic(method);
|
||||
assertIsReturn(method,Void.TYPE);
|
||||
assertValidJsrSignature(method,WebSocketClose.class,validCloseParams);
|
||||
assertUnset(metadata.onClose,WebSocketClose.class,method);
|
||||
metadata.onClose = new CallableMethod(pojo,method);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAnnotation(annotation,WebSocketError.class))
|
||||
{
|
||||
assertIsPublicNonStatic(method);
|
||||
assertIsReturn(method,Void.TYPE);
|
||||
assertValidJsrSignature(method,WebSocketError.class,validErrorParams);
|
||||
assertUnset(metadata.onError,WebSocketError.class,method);
|
||||
metadata.onError = new CallableMethod(pojo,method);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAnnotation(annotation,WebSocketMessage.class))
|
||||
{
|
||||
assertIsPublicNonStatic(method);
|
||||
JsrMessageCallableMethod callable = new JsrMessageCallableMethod(pojo,method);
|
||||
callable.setReturnType(method.getReturnType(),encoders);
|
||||
|
||||
// TODO: create MessageHandler wrapper for methods
|
||||
|
||||
// TODO: ensure conflicting parameters not present
|
||||
// assertUnset(metadata.onMessage,WebSocketMessage.class,method);
|
||||
|
||||
// metadata.onMessage = new CallableMethod(pojo,method);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public JsrAnnotatedMetadata scan()
|
||||
{
|
||||
JsrAnnotatedMetadata metadata = new JsrAnnotatedMetadata();
|
||||
scanMethodAnnotations(metadata,pojo);
|
||||
return metadata;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package org.eclipse.jetty.websocket.jsr356.endpoints;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriverImpl;
|
||||
|
||||
public class JsrAnnotatedImpl implements EventDriverImpl
|
||||
{
|
||||
|
||||
@Override
|
||||
public EventDriver create(Object websocket, WebSocketPolicy policy)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String describeRule()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Object websocket)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.endpoints;
|
||||
|
||||
import javax.websocket.WebSocketClose;
|
||||
import javax.websocket.WebSocketError;
|
||||
import javax.websocket.WebSocketMessage;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.CallableMethod;
|
||||
|
||||
/**
|
||||
* Represents the metadata associated with Annotation discovery of a specific class.
|
||||
*/
|
||||
public class JsrAnnotatedMetadata
|
||||
{
|
||||
/**
|
||||
* Callable for @{@link WebSocketOpen} annotation
|
||||
*/
|
||||
public CallableMethod onOpen;
|
||||
/**
|
||||
* Callable for @{@link WebSocketClose} annotation
|
||||
*/
|
||||
public CallableMethod onClose;
|
||||
/**
|
||||
* Callable for @{@link WebSocketError} annotation
|
||||
*/
|
||||
public CallableMethod onError;
|
||||
/**
|
||||
* Callable for @{@link WebSocketMessage} annotation dealing with Text Message Format
|
||||
*/
|
||||
public CallableMethod onText;
|
||||
/**
|
||||
* Callable for @{@link WebSocketMessage} annotation dealing with Binary Message Format
|
||||
*/
|
||||
public CallableMethod onBinary;
|
||||
/**
|
||||
* Callable for @{@link WebSocketMessage} annotation dealing with Pong Message Format
|
||||
*/
|
||||
public CallableMethod onPong;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.Encoder;
|
||||
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.CallableMethod;
|
||||
|
||||
public class JsrMessageCallableMethod extends CallableMethod
|
||||
{
|
||||
private Class<?> returnType;
|
||||
|
||||
public JsrMessageCallableMethod(Class<?> pojo, Method method)
|
||||
{
|
||||
super(pojo,method);
|
||||
}
|
||||
|
||||
public void setReturnType(Class<?> returnType, Class<? extends Encoder> encoders[])
|
||||
{
|
||||
if (Void.TYPE.equals(returnType))
|
||||
{
|
||||
// Void type
|
||||
this.returnType = returnType;
|
||||
return;
|
||||
}
|
||||
|
||||
if (returnType.isArray() && Byte.TYPE.equals(returnType))
|
||||
{
|
||||
// A byte array
|
||||
this.returnType = returnType;
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.toName(returnType) != null)
|
||||
{
|
||||
// A primitive (including String)
|
||||
this.returnType = returnType;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ByteBuffer.class.isAssignableFrom(returnType))
|
||||
{
|
||||
// A nio ByteBuffer
|
||||
this.returnType = returnType;
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine if encoder exists for this return type
|
||||
for (Class<? extends Encoder> encoder : encoders)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.JsrMethodParameters.Param;
|
||||
|
||||
public class JsrMethodParameters extends ArrayList<Param>
|
||||
{
|
||||
public static class Param
|
||||
{
|
||||
public int index;
|
||||
public Class<?> type;
|
||||
private boolean valid = false;
|
||||
private String pathParamVariable = null;
|
||||
|
||||
public Param(int idx, Class<?> type)
|
||||
{
|
||||
this.index = idx;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPathParamVariable()
|
||||
{
|
||||
return this.pathParamVariable;
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setPathParamVariable(String name)
|
||||
{
|
||||
this.pathParamVariable = name;
|
||||
}
|
||||
|
||||
public void setValid(boolean flag)
|
||||
{
|
||||
this.valid = flag;
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -181761176209945279L;
|
||||
|
||||
public JsrMethodParameters(Method method)
|
||||
{
|
||||
Class<?> ptypes[] = method.getParameterTypes();
|
||||
int len = ptypes.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
add(new Param(i,ptypes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsParameterSet(Class<?>[] paramSet)
|
||||
{
|
||||
for (Class<?> entry : paramSet)
|
||||
{
|
||||
boolean found = false;
|
||||
for (Param param : this)
|
||||
{
|
||||
if (param.type.isAssignableFrom(entry))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setValid(Class<?>[] paramSet)
|
||||
{
|
||||
for (Class<?> entry : paramSet)
|
||||
{
|
||||
for (Param param : this)
|
||||
{
|
||||
if (param.type.isAssignableFrom(entry))
|
||||
{
|
||||
param.setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.CallableMethod;
|
||||
import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.BasicOpenCloseSessionSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.BasicOpenCloseSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.BasicOpenSessionSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.BasicOpenSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.InvalidOpenCloseReasonSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.InvalidOpenIntSocket;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.samples.InvalidOpenSessionIntSocket;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsrAnnotatedClientScannerTest
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(JsrAnnotatedClientScannerTest.class);
|
||||
|
||||
private void assertHasCallable(String msg, CallableMethod callable, Class<?>... expectedParameters)
|
||||
{
|
||||
Assert.assertThat(msg,notNullValue());
|
||||
int len = expectedParameters.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
Class<?> expectedParam = expectedParameters[i];
|
||||
Class<?> actualParam = callable.getParamTypes()[i];
|
||||
|
||||
Assert.assertTrue("Parameter[" + i + "] - expected:[" + expectedParam + "], actual:[" + actualParam + "]",actualParam.equals(expectedParam));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertInvalidAnnotationSignature(Class<?> pojo, Class<? extends Annotation> expectedAnnoClass)
|
||||
{
|
||||
JsrAnnotatedClientScanner scanner = new JsrAnnotatedClientScanner(pojo);
|
||||
try
|
||||
{
|
||||
scanner.scan();
|
||||
Assert.fail("Expected " + InvalidSignatureException.class + " with message that references " + expectedAnnoClass + " annotation");
|
||||
}
|
||||
catch (InvalidSignatureException e)
|
||||
{
|
||||
LOG.debug("{}:{}",e.getClass(),e.getMessage());
|
||||
Assert.assertThat("Message",e.getMessage(),containsString(expectedAnnoClass.getSimpleName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_BasicOpen()
|
||||
{
|
||||
JsrAnnotatedClientScanner scanner = new JsrAnnotatedClientScanner(BasicOpenSocket.class);
|
||||
JsrAnnotatedMetadata metadata = scanner.scan();
|
||||
Assert.assertThat("Metadata",metadata,notNullValue());
|
||||
assertHasCallable("Metadata.onOpen",metadata.onOpen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_BasicOpenClose()
|
||||
{
|
||||
JsrAnnotatedClientScanner scanner = new JsrAnnotatedClientScanner(BasicOpenCloseSocket.class);
|
||||
JsrAnnotatedMetadata metadata = scanner.scan();
|
||||
|
||||
Assert.assertThat("Metadata",metadata,notNullValue());
|
||||
|
||||
assertHasCallable("Metadata.onOpen",metadata.onOpen);
|
||||
assertHasCallable("Metadata.onClose",metadata.onClose,CloseReason.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_BasicOpenSession()
|
||||
{
|
||||
JsrAnnotatedClientScanner scanner = new JsrAnnotatedClientScanner(BasicOpenSessionSocket.class);
|
||||
JsrAnnotatedMetadata metadata = scanner.scan();
|
||||
Assert.assertThat("Metadata",metadata,notNullValue());
|
||||
assertHasCallable("Metadata.onOpen",metadata.onOpen,Session.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_BasicSessionOpenClose()
|
||||
{
|
||||
JsrAnnotatedClientScanner scanner = new JsrAnnotatedClientScanner(BasicOpenCloseSessionSocket.class);
|
||||
JsrAnnotatedMetadata metadata = scanner.scan();
|
||||
|
||||
Assert.assertThat("Metadata",metadata,notNullValue());
|
||||
|
||||
assertHasCallable("Metadata.onOpen",metadata.onOpen);
|
||||
assertHasCallable("Metadata.onClose",metadata.onClose,CloseReason.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_InvalidOpenCloseReason()
|
||||
{
|
||||
assertInvalidAnnotationSignature(InvalidOpenCloseReasonSocket.class,WebSocketOpen.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_InvalidOpenInt()
|
||||
{
|
||||
assertInvalidAnnotationSignature(InvalidOpenIntSocket.class,WebSocketOpen.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScan_InvalidOpenSessionInt()
|
||||
{
|
||||
assertInvalidAnnotationSignature(InvalidOpenSessionIntSocket.class,WebSocketOpen.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.CloseReason.CloseCode;
|
||||
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Abstract base socket used for tracking state and events within the socket for testing reasons.
|
||||
*/
|
||||
public abstract class TrackingSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TrackingSocket.class);
|
||||
|
||||
public CloseReason closeReason;
|
||||
public BlockingQueue<String> eventQueue = new BlockingArrayQueue<String>();
|
||||
public BlockingQueue<Throwable> errorQueue = new BlockingArrayQueue<>();
|
||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public CountDownLatch dataLatch = new CountDownLatch(1);
|
||||
|
||||
public void assertClose(CloseCode expectedCode, String expectedReason) throws InterruptedException
|
||||
{
|
||||
assertCloseCode(expectedCode);
|
||||
assertCloseReason(expectedReason);
|
||||
}
|
||||
|
||||
public void assertCloseCode(CloseCode expectedCode) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Closed",closeLatch.await(50,TimeUnit.MILLISECONDS),is(true));
|
||||
Assert.assertThat("CloseReason",closeReason,notNullValue());
|
||||
Assert.assertThat("Close Code",closeReason.getCloseCode(),is(expectedCode));
|
||||
}
|
||||
|
||||
private void assertCloseReason(String expectedReason)
|
||||
{
|
||||
Assert.assertThat("Close Reason",closeReason.getReasonPhrase(),is(expectedReason));
|
||||
}
|
||||
|
||||
protected void addEvent(String format, Object... args)
|
||||
{
|
||||
eventQueue.add(String.format(format,args));
|
||||
}
|
||||
|
||||
protected void addError(Throwable t)
|
||||
{
|
||||
errorQueue.add(t);
|
||||
}
|
||||
|
||||
public void assertIsOpen() throws InterruptedException
|
||||
{
|
||||
assertWasOpened();
|
||||
assertNotClosed();
|
||||
}
|
||||
|
||||
public void assertEvent(String expected)
|
||||
{
|
||||
String actual = eventQueue.poll();
|
||||
Assert.assertEquals("Event",expected,actual);
|
||||
}
|
||||
|
||||
public void assertNotClosed()
|
||||
{
|
||||
Assert.assertThat("Closed Latch",closeLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertNotOpened()
|
||||
{
|
||||
Assert.assertThat("Open Latch",openLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertWasOpened() throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Opened",openLatch.await(500,TimeUnit.MILLISECONDS),is(true));
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
eventQueue.clear();
|
||||
errorQueue.clear();
|
||||
}
|
||||
|
||||
public void waitForClose(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForConnected(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Connected",openLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForData(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
LOG.debug("Waiting for message");
|
||||
Assert.assertThat("Data Received",dataLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketClose;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class BasicOpenCloseSessionSocket extends TrackingSocket
|
||||
{
|
||||
@WebSocketClose
|
||||
public void onClose(CloseReason close, Session session)
|
||||
{
|
||||
addEvent("onClose(%s, %s)",close,session);
|
||||
this.closeReason = close;
|
||||
closeLatch.countDown();
|
||||
}
|
||||
|
||||
@WebSocketOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
addEvent("onOpen(%s)",session);
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketClose;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class BasicOpenCloseSocket extends TrackingSocket
|
||||
{
|
||||
@WebSocketOpen
|
||||
public void onOpen() {
|
||||
openLatch.countDown();
|
||||
}
|
||||
|
||||
@WebSocketClose
|
||||
public void onClose(CloseReason close) {
|
||||
this.closeReason = close;
|
||||
closeLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class BasicOpenSessionSocket extends TrackingSocket
|
||||
{
|
||||
@WebSocketOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// Copyright (c) 1995-2013 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
|
||||
|
@ -16,12 +16,19 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.endpoints;
|
||||
package org.eclipse.jetty.websocket.jsr356.endpoints.samples;
|
||||
|
||||
/**
|
||||
* Represents the metadata associated with Annotation discovery of a specific class.
|
||||
*/
|
||||
public class JavaxPojoMetadata
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class BasicOpenSocket extends TrackingSocket
|
||||
{
|
||||
|
||||
@WebSocketOpen
|
||||
public void onOpen()
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class InvalidOpenCloseReasonSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Open Method Declaration (parameter type int)
|
||||
*/
|
||||
@WebSocketOpen
|
||||
public void onOpen(int count)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class InvalidOpenIntSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Open Method Declaration (parameter type CloseReason)
|
||||
*/
|
||||
@WebSocketOpen
|
||||
public void onOpen(CloseReason close)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketClient;
|
||||
import javax.websocket.WebSocketOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@WebSocketClient
|
||||
public class InvalidOpenSessionIntSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Open Method Declaration (parameter of type int)
|
||||
*/
|
||||
@WebSocketOpen
|
||||
public void onOpen(Session session, int count)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG
|
Loading…
Reference in New Issue