Search in sources :

Example 6 with EventListener

use of org.glassfish.jersey.media.sse.EventListener in project jersey by jersey.

the class ItemStoreResourceITCase method testItemsStore.

/**
     * Test the item addition, addition event broadcasting and item retrieval from {@link ItemStoreResource}.
     *
     * @throws Exception in case of a test failure.
     */
@Test
public void testItemsStore() throws Exception {
    final List<String> items = Collections.unmodifiableList(Arrays.asList("foo", "bar", "baz"));
    final WebTarget itemsTarget = target("items");
    // countdown on all events
    final CountDownLatch latch = new CountDownLatch(items.size() * MAX_LISTENERS * 2);
    final List<Queue<Integer>> indexQueues = new ArrayList<Queue<Integer>>(MAX_LISTENERS);
    final EventSource[] sources = new EventSource[MAX_LISTENERS];
    final AtomicInteger sizeEventsCount = new AtomicInteger(0);
    for (int i = 0; i < MAX_LISTENERS; i++) {
        final int id = i;
        final EventSource es = EventSource.target(itemsTarget.path("events")).named("SOURCE " + id).build();
        sources[id] = es;
        final Queue<Integer> indexes = new ConcurrentLinkedQueue<Integer>();
        indexQueues.add(indexes);
        es.register(new EventListener() {

            @Override
            @SuppressWarnings("MagicNumber")
            public void onEvent(InboundEvent inboundEvent) {
                try {
                    if (inboundEvent.getName() == null) {
                        final String data = inboundEvent.readData();
                        LOGGER.info("[-i-] SOURCE " + id + ": Received event id=" + inboundEvent.getId() + " data=" + data);
                        indexes.add(items.indexOf(data));
                    } else if ("size".equals(inboundEvent.getName())) {
                        sizeEventsCount.incrementAndGet();
                    }
                } catch (ProcessingException ex) {
                    LOGGER.log(Level.SEVERE, "[-x-] SOURCE " + id + ": Error getting event data.", ex);
                    indexes.add(-999);
                } finally {
                    latch.countDown();
                }
            }
        });
    }
    try {
        open(sources);
        for (String item : items) {
            postItem(itemsTarget, item);
        }
        assertTrue("Waiting to receive all events has timed out.", latch.await((1000 + MAX_LISTENERS * EventSource.RECONNECT_DEFAULT) * getAsyncTimeoutMultiplier(), TimeUnit.MILLISECONDS));
        // need to force disconnect on server in order for EventSource.close(...) to succeed with HttpUrlConnection
        sendCommand(itemsTarget, "disconnect");
    } finally {
        close(sources);
    }
    String postedItems = itemsTarget.request().get(String.class);
    for (String item : items) {
        assertTrue("Item '" + item + "' not stored on server.", postedItems.contains(item));
    }
    int queueId = 0;
    for (Queue<Integer> indexes : indexQueues) {
        for (int i = 0; i < items.size(); i++) {
            assertTrue("Event for '" + items.get(i) + "' not received in queue " + queueId, indexes.contains(i));
        }
        assertEquals("Not received the expected number of events in queue " + queueId, items.size(), indexes.size());
        queueId++;
    }
    assertEquals("Number of received 'size' events does not match.", items.size() * MAX_LISTENERS, sizeEventsCount.get());
}
Also used : ArrayList(java.util.ArrayList) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) EventSource(org.glassfish.jersey.media.sse.EventSource) InboundEvent(org.glassfish.jersey.media.sse.InboundEvent) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WebTarget(javax.ws.rs.client.WebTarget) EventListener(org.glassfish.jersey.media.sse.EventListener) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Queue(java.util.Queue) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ProcessingException(javax.ws.rs.ProcessingException) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 7 with EventListener

use of org.glassfish.jersey.media.sse.EventListener in project jersey by jersey.

the class ServerSentEventsTest method testCreateDomain.

/**
     * Test receiving all streamed messages in parallel by multiple event sources.
     *
     * @throws Exception in case of a failure during the test execution.
     */
