/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.analytics.push; import static org.testng.AssertJUnit.assertEquals; import java.io.IOException; import java.util.concurrent.ExecutionException; import org.eclipse.jetty.server.Server; import org.json.JSONException; import org.springframework.web.context.WebApplicationContext; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.opengamma.util.test.TestGroup; import com.opengamma.util.tuple.Pair; /** * Tests pushing results to a long polling HTTP connection. */ @Test(groups = TestGroup.UNIT) public class LongPollingTest { public static final String CLIENT_ID = "CLIENT_ID"; private static final String RESULT1 = "RESULT1"; private static final String RESULT2 = "RESULT2"; private static final String RESULT3 = "RESULT3"; private Server _server; private TestConnectionManager _updateManager; private LongPollingConnectionManager _longPollingConnectionManager; private WebPushTestUtils _webPushTestUtils = new WebPushTestUtils(); @BeforeClass void createJettyServer() throws Exception { Pair<Server, WebApplicationContext> serverAndContext = _webPushTestUtils.createJettyServer("classpath:/com/opengamma/web/analytics/push/long-poll-test.xml"); _server = serverAndContext.getFirst(); WebApplicationContext context = serverAndContext.getSecond(); _updateManager = context.getBean(TestConnectionManager.class); _longPollingConnectionManager = context.getBean(LongPollingConnectionManager.class); } @AfterClass void shutdownJettyServer() throws Exception { _server.stop(); } @Test public void testHandshake() throws IOException { String clientId = _webPushTestUtils.handshake(); assertEquals(CLIENT_ID, clientId); } /** * Tests sending an update to a client that is blocked on a long poll request */ @Test public void longPollBlocking() throws IOException, ExecutionException, InterruptedException, JSONException { final String clientId = _webPushTestUtils.handshake(); new Thread(new Runnable() { @Override public void run() { waitAndSend(clientId, RESULT1); } }).start(); String result = _webPushTestUtils.readFromPath("/updates/" + clientId); WebPushTestUtils.checkJsonResults(result, RESULT1); } /** * Tests sending a single update to a client's connection when it's not connected and then connecting. */ @Test public void longPollNotBlocking() throws IOException, JSONException { String clientId = _webPushTestUtils.handshake(); _updateManager.sendUpdate(RESULT1); String result = _webPushTestUtils.readFromPath("/updates/" + clientId); WebPushTestUtils.checkJsonResults(result, RESULT1); } /** * Tests sending multiple updates to a connection where the client isn't currently connected. */ @Test public void longPollQueue() throws IOException, JSONException { String clientId = _webPushTestUtils.handshake(); _updateManager.sendUpdate(RESULT1); _updateManager.sendUpdate(RESULT2); _updateManager.sendUpdate(RESULT3); String result = _webPushTestUtils.readFromPath("/updates/" + clientId); WebPushTestUtils.checkJsonResults(result, RESULT1, RESULT2, RESULT3); } /** * test multiple updates for the same url get squashed into a single update */ @Test public void longPollQueueMultipleUpdates() throws IOException, JSONException { String clientId = _webPushTestUtils.handshake(); _updateManager.sendUpdate(RESULT1); _updateManager.sendUpdate(RESULT1); _updateManager.sendUpdate(RESULT2); _updateManager.sendUpdate(RESULT3); _updateManager.sendUpdate(RESULT2); String result = _webPushTestUtils.readFromPath("/updates/" + clientId); WebPushTestUtils.checkJsonResults(result, RESULT1, RESULT2, RESULT3); } @Test public void repeatingLongPoll() throws IOException, JSONException { final String clientId = _webPushTestUtils.handshake(); new Thread(new Runnable() { @Override public void run() { waitAndSend(clientId, RESULT1); waitAndSend(clientId, RESULT2); waitAndSend(clientId, RESULT3); waitAndSend(clientId, RESULT2); waitAndSend(clientId, RESULT1); } }).start(); String path = "/updates/" + clientId; WebPushTestUtils.checkJsonResults(_webPushTestUtils.readFromPath(path), RESULT1); WebPushTestUtils.checkJsonResults(_webPushTestUtils.readFromPath(path), RESULT2); WebPushTestUtils.checkJsonResults(_webPushTestUtils.readFromPath(path), RESULT3); WebPushTestUtils.checkJsonResults(_webPushTestUtils.readFromPath(path), RESULT2); WebPushTestUtils.checkJsonResults(_webPushTestUtils.readFromPath(path), RESULT1); } @Test public void longPollTimeout() throws IOException, JSONException { String clientId = _webPushTestUtils.handshake(); String path = "/updates/" + clientId; String timeoutResult = _webPushTestUtils.readFromPath(path); assertEquals("", timeoutResult); _updateManager.sendUpdate(RESULT1); WebPushTestUtils.checkJsonResults(_webPushTestUtils.readFromPath(path), RESULT1); } /** * Waits until the client is connected before sending the result to its listener */ private void waitAndSend(String clientId, String result) { // wait for the request to block while (!_longPollingConnectionManager.isClientConnected(clientId)) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } _updateManager.sendUpdate(result); } }