Trailing merge fixes
This commit is contained in:
parent
57bbf67735
commit
b71be7c808
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
public final class CloseableLifeCycle<T extends LifeCycle> implements AutoCloseable
|
||||
{
|
||||
public T lifecycle;
|
||||
|
||||
public CloseableLifeCycle(T lifecycle) throws Exception
|
||||
{
|
||||
this.lifecycle = lifecycle;
|
||||
this.lifecycle.start();
|
||||
}
|
||||
|
||||
public T get()
|
||||
{
|
||||
return lifecycle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception
|
||||
{
|
||||
lifecycle.stop();
|
||||
}
|
||||
}
|
|
@ -47,7 +47,6 @@ import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
|||
import org.eclipse.jetty.websocket.common.function.CommonEndpointFunctions;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.UnorderedSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
import org.eclipse.jetty.websocket.jsr356.JsrSession;
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.AvailableDecoders;
|
||||
|
@ -420,7 +419,7 @@ public class JsrEndpointFunctions extends CommonEndpointFunctions<JsrSession>
|
|||
}
|
||||
}
|
||||
|
||||
argBuilder.addSignature(new UnorderedSignature(callArgs));
|
||||
argBuilder.addSignature(callArgs);
|
||||
|
||||
return argBuilder;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import javax.websocket.Session;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.UnorderedSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -80,7 +79,7 @@ public class JsrOnByteArrayFunction implements Function<byte[], Void>
|
|||
callArgs[idx++] = arg;
|
||||
}
|
||||
|
||||
argBuilder.addSignature(new UnorderedSignature(callArgs));
|
||||
argBuilder.addSignature(callArgs);
|
||||
|
||||
// Attempt to build callable
|
||||
this.callable = argBuilder.build(method);
|
||||
|
|
|
@ -28,7 +28,6 @@ import javax.websocket.Session;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.UnorderedSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -77,7 +76,7 @@ public class JsrOnByteBufferFunction implements Function<ByteBuffer, Void>
|
|||
callArgs[idx++] = arg;
|
||||
}
|
||||
|
||||
argBuilder.addSignature(new UnorderedSignature(callArgs));
|
||||
argBuilder.addSignature(callArgs);
|
||||
|
||||
// Attempt to build callable
|
||||
this.callable = argBuilder.build(method);
|
||||
|
|
|
@ -28,7 +28,6 @@ import javax.websocket.Session;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.UnorderedSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -78,7 +77,7 @@ public class JsrOnInputStreamFunction implements Function<InputStream, Void>
|
|||
callArgs[idx++] = arg;
|
||||
}
|
||||
|
||||
argBuilder.addSignature(new UnorderedSignature(callArgs));
|
||||
argBuilder.addSignature(callArgs);
|
||||
|
||||
// Attempt to build callable
|
||||
this.callable = argBuilder.build(method, callArgs);
|
||||
|
|
|
@ -18,8 +18,11 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.jsr356.server;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -33,129 +36,22 @@ import javax.websocket.server.ServerEndpoint;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
||||
import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SessionTrackingTest
|
||||
{
|
||||
private Server server;
|
||||
private ServerContainer serverContainer;
|
||||
private WebSocketServerFactory wsServerFactory;
|
||||
private URI serverURI;
|
||||
|
||||
@Before
|
||||
public void startServer() throws Exception
|
||||
public static class ClientSocket extends Endpoint
|
||||
{
|
||||
QueuedThreadPool serverThreads = new QueuedThreadPool();
|
||||
serverThreads.setName("server");
|
||||
server = new Server(serverThreads);
|
||||
ServerConnector serverConnector = new ServerConnector(server);
|
||||
serverConnector.setPort(0);
|
||||
server.addConnector(serverConnector);
|
||||
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
|
||||
servletContextHandler.setContextPath("/");
|
||||
server.setHandler(servletContextHandler);
|
||||
|
||||
serverContainer = WebSocketServerContainerInitializer.configureContext(servletContextHandler);
|
||||
serverContainer.addEndpoint(EchoSocket.class);
|
||||
|
||||
wsServerFactory = serverContainer.getBean(WebSocketServerFactory.class);
|
||||
|
||||
server.start();
|
||||
|
||||
serverURI = new URI("ws://localhost:" + serverConnector.getLocalPort());
|
||||
}
|
||||
|
||||
@After
|
||||
public void stopServer() throws Exception
|
||||
{
|
||||
if (server != null)
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRemoveSessions() throws Exception
|
||||
{
|
||||
// Create Client
|
||||
ClientContainer clientContainer = new ClientContainer();
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
clientContainer.getClient().setExecutor(clientThreads);
|
||||
try
|
||||
{
|
||||
CountDownLatch openedLatch = new CountDownLatch(2);
|
||||
CountDownLatch closedLatch = new CountDownLatch(2);
|
||||
wsServerFactory.addSessionListener(new WebSocketSession.Listener()
|
||||
{
|
||||
@Override
|
||||
public void onOpened(WebSocketSession session)
|
||||
{
|
||||
openedLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed(WebSocketSession session)
|
||||
{
|
||||
closedLatch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
clientContainer.start();
|
||||
|
||||
// Establish connections
|
||||
ClientSocket cli1 = new ClientSocket();
|
||||
clientContainer.connectToServer(cli1, serverURI.resolve("/test"));
|
||||
cli1.waitForOpen(1, TimeUnit.SECONDS);
|
||||
|
||||
// Establish new connection
|
||||
ClientSocket cli2 = new ClientSocket();
|
||||
clientContainer.connectToServer(cli2, serverURI.resolve("/test"));
|
||||
cli2.waitForOpen(1, TimeUnit.SECONDS);
|
||||
|
||||
openedLatch.await(5, TimeUnit.SECONDS);
|
||||
assertServerOpenConnectionCount(2);
|
||||
|
||||
// Establish close both connections
|
||||
cli1.session.close();
|
||||
cli2.session.close();
|
||||
|
||||
cli1.waitForClose(1, TimeUnit.SECONDS);
|
||||
cli2.waitForClose(1, TimeUnit.SECONDS);
|
||||
|
||||
closedLatch.await(5, TimeUnit.SECONDS);
|
||||
assertServerOpenConnectionCount(0);
|
||||
}
|
||||
finally
|
||||
{
|
||||
clientContainer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertServerOpenConnectionCount(int expectedCount)
|
||||
{
|
||||
Set<Session> sessions = serverContainer.getOpenSessions();
|
||||
int openCount = 0;
|
||||
for (Session session : sessions)
|
||||
{
|
||||
Assert.assertThat("Session.isopen: " + session, session.isOpen(), Matchers.is(true));
|
||||
openCount++;
|
||||
}
|
||||
Assert.assertThat("Open Session Count", openCount, Matchers.is(expectedCount));
|
||||
}
|
||||
|
||||
private static class ClientSocket extends Endpoint
|
||||
{
|
||||
private Session session;
|
||||
private CountDownLatch openLatch = new CountDownLatch(1);
|
||||
private CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public Session session;
|
||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config)
|
||||
|
@ -172,12 +68,12 @@ public class SessionTrackingTest
|
|||
|
||||
public void waitForOpen(long timeout, TimeUnit unit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("ClientSocket opened", openLatch.await(timeout, unit), Matchers.is(true));
|
||||
assertThat("ClientSocket opened",openLatch.await(timeout,unit),is(true));
|
||||
}
|
||||
|
||||
public void waitForClose(long timeout, TimeUnit unit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("ClientSocket opened", closeLatch.await(timeout, unit), Matchers.is(true));
|
||||
assertThat("ClientSocket opened",closeLatch.await(timeout,unit),is(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,4 +86,98 @@ public class SessionTrackingTest
|
|||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
private static Server server;
|
||||
private static WebSocketServerFactory wsServerFactory;
|
||||
private static URI serverURI;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
ServerConnector serverConnector = new ServerConnector(server);
|
||||
serverConnector.setPort(0);
|
||||
server.addConnector(serverConnector);
|
||||
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
|
||||
servletContextHandler.setContextPath("/");
|
||||
server.setHandler(servletContextHandler);
|
||||
|
||||
ServerContainer serverContainer = WebSocketServerContainerInitializer.configureContext(servletContextHandler);
|
||||
serverContainer.addEndpoint(EchoSocket.class);
|
||||
|
||||
wsServerFactory = serverContainer.getBean(WebSocketServerFactory.class);
|
||||
|
||||
server.start();
|
||||
|
||||
String host = serverConnector.getHost();
|
||||
if (StringUtil.isBlank(host))
|
||||
{
|
||||
host = "localhost";
|
||||
}
|
||||
serverURI = new URI("ws://" + host + ":" + serverConnector.getLocalPort());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer() throws Exception
|
||||
{
|
||||
if (server == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRemoveSessions() throws Exception
|
||||
{
|
||||
// Create Client
|
||||
ClientContainer clientContainer = new ClientContainer();
|
||||
try
|
||||
{
|
||||
clientContainer.start();
|
||||
|
||||
// Establish connections
|
||||
ClientSocket cli1 = new ClientSocket();
|
||||
clientContainer.connectToServer(cli1,serverURI.resolve("/test"));
|
||||
cli1.waitForOpen(1,TimeUnit.SECONDS);
|
||||
|
||||
// Assert open connections
|
||||
assertServerOpenConnectionCount(1);
|
||||
|
||||
// Establish new connection
|
||||
ClientSocket cli2 = new ClientSocket();
|
||||
clientContainer.connectToServer(cli2,serverURI.resolve("/test"));
|
||||
cli2.waitForOpen(1,TimeUnit.SECONDS);
|
||||
|
||||
// Assert open connections
|
||||
assertServerOpenConnectionCount(2);
|
||||
|
||||
// Establish close both connections
|
||||
cli1.session.close();
|
||||
cli2.session.close();
|
||||
|
||||
cli1.waitForClose(1,TimeUnit.SECONDS);
|
||||
cli2.waitForClose(1,TimeUnit.SECONDS);
|
||||
|
||||
// Assert open connections
|
||||
assertServerOpenConnectionCount(0);
|
||||
}
|
||||
finally
|
||||
{
|
||||
clientContainer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertServerOpenConnectionCount(int expectedCount)
|
||||
{
|
||||
Collection<javax.websocket.Session> sessions = wsServerFactory.getBeans(javax.websocket.Session.class);
|
||||
int openCount = 0;
|
||||
for (javax.websocket.Session session : sessions)
|
||||
{
|
||||
assertThat("Session.isopen: " + session,session.isOpen(),is(true));
|
||||
openCount++;
|
||||
}
|
||||
assertThat("Open Session Count",openCount,is(expectedCount));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -37,17 +36,14 @@ public class OnByteArrayFunction implements Function<byte[], Void>
|
|||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_BUFFER = new Arg(2, byte[].class);
|
||||
private static final Arg ARG_BUFFER = new Arg(2, byte[].class).required();
|
||||
private static final Arg ARG_OFFSET = new Arg(3, int.class);
|
||||
private static final Arg ARG_LENGTH = new Arg(4, int.class);
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_BUFFER));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_BUFFER, ARG_OFFSET, ARG_LENGTH));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_BUFFER));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_BUFFER, ARG_OFFSET, ARG_LENGTH));
|
||||
ARGBUILDER.addSignature(ARG_SESSION, ARG_BUFFER, ARG_OFFSET, ARG_LENGTH);
|
||||
}
|
||||
|
||||
public static DynamicArgs.Builder getDynamicArgsBuilder()
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -38,13 +37,12 @@ public class OnByteBufferFunction implements Function<ByteBuffer, Void>
|
|||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_BUFFER = new Arg(2, ByteBuffer.class);
|
||||
private static final Arg ARG_BUFFER = new Arg(2, ByteBuffer.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_BUFFER));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_BUFFER));
|
||||
ARGBUILDER.addSignature(ARG_SESSION, ARG_BUFFER);
|
||||
}
|
||||
|
||||
public static DynamicArgs.Builder getDynamicArgsBuilder()
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.eclipse.jetty.websocket.common.CloseInfo;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -44,10 +43,7 @@ public class OnCloseFunction implements Function<CloseInfo, Void>
|
|||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature());
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_STATUS_CODE, ARG_REASON));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_STATUS_CODE, ARG_REASON));
|
||||
ARGBUILDER.addSignature(ARG_SESSION, ARG_STATUS_CODE, ARG_REASON);
|
||||
}
|
||||
|
||||
private final Session session;
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -37,13 +36,12 @@ public class OnErrorFunction implements Function<Throwable, Void>
|
|||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_CAUSE = new Arg(2, Throwable.class);
|
||||
private static final Arg ARG_CAUSE = new Arg(2, Throwable.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_CAUSE));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_CAUSE));
|
||||
ARGBUILDER.addSignature(ARG_SESSION, ARG_CAUSE);
|
||||
}
|
||||
|
||||
private final Session session;
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
|||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -39,13 +38,12 @@ public class OnFrameFunction implements Function<Frame, Void>
|
|||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_FRAME = new Arg(2, Frame.class);
|
||||
private static final Arg ARG_FRAME = new Arg(2, Frame.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_FRAME));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_FRAME));
|
||||
ARGBUILDER.addSignature(ARG_SESSION, ARG_FRAME);
|
||||
}
|
||||
|
||||
private final Session session;
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -39,13 +38,12 @@ public class OnInputStreamFunction implements Function<InputStream, Void>
|
|||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_STREAM = new Arg(2, InputStream.class);
|
||||
private static final Arg ARG_STREAM = new Arg(2, InputStream.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_STREAM));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_STREAM));
|
||||
ARGBUILDER.addSignature(ARG_SESSION, ARG_STREAM);
|
||||
}
|
||||
|
||||
public static DynamicArgs.Builder getDynamicArgsBuilder()
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -36,13 +35,12 @@ import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
|||
public class OnOpenFunction<T extends Session> implements Function<T, Void>
|
||||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature());
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION));
|
||||
ARGBUILDER.addSignature(ARG_SESSION);
|
||||
}
|
||||
|
||||
private final Object endpoint;
|
||||
|
|
|
@ -20,15 +20,17 @@ package org.eclipse.jetty.websocket.common.function;
|
|||
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -36,15 +38,15 @@ import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
|||
*/
|
||||
public class OnReaderFunction implements Function<Reader, Void>
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(OnReaderFunction.class);
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_STREAM = new Arg(2, Reader.class);
|
||||
private static final Arg ARG_STREAM = new Arg(2, Reader.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_STREAM));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_STREAM));
|
||||
ARGBUILDER.addSignature(ARG_STREAM, ARG_SESSION);
|
||||
}
|
||||
|
||||
public static DynamicArgs.Builder getDynamicArgsBuilder()
|
||||
|
@ -82,6 +84,11 @@ public class OnReaderFunction implements Function<Reader, Void>
|
|||
@Override
|
||||
public Void apply(Reader stream)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("apply({}, {}, {})", endpoint, session, stream);
|
||||
|
||||
Objects.requireNonNull(stream, "Reader cannot be null");
|
||||
|
||||
this.callable.invoke(endpoint, session, stream);
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|||
import org.eclipse.jetty.websocket.common.InvalidSignatureException;
|
||||
import org.eclipse.jetty.websocket.common.reflect.Arg;
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs;
|
||||
import org.eclipse.jetty.websocket.common.reflect.ExactSignature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
/**
|
||||
|
@ -37,13 +36,12 @@ public class OnTextFunction implements Function<String, Void>
|
|||
{
|
||||
private static final DynamicArgs.Builder ARGBUILDER;
|
||||
private static final Arg ARG_SESSION = new Arg(1, Session.class);
|
||||
private static final Arg ARG_TEXT = new Arg(2, String.class);
|
||||
private static final Arg ARG_TEXT = new Arg(2, String.class).required();
|
||||
|
||||
static
|
||||
{
|
||||
ARGBUILDER = new DynamicArgs.Builder();
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_TEXT));
|
||||
ARGBUILDER.addSignature(new ExactSignature(ARG_SESSION, ARG_TEXT));
|
||||
ARGBUILDER.addSignature(ARG_TEXT, ARG_SESSION);
|
||||
}
|
||||
|
||||
public static DynamicArgs.Builder getDynamicArgsBuilder()
|
||||
|
|
|
@ -23,8 +23,12 @@ import java.nio.ByteBuffer;
|
|||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
public class ReaderMessageSink implements MessageSink
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ReaderMessageSink.class);
|
||||
private final Executor executor;
|
||||
private final Function<Reader, Void> onStreamFunction;
|
||||
private MessageReader stream;
|
||||
|
@ -54,6 +58,8 @@ public class ReaderMessageSink implements MessageSink
|
|||
executor.execute(() -> {
|
||||
// processing of errors is the responsibility
|
||||
// of the stream function
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("onStreamFunction.apply({})", stream);
|
||||
onStreamFunction.apply(stream);
|
||||
});
|
||||
}
|
||||
|
@ -62,7 +68,11 @@ public class ReaderMessageSink implements MessageSink
|
|||
{
|
||||
if (fin)
|
||||
{
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("stream.awaitClose() - {}", stream);
|
||||
stream.awaitClose();
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("stream recycled - {}", stream);
|
||||
stream = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,9 +123,9 @@ public class DynamicArgs
|
|||
return null;
|
||||
}
|
||||
|
||||
public Builder addSignature(Signature sig)
|
||||
public Builder addSignature(Arg... args)
|
||||
{
|
||||
signatures.add(sig);
|
||||
signatures.add(new UnorderedSignature(args));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common.reflect;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs.Signature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
public class ExactSignature implements Signature, Predicate<Method>
|
||||
{
|
||||
private final Arg[] params;
|
||||
|
||||
public ExactSignature()
|
||||
{
|
||||
this.params = new Arg[0];
|
||||
}
|
||||
|
||||
public ExactSignature(Arg... params)
|
||||
{
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate<Method> getPredicate()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Arg[] getCallArgs()
|
||||
{
|
||||
return this.params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Method method)
|
||||
{
|
||||
Class<?>[] types = method.getParameterTypes();
|
||||
if (types.length != params.length)
|
||||
return false;
|
||||
int len = params.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (!params[i].getType().equals(types[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void appendDescription(StringBuilder str)
|
||||
{
|
||||
str.append('(');
|
||||
boolean delim = false;
|
||||
for (Arg arg : params)
|
||||
{
|
||||
if (delim)
|
||||
{
|
||||
str.append(',');
|
||||
}
|
||||
str.append(' ');
|
||||
str.append(arg.getName());
|
||||
if (arg.isArray())
|
||||
{
|
||||
str.append("[]");
|
||||
}
|
||||
delim = true;
|
||||
}
|
||||
str.append(')');
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiFunction<Object, Object[], Object> getInvoker(Method method, Arg... callArgs)
|
||||
{
|
||||
// Figure out mapping of calling args to method args
|
||||
Class<?> paramTypes[] = method.getParameterTypes();
|
||||
int paramTypesLength = paramTypes.length;
|
||||
|
||||
// Method argument array pointing to index in calling array
|
||||
int argMapping[] = new int[paramTypesLength];
|
||||
int callArgsLen = callArgs.length;
|
||||
|
||||
for (int mi = 0; mi < paramTypesLength; mi++)
|
||||
{
|
||||
int ref = -1;
|
||||
// Find reference to argument in callArgs
|
||||
for (int ci = 0; ci < callArgsLen; ci++)
|
||||
{
|
||||
if (callArgs[ci].getIndex() == params[mi].getIndex())
|
||||
{
|
||||
ref = ci;
|
||||
}
|
||||
}
|
||||
if (ref < 0)
|
||||
{
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Unable to map type [");
|
||||
err.append(params[mi]);
|
||||
err.append("] in method ");
|
||||
ReflectUtils.append(err,method);
|
||||
err.append(" to calling args: (");
|
||||
boolean delim = false;
|
||||
for (Arg arg : callArgs)
|
||||
{
|
||||
if (delim)
|
||||
err.append(", ");
|
||||
err.append(arg);
|
||||
delim = true;
|
||||
}
|
||||
err.append(")");
|
||||
|
||||
throw new DynamicArgsException(err.toString());
|
||||
}
|
||||
argMapping[mi] = ref;
|
||||
}
|
||||
|
||||
// Return function capable of calling method
|
||||
return (obj, potentialArgs) -> {
|
||||
Object args[] = new Object[paramTypesLength];
|
||||
for (int i = 0; i < paramTypesLength; i++)
|
||||
{
|
||||
args[i] = potentialArgs[argMapping[i]];
|
||||
}
|
||||
try
|
||||
{
|
||||
return method.invoke(obj,args);
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
{
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Unable to call: ");
|
||||
ReflectUtils.append(err,obj.getClass(),method);
|
||||
err.append(" [with ");
|
||||
boolean delim = false;
|
||||
for (Object arg : args)
|
||||
{
|
||||
if (delim)
|
||||
err.append(", ");
|
||||
if (arg == null)
|
||||
{
|
||||
err.append("<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
err.append(arg.getClass().getSimpleName());
|
||||
}
|
||||
delim = true;
|
||||
}
|
||||
err.append("]");
|
||||
throw new DynamicArgsException(err.toString(),e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -29,34 +29,34 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.websocket.common.reflect.DynamicArgs.Signature;
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
public class UnorderedSignature implements Signature, Predicate<Method>
|
||||
class UnorderedSignature implements Signature, Predicate<Method>
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger(UnorderedSignature.class);
|
||||
private final Arg[] params;
|
||||
|
||||
|
||||
public UnorderedSignature(Arg... args)
|
||||
{
|
||||
this.params = args;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Arg[] getCallArgs()
|
||||
{
|
||||
return this.params;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Predicate<Method> getPredicate()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean test(Method method)
|
||||
{
|
||||
return getArgMapping(method, false, params) != null;
|
||||
}
|
||||
|
||||
|
||||
public void appendDescription(StringBuilder str)
|
||||
{
|
||||
str.append('(');
|
||||
|
@ -77,36 +77,52 @@ public class UnorderedSignature implements Signature, Predicate<Method>
|
|||
}
|
||||
str.append(')');
|
||||
}
|
||||
|
||||
private int[] getArgMapping(Method method, boolean throwOnFailure, Arg... callArgs)
|
||||
|
||||
/**
|
||||
* Identify mapping of argument indexes of the callArgs to method Args.
|
||||
* <p>
|
||||
* The callArgs is what the websocket implementation code is
|
||||
* using to call the method.
|
||||
* </p>
|
||||
* <p>
|
||||
* The method Args are what the user endpoint method args
|
||||
* are declared as.
|
||||
* </p>
|
||||
*
|
||||
* @param method the method that we want to eventually call
|
||||
* @param throwOnFailure true to toss a {@link DynamicArgsException} if there is a problem
|
||||
* attempting to identify the mapping. false to debug log the issue.
|
||||
* @param callArgs the calling args for this signature
|
||||
*/
|
||||
public int[] getArgMapping(Method method, boolean throwOnFailure, Arg... callArgs)
|
||||
{
|
||||
int callArgsLen = callArgs.length;
|
||||
|
||||
|
||||
// Figure out mapping of calling args to method args
|
||||
Class<?> paramTypes[] = method.getParameterTypes();
|
||||
int paramTypesLength = paramTypes.length;
|
||||
|
||||
|
||||
// Method argument array pointing to index in calling array
|
||||
int argMapping[] = new int[paramTypesLength];
|
||||
int argMappingLength = argMapping.length;
|
||||
|
||||
|
||||
// ServiceLoader for argument identification plugins
|
||||
List<ArgIdentifier> argIdentifiers = DynamicArgs.lookupArgIdentifiers();
|
||||
Arg methodArgs[] = new Arg[paramTypesLength];
|
||||
for (int pi = 0; pi < paramTypesLength; pi++)
|
||||
{
|
||||
methodArgs[pi] = new Arg(method, pi, paramTypes[pi]);
|
||||
|
||||
|
||||
// Supplement method argument identification from plugins
|
||||
for (ArgIdentifier argId : argIdentifiers)
|
||||
methodArgs[pi] = argId.apply(methodArgs[pi]);
|
||||
}
|
||||
|
||||
|
||||
// Iterate through mappings, looking for a callArg that fits it
|
||||
for (int ai = 0; ai < argMappingLength; ai++)
|
||||
{
|
||||
int ref = -1;
|
||||
|
||||
|
||||
// Find reference to argument in callArgs
|
||||
for (int ci = 0; ci < callArgsLen; ci++)
|
||||
{
|
||||
|
@ -116,7 +132,7 @@ public class UnorderedSignature implements Signature, Predicate<Method>
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ref < 0)
|
||||
{
|
||||
StringBuilder err = new StringBuilder();
|
||||
|
@ -134,19 +150,24 @@ public class UnorderedSignature implements Signature, Predicate<Method>
|
|||
delim = true;
|
||||
}
|
||||
err.append(")");
|
||||
|
||||
|
||||
if (throwOnFailure)
|
||||
{
|
||||
throw new DynamicArgsException(err.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("{}", err.toString());
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("{}", err.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
argMapping[ai] = ref;
|
||||
}
|
||||
|
||||
|
||||
// Ensure that required arguments are present in the mapping
|
||||
for (int ci = 0; ci < callArgsLen; ci++)
|
||||
{
|
||||
|
@ -168,7 +189,7 @@ public class UnorderedSignature implements Signature, Predicate<Method>
|
|||
err.append(callArgs[ci].getType());
|
||||
err.append("] in method ");
|
||||
ReflectUtils.append(err, method);
|
||||
|
||||
|
||||
if (throwOnFailure)
|
||||
throw new DynamicArgsException(err.toString());
|
||||
else
|
||||
|
@ -179,33 +200,33 @@ public class UnorderedSignature implements Signature, Predicate<Method>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return argMapping;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiFunction<Object, Object[], Object> getInvoker(Method method, Arg... callArgs)
|
||||
{
|
||||
int argMapping[] = getArgMapping(method, true, callArgs);
|
||||
|
||||
|
||||
// Return function capable of calling method
|
||||
return new UnorderedParamsFunction(method, argMapping);
|
||||
}
|
||||
|
||||
|
||||
public static class UnorderedParamsFunction
|
||||
implements BiFunction<Object, Object[], Object>
|
||||
{
|
||||
private final Method method;
|
||||
private final int paramTypesLength;
|
||||
private final int argMapping[];
|
||||
|
||||
|
||||
public UnorderedParamsFunction(Method method, int argMapping[])
|
||||
{
|
||||
this.method = method;
|
||||
this.paramTypesLength = method.getParameterTypes().length;
|
||||
this.argMapping = argMapping;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object apply(Object obj, Object[] potentialArgs)
|
||||
{
|
||||
|
@ -244,5 +265,5 @@ public class UnorderedSignature implements Signature, Predicate<Method>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.component.CloseableLifeCycle;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketConnectionListener;
|
||||
|
@ -84,17 +85,21 @@ public class CommonEndpointFunctionsTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testWebSocketConnectionListener_OpenTextClose()
|
||||
public void testWebSocketConnectionListener_OpenTextClose() throws Exception
|
||||
{
|
||||
// Setup
|
||||
ConnectionOnly socket = new ConnectionOnly();
|
||||
Session session = initSession(socket);
|
||||
EndpointFunctions<Session> endpointFunctions = new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor());
|
||||
try (CloseableLifeCycle<CommonEndpointFunctions> lifecycle = new CloseableLifeCycle<>(
|
||||
new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor())))
|
||||
{
|
||||
EndpointFunctions<Session> endpointFunctions = lifecycle.get();
|
||||
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello World", UTF8), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello World", UTF8), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
}
|
||||
|
||||
// Validate Events
|
||||
socket.assertCaptured(
|
||||
|
@ -118,17 +123,21 @@ public class CommonEndpointFunctionsTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testWebSocketListener_OpenTextClose()
|
||||
public void testWebSocketListener_OpenTextClose() throws Exception
|
||||
{
|
||||
// Setup
|
||||
DataConnection socket = new DataConnection();
|
||||
Session session = initSession(socket);
|
||||
EndpointFunctions<Session> endpointFunctions = new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor());
|
||||
try (CloseableLifeCycle<CommonEndpointFunctions> lifecycle = new CloseableLifeCycle<>(
|
||||
new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor())))
|
||||
{
|
||||
EndpointFunctions<Session> endpointFunctions = lifecycle.get();
|
||||
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello World", UTF8), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello World", UTF8), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
}
|
||||
|
||||
// Validate Events
|
||||
socket.assertCaptured(
|
||||
|
@ -160,18 +169,22 @@ public class CommonEndpointFunctionsTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotatedStreamedText_Single() throws InterruptedException
|
||||
@Test(timeout = 1000)
|
||||
public void testAnnotatedStreamedText_Single() throws Exception
|
||||
{
|
||||
// Setup
|
||||
StreamedText socket = new StreamedText(1);
|
||||
Session session = initSession(socket);
|
||||
EndpointFunctions<Session> endpointFunctions = new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor());
|
||||
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello World", UTF8), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
try (CloseableLifeCycle<CommonEndpointFunctions> lifecycle = new CloseableLifeCycle<>(
|
||||
new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor())))
|
||||
{
|
||||
EndpointFunctions<Session> endpointFunctions = lifecycle.get();
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hello World", UTF8), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
}
|
||||
|
||||
// Await completion (of threads)
|
||||
socket.streamLatch.await(2, TimeUnit.SECONDS);
|
||||
|
@ -180,21 +193,24 @@ public class CommonEndpointFunctionsTest
|
|||
socket.assertCaptured("onTextStream\\(Hello World\\)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnotatedStreamedText_MultipleParts() throws InterruptedException
|
||||
@Test(timeout = 1000)
|
||||
public void testAnnotatedStreamedText_MultipleParts() throws Exception
|
||||
{
|
||||
// Setup
|
||||
StreamedText socket = new StreamedText(1);
|
||||
Session session = initSession(socket);
|
||||
EndpointFunctions<Session> endpointFunctions = new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor());
|
||||
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hel"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("lo "), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Wor"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("ld"), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
try (CloseableLifeCycle<CommonEndpointFunctions> lifecycle = new CloseableLifeCycle<>(
|
||||
new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor())))
|
||||
{
|
||||
EndpointFunctions<Session> endpointFunctions = lifecycle.get();
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hel"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("lo "), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Wor"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("ld"), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
}
|
||||
|
||||
// Await completion (of threads)
|
||||
socket.streamLatch.await(2, TimeUnit.SECONDS);
|
||||
|
@ -219,20 +235,24 @@ public class CommonEndpointFunctionsTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testWebSocketPartialListener()
|
||||
public void testWebSocketPartialListener() throws Exception
|
||||
{
|
||||
// Setup
|
||||
PartialData socket = new PartialData();
|
||||
Session session = initSession(socket);
|
||||
EndpointFunctions<Session> endpointFunctions = new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor());
|
||||
try (CloseableLifeCycle<CommonEndpointFunctions> lifecycle = new CloseableLifeCycle<>(
|
||||
new CommonEndpointFunctions(socket, containerScope.getPolicy(), containerScope.getExecutor())))
|
||||
{
|
||||
EndpointFunctions<Session> endpointFunctions = lifecycle.get();
|
||||
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hel"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("lo "), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Wor"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("ld"), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
// Trigger Events
|
||||
endpointFunctions.onOpen(session);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Hel"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("lo "), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("Wor"), false);
|
||||
endpointFunctions.onText(BufferUtil.toBuffer("ld"), true);
|
||||
endpointFunctions.onClose(new CloseInfo(StatusCode.NORMAL, "Normal"));
|
||||
}
|
||||
|
||||
// Validate Events
|
||||
socket.assertCaptured(
|
||||
|
@ -242,6 +262,6 @@ public class CommonEndpointFunctionsTest
|
|||
"onWebSocketPartialText\\(Wor, false\\)",
|
||||
"onWebSocketPartialText\\(ld, true\\)",
|
||||
"onWebSocketClose\\([^\\)]*\\)"
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,14 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.common.io;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
public class CloseableLocalWebSocketSession extends LocalWebSocketSession implements AutoCloseable
|
||||
{
|
||||
public CloseableLocalWebSocketSession(WebSocketContainerScope containerScope, TestName testname, EventDriver driver)
|
||||
public CloseableLocalWebSocketSession(WebSocketContainerScope containerScope, TestName testname, Object websocket)
|
||||
{
|
||||
super(containerScope, testname, driver);
|
||||
super(containerScope, testname, websocket);
|
||||
// LifeCycle start
|
||||
try
|
||||
{
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.common.message;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
|
@ -39,10 +42,6 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class MessageOutputStreamTest
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(MessageOutputStreamTest.class);
|
||||
|
@ -59,16 +58,19 @@ public class MessageOutputStreamTest
|
|||
private WebSocketPolicy policy;
|
||||
private TrackingSocket remoteSocket;
|
||||
private LocalWebSocketSession session;
|
||||
|
||||
private WebSocketSession remoteSession;
|
||||
|
||||
@After
|
||||
public void closeSession() throws Exception
|
||||
{
|
||||
session.close();
|
||||
session.stop();
|
||||
remoteSession.close();
|
||||
remoteSession.stop();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setupSession() throws URISyntaxException
|
||||
public void setupSession() throws Exception
|
||||
{
|
||||
policy = WebSocketPolicy.newServerPolicy();
|
||||
policy.setInputBufferSize(1024);
|
||||
|
@ -79,8 +81,9 @@ public class MessageOutputStreamTest
|
|||
|
||||
// remote socket
|
||||
remoteSocket = new TrackingSocket("remote");
|
||||
WebSocketSession remoteSession = new LocalWebSocketSession(containerScope,testname,remoteSocket);
|
||||
remoteSession = new LocalWebSocketSession(containerScope,testname,remoteSocket);
|
||||
OutgoingFrames socketPipe = FramePipes.to(remoteSession);
|
||||
remoteSession.start();
|
||||
remoteSession.open();
|
||||
|
||||
// Local Session
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.common.message;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
|
@ -65,10 +64,11 @@ public class MessageWriterTest
|
|||
{
|
||||
session.close();
|
||||
remoteSession.close();
|
||||
remoteSession.stop();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setupSession() throws URISyntaxException
|
||||
public void setupSession() throws Exception
|
||||
{
|
||||
policy = WebSocketPolicy.newServerPolicy();
|
||||
policy.setInputBufferSize(1024);
|
||||
|
@ -83,6 +83,7 @@ public class MessageWriterTest
|
|||
LocalWebSocketConnection remoteConnection = new LocalWebSocketConnection(bufferPool);
|
||||
remoteSession = new WebSocketSession(containerScope,remoteURI,remoteSocket,remoteConnection);
|
||||
OutgoingFrames socketPipe = FramePipes.to(remoteSession);
|
||||
remoteSession.start();
|
||||
remoteSession.open();
|
||||
|
||||
// Local Session
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common.reflect;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DynamicArgsTest
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
public static class SampleSignatures
|
||||
{
|
||||
public String sigEmpty()
|
||||
{
|
||||
return "sigEmpty<>";
|
||||
}
|
||||
|
||||
public String sigStr(String str)
|
||||
{
|
||||
return String.format("sigStr<%s>", str);
|
||||
}
|
||||
|
||||
public String sigStrFile(String str, File foo)
|
||||
{
|
||||
return String.format("sigStrFile<%s,%s>", str, foo);
|
||||
}
|
||||
|
||||
public String sigFileStr(File foo, String str)
|
||||
{
|
||||
return String.format("sigFileStr<%s,%s>", foo, str);
|
||||
}
|
||||
|
||||
public String sigFileStrFin(File foo, String str, @Name("fin") boolean fin)
|
||||
{
|
||||
return String.format("sigFileStrFin<%s,%s,%b>", foo, str, fin);
|
||||
}
|
||||
|
||||
public String sigByteArray(byte[] buf, @Name("offset") int offset, @Name("length") int len)
|
||||
{
|
||||
return String.format("sigByteArray<%s,%d,%d>", buf == null ? "<null>" : ("[" + buf.length + "]"), offset, len);
|
||||
}
|
||||
}
|
||||
|
||||
public static Method findMethodByName(Object obj, String name)
|
||||
{
|
||||
for (Method method : obj.getClass().getMethods())
|
||||
{
|
||||
if (method.getName().equals(name))
|
||||
{
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new AssertionError("Unable to find method: " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with method that has empty signature,
|
||||
* and desired callable that also has an empty signature
|
||||
*
|
||||
* @throws Exception on error
|
||||
*/
|
||||
@Test
|
||||
public void testEmptySignature() throws Exception
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(); // intentionally empty
|
||||
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method m = findMethodByName(samples, "sigEmpty");
|
||||
DynamicArgs dynamicArgs = dab.build(m);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with empty potential args
|
||||
String result = (String) dynamicArgs.invoke(samples);
|
||||
assertThat("result", result, is("sigEmpty<>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with method that has empty signature,
|
||||
* and desired callable that has a String (optional) signature
|
||||
*
|
||||
* @throws Exception on error
|
||||
*/
|
||||
@Test
|
||||
public void testEmptySignature_StringCallable() throws Exception
|
||||
{
|
||||
final Arg ARG_STR = new Arg(String.class);
|
||||
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(ARG_STR);
|
||||
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method m = findMethodByName(samples, "sigEmpty");
|
||||
DynamicArgs dynamicArgs = dab.build(m);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with empty potential args
|
||||
String result = (String) dynamicArgs.invoke(samples, "Hello");
|
||||
assertThat("result", result, is("sigEmpty<>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with method that has String signature, and
|
||||
* a desired callable that also has String signature.
|
||||
*
|
||||
* @throws Exception on error
|
||||
*/
|
||||
@Test
|
||||
public void testStringSignature() throws Exception
|
||||
{
|
||||
final Arg ARG_STR = new Arg(String.class);
|
||||
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(ARG_STR);
|
||||
|
||||
final Arg CALL_STR = new Arg(String.class);
|
||||
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method m = findMethodByName(samples, "sigStr");
|
||||
DynamicArgs dynamicArgs = dab.build(m, CALL_STR);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
String result = (String) dynamicArgs.invoke(samples, "Hello");
|
||||
assertThat("result", result, is("sigStr<Hello>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of finding a match on a method that is tagged
|
||||
* via the ArgIdentifier concepts.
|
||||
*
|
||||
* @throws Exception on error
|
||||
*/
|
||||
@Test
|
||||
public void testByteArraySignature() throws Exception
|
||||
{
|
||||
final Arg ARG_BYTEARRAY = new Arg(byte[].class);
|
||||
final Arg ARG_OFFSET = new Arg(int.class).setTag("offset");
|
||||
final Arg ARG_LENGTH = new Arg(int.class).setTag("length");
|
||||
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(ARG_BYTEARRAY, ARG_OFFSET, ARG_LENGTH);
|
||||
|
||||
final Arg CALL_BYTEARRAY = new Arg(byte[].class);
|
||||
final Arg CALL_OFFSET = new Arg(int.class).setTag("offset");
|
||||
final Arg CALL_LENGTH = new Arg(int.class).setTag("length");
|
||||
|
||||
SampleSignatures ssigs = new SampleSignatures();
|
||||
Method m = findMethodByName(ssigs, "sigByteArray");
|
||||
DynamicArgs dynamicArgs = dab.build(m, CALL_BYTEARRAY, CALL_OFFSET, CALL_LENGTH);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
byte buf[] = new byte[222];
|
||||
int offset = 3;
|
||||
int len = 44;
|
||||
String result = (String) dynamicArgs.invoke(ssigs, buf, offset, len);
|
||||
assertThat("result", result, is("sigByteArray<[222],3,44>"));
|
||||
|
||||
// Test with empty potential args
|
||||
result = (String) dynamicArgs.invoke(ssigs, null, 123, 456);
|
||||
assertThat("result", result, is("sigByteArray<<null>,123,456>"));
|
||||
}
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common.reflect;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExactSignatureTest
|
||||
{
|
||||
public static class SampleSignatures
|
||||
{
|
||||
public String sigEmpty()
|
||||
{
|
||||
return "sigEmpty<>";
|
||||
}
|
||||
|
||||
public String sigStr(String str)
|
||||
{
|
||||
return String.format("sigStr<%s>", str);
|
||||
}
|
||||
|
||||
public String sigByteArray(byte[] buf, int offset, int len)
|
||||
{
|
||||
return String.format("sigByteArray<%s,%d,%d>", buf == null ? "<null>" : ("[" + buf.length + "]"), offset, len);
|
||||
}
|
||||
}
|
||||
|
||||
public static Method findMethodByName(Object obj, String name)
|
||||
{
|
||||
for (Method method : obj.getClass().getMethods())
|
||||
{
|
||||
if (method.getName().equals(name))
|
||||
{
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new AssertionError("Unable to find method: " + name);
|
||||
}
|
||||
|
||||
private static final Arg ARG_STR = new Arg(1, String.class);
|
||||
private static final Arg ARG_BOOL = new Arg(2, Boolean.class);
|
||||
private static final Arg ARG_FILE = new Arg(3, File.class);
|
||||
private static final Arg ARG_BYTEARRAY = new Arg(4, byte[].class);
|
||||
private static final Arg ARG_OFFSET = new Arg(5, int.class);
|
||||
private static final Arg ARG_LEN = new Arg(6, int.class);
|
||||
|
||||
@Test
|
||||
public void testEmptySignature() throws Exception
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new ExactSignature());
|
||||
|
||||
SampleSignatures ssigs = new SampleSignatures();
|
||||
Method m = findMethodByName(ssigs, "sigEmpty");
|
||||
DynamicArgs dargs = dab.build(m, ARG_STR, ARG_BOOL, ARG_FILE);
|
||||
assertThat("DynamicArgs", dargs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
String result = (String) dargs.invoke(ssigs, "Hello", Boolean.TRUE, new File("bar"));
|
||||
assertThat("result", result, is("sigEmpty<>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringSignature() throws Exception
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new ExactSignature(ARG_STR));
|
||||
|
||||
SampleSignatures ssigs = new SampleSignatures();
|
||||
Method m = findMethodByName(ssigs, "sigStr");
|
||||
DynamicArgs dargs = dab.build(m, ARG_STR, ARG_BOOL, ARG_FILE);
|
||||
assertThat("DynamicArgs", dargs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
String result = (String) dargs.invoke(ssigs, "Hello", Boolean.TRUE, new File("bar"));
|
||||
assertThat("result", result, is("sigStr<Hello>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteArraySignature() throws Exception
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new ExactSignature(ARG_BYTEARRAY, ARG_OFFSET, ARG_LEN));
|
||||
|
||||
SampleSignatures ssigs = new SampleSignatures();
|
||||
Method m = findMethodByName(ssigs, "sigByteArray");
|
||||
DynamicArgs dargs = dab.build(m, ARG_BYTEARRAY, ARG_OFFSET, ARG_LEN);
|
||||
assertThat("DynamicArgs", dargs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
byte buf[] = new byte[222];
|
||||
int offset = 3;
|
||||
int len = 44;
|
||||
String result = (String) dargs.invoke(ssigs, buf, offset, len);
|
||||
assertThat("result", result, is("sigByteArray<[222],3,44>"));
|
||||
|
||||
// Test with empty potential args
|
||||
result = (String) dargs.invoke(ssigs, null, 123, 456);
|
||||
assertThat("result", result, is("sigByteArray<<null>,123,456>"));
|
||||
}
|
||||
}
|
|
@ -26,44 +26,52 @@ import java.io.File;
|
|||
import java.lang.reflect.Method;
|
||||
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UnorderedSignatureTest
|
||||
{
|
||||
@SuppressWarnings("unused")
|
||||
public static class SampleSignatures
|
||||
{
|
||||
public String sigEmpty()
|
||||
{
|
||||
return "sigEmpty<>";
|
||||
}
|
||||
|
||||
|
||||
public String sigStr(String str)
|
||||
{
|
||||
return String.format("sigStr<%s>",str);
|
||||
return String.format("sigStr<%s>", str);
|
||||
}
|
||||
|
||||
|
||||
public String sigStrFile(String str, File foo)
|
||||
{
|
||||
return String.format("sigStrFile<%s,%s>",str,foo);
|
||||
return String.format("sigStrFile<%s,%s>", str, q(foo));
|
||||
}
|
||||
|
||||
|
||||
public String sigFileStr(File foo, String str)
|
||||
{
|
||||
return String.format("sigFileStr<%s,%s>",foo,str);
|
||||
return String.format("sigFileStr<%s,%s>", q(foo), str);
|
||||
}
|
||||
|
||||
|
||||
public String sigFileStrFin(File foo, String str, @Name("fin") boolean fin)
|
||||
{
|
||||
return String.format("sigFileStrFin<%s,%s,%b>",foo,str,fin);
|
||||
return String.format("sigFileStrFin<%s,%s,%b>", q(foo), q(str), fin);
|
||||
}
|
||||
|
||||
public String sigByteArray(byte[] buf, @Name("offset")int offset, @Name("length")int len)
|
||||
|
||||
public String sigByteArray(byte[] buf, @Name("offset") int offset, @Name("length") int len)
|
||||
{
|
||||
return String.format("sigByteArray<%s,%d,%d>",buf == null ? "<null>" : ("[" + buf.length + "]"),offset,len);
|
||||
return String.format("sigByteArray<%s,%d,%d>", buf == null ? "<null>" : ("[" + buf.length + "]"), offset, len);
|
||||
}
|
||||
|
||||
private String q(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return "<null>";
|
||||
else
|
||||
return obj.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Method findMethodByName(Object obj, String name)
|
||||
{
|
||||
for (Method method : obj.getClass().getMethods())
|
||||
|
@ -75,110 +83,156 @@ public class UnorderedSignatureTest
|
|||
}
|
||||
throw new AssertionError("Unable to find method: " + name);
|
||||
}
|
||||
|
||||
private static final Arg ARG_STR = new Arg(String.class);
|
||||
private static final Arg ARG_BOOL = new Arg(Boolean.class);
|
||||
private static final Arg ARG_FILE = new Arg(File.class);
|
||||
private static final Arg ARG_BYTEARRAY = new Arg(byte[].class);
|
||||
private static final Arg ARG_OFFSET = new Arg(int.class).setTag("offset");
|
||||
private static final Arg ARG_LENGTH = new Arg(int.class).setTag("length");
|
||||
private static final Arg ARG_FIN = new Arg(Boolean.class).setTag("fin");
|
||||
|
||||
/**
|
||||
* Test with method that has empty signature,
|
||||
* and desired callable that also has an empty signature
|
||||
* @throws Exception on error
|
||||
*/
|
||||
@Test
|
||||
public void testEmptySignature() throws Exception
|
||||
|
||||
private void assertMappings(int actualMapping[], int... expectedMapping)
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new UnorderedSignature());
|
||||
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method m = findMethodByName(samples, "sigEmpty");
|
||||
DynamicArgs dynamicArgs = dab.build(m);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with empty potential args
|
||||
String result = (String) dynamicArgs.invoke(samples);
|
||||
assertThat("result", result, is("sigEmpty<>"));
|
||||
assertThat("mapping", actualMapping, notNullValue());
|
||||
assertThat("mapping.length", actualMapping.length, is(expectedMapping.length));
|
||||
if (expectedMapping.length > 0)
|
||||
{
|
||||
for (int i = 0; i < expectedMapping.length; i++)
|
||||
{
|
||||
assertThat("mapping[" + i + "]", actualMapping[i], is(expectedMapping[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with method that has empty signature,
|
||||
* and desired callable that has a String (optional) signature
|
||||
* @throws Exception on error
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testEmptySignature_StringCallable
|
||||
() throws Exception
|
||||
public void testEmpty_Call_Session()
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new UnorderedSignature(ARG_STR));
|
||||
|
||||
UnorderedSignature sig = new UnorderedSignature(new Arg(Session.class));
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method m = findMethodByName(samples, "sigEmpty");
|
||||
DynamicArgs dynamicArgs = dab.build(m);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with empty potential args
|
||||
String result = (String) dynamicArgs.invoke(samples, "Hello");
|
||||
assertThat("result", result, is("sigEmpty<>"));
|
||||
Method method = findMethodByName(samples, "sigEmpty");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(Session.class));
|
||||
assertMappings(mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with method that has String signature, and
|
||||
* a desired callable that also has String signature.
|
||||
* @throws Exception on error
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testStringSignature() throws Exception
|
||||
public void testEmpty_Call_None()
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new UnorderedSignature(ARG_STR));
|
||||
|
||||
final Arg CALL_STR = new Arg(String.class);
|
||||
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method m = findMethodByName(samples, "sigStr");
|
||||
DynamicArgs dynamicArgs = dab.build(m, CALL_STR);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
String result = (String) dynamicArgs.invoke(samples, "Hello");
|
||||
assertThat("result", result, is("sigStr<Hello>"));
|
||||
Method method = findMethodByName(samples, "sigEmpty");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false);
|
||||
assertMappings(mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of finding a match on a method that is tagged
|
||||
* via a the ArgIdentifier concepts.
|
||||
* @throws Exception on error
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testByteArraySignature() throws Exception
|
||||
public void testString_Call_String()
|
||||
{
|
||||
DynamicArgs.Builder dab = new DynamicArgs.Builder();
|
||||
dab.addSignature(new UnorderedSignature(ARG_BYTEARRAY, ARG_OFFSET, ARG_LENGTH));
|
||||
|
||||
final Arg CALL_BYTEARRAY = new Arg(byte[].class);
|
||||
final Arg CALL_OFFSET = new Arg(int.class).setTag("offset");
|
||||
final Arg CALL_LENGTH = new Arg(int.class).setTag("length");
|
||||
|
||||
SampleSignatures ssigs = new SampleSignatures();
|
||||
Method m = findMethodByName(ssigs, "sigByteArray");
|
||||
DynamicArgs dynamicArgs = dab.build(m,CALL_BYTEARRAY, CALL_OFFSET, CALL_LENGTH);
|
||||
assertThat("DynamicArgs", dynamicArgs, notNullValue());
|
||||
|
||||
// Test with potential args
|
||||
byte buf[] = new byte[222];
|
||||
int offset = 3;
|
||||
int len = 44;
|
||||
String result = (String)dynamicArgs.invoke(ssigs,buf,offset,len);
|
||||
assertThat("result", result, is("sigByteArray<[222],3,44>"));
|
||||
|
||||
// Test with empty potential args
|
||||
result = (String)dynamicArgs.invoke(ssigs,null,123,456);
|
||||
assertThat("result", result, is("sigByteArray<<null>,123,456>"));
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigStr");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(String.class));
|
||||
assertMappings(mapping, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testString_Call_Session_String()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigStr");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(Session.class), new Arg(String.class));
|
||||
assertMappings(mapping, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringFile_Call_String_File()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigStrFile");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(String.class), new Arg(File.class));
|
||||
assertMappings(mapping, 0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringFile_Call_File_String()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigStrFile");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(File.class), new Arg(String.class));
|
||||
assertMappings(mapping, 1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileString_Call_String_File()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigFileStr");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(String.class), new Arg(File.class));
|
||||
assertMappings(mapping, 1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileString_Call_File_String()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigFileStr");
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, new Arg(File.class), new Arg(String.class));
|
||||
assertMappings(mapping, 0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileStringFin_Call_File_String_BoolTag()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigFileStrFin");
|
||||
|
||||
Arg callArgs[] = {new Arg(File.class), new Arg(String.class), new Arg(boolean.class).setTag("fin")};
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, callArgs);
|
||||
assertMappings(mapping, 0, 1, 2);
|
||||
|
||||
Object params[] = {new File("foo"), "bar", true};
|
||||
String resp = (String) sig.getInvoker(method, callArgs).apply(samples, params);
|
||||
assertThat("Invoked response", resp, is("sigFileStrFin<foo,bar,true>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileStringFin_Call_BoolTag_File_String()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigFileStrFin");
|
||||
|
||||
Arg callArgs[] = {new Arg(boolean.class).setTag("fin"), new Arg(File.class), new Arg(String.class)};
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, callArgs);
|
||||
assertMappings(mapping, 1, 2, 0);
|
||||
|
||||
Object params[] = {true, new File("foo"), "bar"};
|
||||
String resp = (String) sig.getInvoker(method, callArgs).apply(samples, params);
|
||||
assertThat("Invoked response", resp, is("sigFileStrFin<foo,bar,true>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileStringFin_Call_BoolTag_Null_String()
|
||||
{
|
||||
UnorderedSignature sig = new UnorderedSignature();
|
||||
SampleSignatures samples = new SampleSignatures();
|
||||
Method method = findMethodByName(samples, "sigFileStrFin");
|
||||
|
||||
Arg callArgs[] = {new Arg(boolean.class).setTag("fin"), new Arg(File.class), new Arg(String.class)};
|
||||
|
||||
int mapping[] = sig.getArgMapping(method, false, callArgs);
|
||||
assertMappings(mapping, 1, 2, 0);
|
||||
|
||||
Object params[] = {true, null, "bar"};
|
||||
String resp = (String) sig.getInvoker(method, callArgs).apply(samples, params);
|
||||
assertThat("Invoked response", resp, is("sigFileStrFin<<null>,bar,true>"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=WARN
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.protocol.Parser.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.protocol.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.io.payload.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.extensions.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.message.LEVEL=DEBUG
|
||||
org.eclipse.jetty.websocket.common.function.LEVEL=DEBUG
|
||||
|
|
Loading…
Reference in New Issue