@Test
public void testCreateDomain() throws Exception {
    final int MAX_CLIENTS = 25;
    final int MESSAGE_COUNT = 6;
    final Response response = target().path("domain/start").queryParam("testSources", MAX_CLIENTS).request().post(Entity.text("data"), Response.class);
    assertThat("Unexpected start domain response status code.", response.getStatus(), equalTo(Response.Status.CREATED.getStatusCode()));
    final Map<Integer, Integer> messageCounts = new ConcurrentHashMap<Integer, Integer>(MAX_CLIENTS);
    final CountDownLatch doneLatch = new CountDownLatch(MAX_CLIENTS);
    final EventSource[] sources = new EventSource[MAX_CLIENTS];
    final String processUriString = target().getUri().relativize(response.getLocation()).toString();
    final WebTarget sseTarget = target().path(processUriString).queryParam("testSource", "true");
    for (int i = 0; i < MAX_CLIENTS; i++) {
        final int id = i;
        sources[id] = EventSource.target(sseTarget).build();
        sources[id].register(new EventListener() {

            private final AtomicInteger messageCount = new AtomicInteger(0);

            @Override
            public void onEvent(InboundEvent inboundEvent) {
                messageCount.incrementAndGet();
                final String message = inboundEvent.readData(String.class);
                if ("done".equals(message)) {
                    messageCounts.put(id, messageCount.get());
                    doneLatch.countDown();
                }
            }
        });
        sources[i].open();
    }
    doneLatch.await(5 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS);
    for (EventSource source : sources) {
        source.close();
    }
    for (int i = 0; i < MAX_CLIENTS; i++) {
        final Integer count = messageCounts.get(i);
        assertThat("Final message not received by event source " + i, count, notNullValue());
        assertThat("Unexpected number of messages received by event source " + i, count, equalTo(MESSAGE_COUNT));
    }
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) Response(javax.ws.rs.core.Response) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) EventSource(org.glassfish.jersey.media.sse.EventSource) InboundEvent(org.glassfish.jersey.media.sse.InboundEvent) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WebTarget(javax.ws.rs.client.WebTarget) EventListener(org.glassfish.jersey.media.sse.EventListener) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 8 with EventListener

use of org.glassfish.jersey.media.sse.EventListener in project jersey by jersey.

the class ItemStoreResourceTest method testEventSourceReconnect.

/**
     * Test the {@link EventSource} reconnect feature.
     *
     * @throws Exception in case of a test failure.
     */
@Test
public void testEventSourceReconnect() throws Exception {
    final WebTarget itemsTarget = target("items");
    // countdown only on new item events
    final CountDownLatch latch = new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2);
    final List<Queue<String>> receivedQueues = new ArrayList<Queue<String>>(MAX_LISTENERS);
    final EventSource[] sources = new EventSource[MAX_LISTENERS];
    for (int i = 0; i < MAX_LISTENERS; i++) {
        final int id = i;
        final EventSource es = EventSource.target(itemsTarget.path("events")).named("SOURCE " + id).build();
        sources[id] = es;
        final Queue<String> received = new ConcurrentLinkedQueue<String>();
        receivedQueues.add(received);
        es.register(new EventListener() {

            @Override
            public void onEvent(InboundEvent inboundEvent) {
                try {
                    if (inboundEvent.getName() == null) {
                        latch.countDown();
                        final String data = inboundEvent.readData();
                        LOGGER.info("[-i-] SOURCE " + id + ": Received event id=" + inboundEvent.getId() + " data=" + data);
                        received.add(data);
                    }
                } catch (Exception ex) {
                    LOGGER.log(Level.SEVERE, "[-x-] SOURCE " + id + ": Error getting event data.", ex);
                    received.add("[data processing error]");
                }
            }
        });
    }
    final String[] postedItems = new String[MAX_ITEMS * 2];
    try {
        open(sources);
        for (int i = 0; i < MAX_ITEMS; i++) {
            final String item = String.format("round-1-%02d", i);
            postItem(itemsTarget, item);
            postedItems[i] = item;
            sendCommand(itemsTarget, "disconnect");
            Thread.sleep(100);
        }
        final int reconnectDelay = 1;
        sendCommand(itemsTarget, "reconnect " + reconnectDelay);
        sendCommand(itemsTarget, "disconnect");
        Thread.sleep(reconnectDelay * 1000);
        for (int i = 0; i < MAX_ITEMS; i++) {
            final String item = String.format("round-2-%02d", i);
            postedItems[i + MAX_ITEMS] = item;
            postItem(itemsTarget, item);
        }
        sendCommand(itemsTarget, "reconnect now");
        assertTrue("Waiting to receive all events has timed out.", latch.await((1 + MAX_LISTENERS * (MAX_ITEMS + 1) * reconnectDelay) * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS));
        // need to force disconnect on server in order for EventSource.close(...) to succeed with HttpUrlConnection
        sendCommand(itemsTarget, "disconnect");
    } finally {
        close(sources);
    }
    final String storedItems = itemsTarget.request().get(String.class);
    for (String item : postedItems) {
        assertThat("Posted item '" + item + "' stored on server", storedItems, containsString(item));
    }
    int sourceId = 0;
    for (Queue<String> queue : receivedQueues) {
        assertThat("Received events in source " + sourceId, queue, describedAs("Collection containing %0", hasItems(postedItems), Arrays.asList(postedItems).toString()));
        assertThat("Size of received queue for source " + sourceId, queue.size(), equalTo(postedItems.length));
        sourceId++;
    }
}
Also used : ArrayList(java.util.ArrayList) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) EventSource(org.glassfish.jersey.media.sse.EventSource) InboundEvent(org.glassfish.jersey.media.sse.InboundEvent) WebTarget(javax.ws.rs.client.WebTarget) EventListener(org.glassfish.jersey.media.sse.EventListener) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Queue(java.util.Queue) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 9 with EventListener

