@Test
  public void executeTrade() throws Exception {

    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> failure = new AtomicReference<Throwable>();

    URI uri = new URI("ws://localhost:" + port + "/portfolio/websocket");
    WebSocketStompClient stompClient =
        new WebSocketStompClient(uri, this.headers, new StandardWebSocketClient());
    stompClient.setMessageConverter(new MappingJackson2MessageConverter());

    stompClient.connect(
        new StompMessageHandler() {

          private StompSession stompSession;

          @Override
          public void afterConnected(StompSession stompSession, StompHeaderAccessor headers) {

            this.stompSession = stompSession;
            this.stompSession.subscribe("/user/queue/position-updates", null);

            try {
              Trade trade = new Trade();
              trade.setAction(Trade.TradeAction.Buy);
              trade.setTicker("DELL");
              trade.setShares(25);

              this.stompSession.send("/app/trade", trade);
            } catch (Throwable t) {
              failure.set(t);
              latch.countDown();
            }
          }

          @Override
          public void handleMessage(Message<byte[]> message) {
            StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
            if (!"/user/queue/position-updates".equals(headers.getDestination())) {
              failure.set(new IllegalStateException("Unexpected message: " + message));
            }
            logger.debug("Got " + new String((byte[]) message.getPayload()));
            try {
              String json = new String((byte[]) message.getPayload(), Charset.forName("UTF-8"));
              new JsonPathExpectationsHelper("$.shares").assertValue(json, 75);
              new JsonPathExpectationsHelper("$.company").assertValue(json, "Dell Inc.");
            } catch (Throwable t) {
              failure.set(t);
            } finally {
              latch.countDown();
              this.stompSession.disconnect();
            }
          }

          @Override
          public void handleError(Message<byte[]> message) {
            failure.set(new Exception(new String(message.getPayload(), Charset.forName("UTF-8"))));
          }

          @Override
          public void handleReceipt(String receiptId) {}

          @Override
          public void afterDisconnected() {}
        });

    if (!latch.await(5, TimeUnit.SECONDS)) {
      fail("Trade confirmation not received");
    } else if (failure.get() != null) {
      throw new AssertionError("", failure.get());
    }
  }
  @Test
  public void getPositions() throws Exception {

    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> failure = new AtomicReference<Throwable>();

    URI uri = new URI("ws://localhost:" + port + "/portfolio/websocket");
    WebSocketStompClient stompClient =
        new WebSocketStompClient(uri, this.headers, new StandardWebSocketClient());
    stompClient.setMessageConverter(new MappingJackson2MessageConverter());

    stompClient.connect(
        new StompMessageHandler() {

          private StompSession stompSession;

          @Override
          public void afterConnected(StompSession stompSession, StompHeaderAccessor headers) {
            stompSession.subscribe("/app/positions", null);
            this.stompSession = stompSession;
          }

          @Override
          public void handleMessage(Message<byte[]> message) {
            StompHeaderAccessor headers = StompHeaderAccessor.wrap(message);
            if (!"/app/positions".equals(headers.getDestination())) {
              failure.set(new IllegalStateException("Unexpected message: " + message));
            }
            logger.debug("Got " + new String((byte[]) message.getPayload()));
            try {
              String json = new String((byte[]) message.getPayload(), Charset.forName("UTF-8"));
              new JsonPathExpectationsHelper("$[0].company")
                  .assertValue(json, "Citrix Systems, Inc.");
              new JsonPathExpectationsHelper("$[1].company").assertValue(json, "Dell Inc.");
              new JsonPathExpectationsHelper("$[2].company").assertValue(json, "Microsoft");
              new JsonPathExpectationsHelper("$[3].company").assertValue(json, "Oracle");
            } catch (Throwable t) {
              failure.set(t);
            } finally {
              latch.countDown();
              this.stompSession.disconnect();
            }
          }

          @Override
          public void handleError(Message<byte[]> message) {
            failure.set(new Exception(new String(message.getPayload(), Charset.forName("UTF-8"))));
          }

          @Override
          public void handleReceipt(String receiptId) {}

          @Override
          public void afterDisconnected() {}
        });

    if (failure.get() != null) {
      throw new AssertionError("", failure.get());
    }

    if (!latch.await(5, TimeUnit.SECONDS)) {
      fail("Portfolio positions not received");
    }
  }