summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompClient.java58
-rw-r--r--backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompSession.java66
2 files changed, 123 insertions, 1 deletions
diff --git a/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompClient.java b/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompClient.java
index 3388e002..43c8edeb 100644
--- a/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompClient.java
+++ b/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompClient.java
@@ -6,6 +6,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import org.springframework.context.Lifecycle;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@@ -16,16 +17,28 @@ import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
-public class JackstompClient {
+/**
+ * A simple wrapper around a {@link WebSocketStompClient} which preconfigures websocket transports, a Jackson
+ * converter for messages, and allows for the creation of {@link JackstompSession}s.
+ */
+public class JackstompClient implements Lifecycle {
private static final long DEFAULT_CONNECTION_TIMEOUT_IN_SECONDS = 15;
private final WebSocketStompClient client;
+ /**
+ * Creates a {@code JackstompClient} with convenient defaults. It creates a pre-configured
+ * {@link WebSocketStompClient} using Spring {@link SockJsClient} and a Jackson message converter.
+ */
public JackstompClient() {
this(createDefaultStompClient());
}
+ /**
+ * Creates a {@code JackstompClient} based on the given {@link WebSocketStompClient}. This allows you to
+ * configure as you please the actual client used by Jackstomp.
+ */
public JackstompClient(WebSocketStompClient client) {
this.client = client;
}
@@ -51,10 +64,42 @@ public class JackstompClient {
return taskScheduler;
}
+ /**
+ * Connects to the given URL. Uses a default timeout of {@value #DEFAULT_CONNECTION_TIMEOUT_IN_SECONDS} seconds.
+ *
+ * @param url
+ * the URL to connect to
+ *
+ * @return a new {@link JackstompSession} for the created connection
+ * @throws InterruptedException
+ * if the current thread was interrupted while waiting for the connection
+ * @throws ExecutionException
+ * if an exception was thrown while connecting
+ * @throws TimeoutException
+ * if the connection took too long to establish
+ */
public JackstompSession connect(String url) throws InterruptedException, ExecutionException, TimeoutException {
return connect(url, DEFAULT_CONNECTION_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
}
+ /**
+ * Connects to the given URL. Uses a default timeout of {@value #DEFAULT_CONNECTION_TIMEOUT_IN_SECONDS} seconds.
+ *
+ * @param url
+ * the URL to connect to
+ * @param timeout
+ * the maximum time to wait for the connection
+ * @param unit
+ * the time unit of the timeout argument
+ *
+ * @return a new {@link JackstompSession} for the created connection
+ * @throws InterruptedException
+ * if the current thread was interrupted while waiting for the connection
+ * @throws ExecutionException
+ * if an exception was thrown while connecting
+ * @throws TimeoutException
+ * if the connection took too long to establish
+ */
public JackstompSession connect(String url, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
StompSession session = client.connect(url, new LoggingStompSessionHandler()).get(timeout, unit);
@@ -62,7 +107,18 @@ public class JackstompClient {
return new JackstompSession(session);
}
+ @Override
+ public void start() {
+ client.start();
+ }
+
+ @Override
public void stop() {
client.stop();
}
+
+ @Override
+ public boolean isRunning() {
+ return client.isRunning();
+ }
}
diff --git a/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompSession.java b/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompSession.java
index 12ab0adc..db361fca 100644
--- a/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompSession.java
+++ b/backend/src/test/java/org/luxons/sevenwonders/test/client/JackstompSession.java
@@ -7,10 +7,21 @@ import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
+/**
+ * Wrapper a {@link StompSession} that provides additional subscription features. It can return a {@link Channel}
+ * upon subscription for a given payload type, which can then be queried actively. This is particularly useful for
+ * unit tests.
+ */
public class JackstompSession implements StompSession {
private final StompSession stompSession;
+ /**
+ * Creates a new {@code JackstompSession} wrapping the given {@link StompSession}.
+ *
+ * @param stompSession
+ * the session to wrap
+ */
public JackstompSession(StompSession stompSession) {
this.stompSession = stompSession;
}
@@ -35,6 +46,17 @@ public class JackstompSession implements StompSession {
return stompSession.subscribe(headers, handler);
}
+ /**
+ * Subscribe to the given destination by sending a SUBSCRIBE frame and queue received messages in the returned
+ * {@link Channel}.
+ *
+ * @param destination
+ * the destination to subscribe to
+ * @param payloadType
+ * the expected type for received messages
+ *
+ * @return a new channel to use to actively check for received values, unsubscribe, or track receipts
+ */
public <T> Channel<T> subscribe(String destination, Class<T> payloadType) {
BlockingQueue<T> blockingQueue = new LinkedBlockingDeque<>();
StompFrameHandler frameHandler = new QueuedStompFrameHandler<>(blockingQueue, payloadType);
@@ -42,6 +64,16 @@ public class JackstompSession implements StompSession {
return new Channel<>(sub, blockingQueue);
}
+ /**
+ * Subscribe to the given destination by sending a SUBSCRIBE frame and queue received messages in the returned
+ * {@link Channel}. The messages are expected to have no body, and empty {@link Object}s are queued to be able to
+ * track reception events.
+ *
+ * @param destination
+ * the destination to subscribe to
+ *
+ * @return a new channel to use to actively check for received events, unsubscribe, or track receipts
+ */
public Channel<Object> subscribeEmptyMsgs(String destination) {
BlockingQueue<Object> blockingQueue = new LinkedBlockingDeque<>();
StompFrameHandler frameHandler = new EmptyMsgStompFrameHandler(blockingQueue);
@@ -74,6 +106,25 @@ public class JackstompSession implements StompSession {
stompSession.disconnect();
}
+ /**
+ * Makes a synchronous request/response call via a send and a subscription.
+ *
+ * @param payload
+ * the payload to send on the given requestDestination
+ * @param responseType
+ * the type of the response to expect on the responseDestination
+ * @param requestDestination
+ * the destination to send payload to
+ * @param responseDestination
+ * the destination to expect a response on
+ * @param <T>
+ * the type of object to receive as a response
+ *
+ * @return the response object, deserialized from the JSON received on the responseDestination, or null if no
+ * response was received before timeout.
+ * @throws InterruptedException
+ * if the current thread was interrupted while waiting for the response
+ */
public <T> T request(Object payload, Class<T> responseType, String requestDestination, String responseDestination)
throws InterruptedException {
Channel<T> channel = subscribe(responseDestination, responseType);
@@ -83,6 +134,21 @@ public class JackstompSession implements StompSession {
return msg;
}
+ /**
+ * Makes a synchronous request/response call via a send and a subscription, but does not expect any value as
+ * response, just an event message with no body.
+ *
+ * @param payload
+ * the payload to send on the given requestDestination
+ * @param requestDestination
+ * the destination to send payload to
+ * @param responseDestination
+ * the destination to expect a response on
+ *
+ * @return true if the event message was received before timeout, false otherwise
+ * @throws InterruptedException
+ * if the current thread was interrupted while waiting for the response
+ */
public boolean request(Object payload, String requestDestination, String responseDestination)
throws InterruptedException {
Channel<Object> channel = subscribeEmptyMsgs(responseDestination);
bgstack15