use of org.glassfish.jersey.media.sse.EventListener in project jersey by jersey.

the class ItemStoreResourceITCase method testEventSourceReconnect.

/**
     * Test the {@link EventSource} reconnect feature.
     *
     * @throws Exception in case of a test failure.
     */
@Test
public void testEventSourceReconnect() throws Exception {
    final WebTarget itemsTarget = target("items");
    // countdown only on new item events
    final CountDownLatch latch = new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2);
    final List<Queue<String>> receivedQueues = new ArrayList<Queue<String>>(MAX_LISTENERS);
    final EventSource[] sources = new EventSource[MAX_LISTENERS];
    for (int i = 0; i < MAX_LISTENERS; i++) {
        final int id = i;
        final EventSource es = EventSource.target(itemsTarget.path("events")).named("SOURCE " + id).build();
        sources[id] = es;
        final Queue<String> received = new ConcurrentLinkedQueue<String>();
        receivedQueues.add(received);
        es.register(new EventListener() {

            @Override
            public void onEvent(InboundEvent inboundEvent) {
                try {
                    if (inboundEvent.getName() == null) {
                        latch.countDown();
                        final String data = inboundEvent.readData();
                        LOGGER.info("[-i-] SOURCE " + id + ": Received event id=" + inboundEvent.getId() + " data=" + data);
                        received.add(data);
                    }
                } catch (ProcessingException ex) {
                    LOGGER.log(Level.SEVERE, "[-x-] SOURCE " + id + ": Error getting event data.", ex);
                    received.add("[data processing error]");
                }
            }
        });
    }
    final String[] postedItems = new String[MAX_ITEMS * 2];
    try {
        open(sources);
        for (int i = 0; i < MAX_ITEMS; i++) {
            final String item = String.format("round-1-%02d", i);
            postItem(itemsTarget, item);
            postedItems[i] = item;
            sendCommand(itemsTarget, "disconnect");
            Thread.sleep(100);
        }
        final int reconnectDelay = 1;
        sendCommand(itemsTarget, "reconnect " + reconnectDelay);
        sendCommand(itemsTarget, "disconnect");
        Thread.sleep(reconnectDelay * 1000);
        for (int i = 0; i < MAX_ITEMS; i++) {
            final String item = String.format("round-2-%02d", i);
            postedItems[i + MAX_ITEMS] = item;
            postItem(itemsTarget, item);
        }
        sendCommand(itemsTarget, "reconnect now");
        assertTrue("Waiting to receive all events has timed out.", latch.await((1 + MAX_LISTENERS * (MAX_ITEMS + 1) * reconnectDelay) * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS));
        // need to force disconnect on server in order for EventSource.close(...) to succeed with HttpUrlConnection
        sendCommand(itemsTarget, "disconnect");
    } finally {
        close(sources);
    }
    final String storedItems = itemsTarget.request().get(String.class);
    for (String item : postedItems) {
        assertThat("Posted item '" + item + "' stored on server", storedItems, containsString(item));
    }
    int sourceId = 0;
    for (Queue<String> queue : receivedQueues) {
        assertThat("Received events in source " + sourceId, queue, describedAs("Collection containing %0", hasItems(postedItems), Arrays.asList(postedItems).toString()));
        assertThat("Size of received queue for source " + sourceId, queue.size(), equalTo(postedItems.length));
        sourceId++;
    }
}
Also used : ArrayList(java.util.ArrayList) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) EventSource(org.glassfish.jersey.media.sse.EventSource) InboundEvent(org.glassfish.jersey.media.sse.InboundEvent) WebTarget(javax.ws.rs.client.WebTarget) EventListener(org.glassfish.jersey.media.sse.EventListener) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Queue(java.util.Queue) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ProcessingException(javax.ws.rs.ProcessingException) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Aggregations

CountDownLatch (java.util.concurrent.CountDownLatch)9 WebTarget (javax.ws.rs.client.WebTarget)9 EventListener (org.glassfish.jersey.media.sse.EventListener)9 EventSource (org.glassfish.jersey.media.sse.EventSource)9 JerseyTest (org.glassfish.jersey.test.JerseyTest)9 Test (org.junit.Test)9 InboundEvent (org.glassfish.jersey.media.sse.InboundEvent)8 ArrayList (java.util.ArrayList)5 Queue (java.util.Queue)4 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 ProcessingException (javax.ws.rs.ProcessingException)4 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)4 Client (javax.ws.rs.client.Client)2 ClientConfig (org.glassfish.jersey.client.ClientConfig)2 GrizzlyConnectorProvider (org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 List (java.util.List)1 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1