Search in sources :

Example 11 with EventSource

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

the class SseEventSinkToEventSourceTest method testWithJerseyApi.

@Test
public void testWithJerseyApi() throws InterruptedException {
    final WebTarget endpoint = target().path("events");
    final EventSource eventSource = EventSource.target(endpoint).build();
    transmitLatch = new CountDownLatch(MSG_COUNT);
    final CountDownLatch receiveLatch = new CountDownLatch(MSG_COUNT);
    final List<Integer> results = new ArrayList<>();
    final EventListener listener = inboundEvent -> {
        try {
            results.add(inboundEvent.readData(Integer.class));
            receiveLatch.countDown();
            Assert.assertEquals(INTEGER_SSE_NAME, inboundEvent.getName());
        } catch (ProcessingException ex) {
            throw new RuntimeException("Error when deserializing of data.", ex);
        }
    };
    eventSource.register(listener, INTEGER_SSE_NAME);
    eventSource.open();
    Assert.assertTrue(transmitLatch.await(5000, TimeUnit.MILLISECONDS));
    Assert.assertTrue(receiveLatch.await(5000, TimeUnit.MILLISECONDS));
    Assert.assertEquals(10, results.size());
}
Also used : SseEventSource(javax.ws.rs.sse.SseEventSource) SseEventSink(javax.ws.rs.sse.SseEventSink) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) Path(javax.ws.rs.Path) Application(javax.ws.rs.core.Application) Singleton(javax.inject.Singleton) ArrayList(java.util.ArrayList) MediaType(javax.ws.rs.core.MediaType) JerseyTest(org.glassfish.jersey.test.JerseyTest) Sse(javax.ws.rs.sse.Sse) ResourceConfig(org.glassfish.jersey.server.ResourceConfig) ExecutorService(java.util.concurrent.ExecutorService) Context(javax.ws.rs.core.Context) EventListener(org.glassfish.jersey.media.sse.EventListener) EventSource(org.glassfish.jersey.media.sse.EventSource) Test(org.junit.Test) Logger(java.util.logging.Logger) Executors(java.util.concurrent.Executors) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) InboundSseEvent(javax.ws.rs.sse.InboundSseEvent) ProcessingException(javax.ws.rs.ProcessingException) WebTarget(javax.ws.rs.client.WebTarget) Assert(org.junit.Assert) SseEventSource(javax.ws.rs.sse.SseEventSource) EventSource(org.glassfish.jersey.media.sse.EventSource) ArrayList(java.util.ArrayList) WebTarget(javax.ws.rs.client.WebTarget) EventListener(org.glassfish.jersey.media.sse.EventListener) CountDownLatch(java.util.concurrent.CountDownLatch) ProcessingException(javax.ws.rs.ProcessingException) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 12 with EventSource

use of org.glassfish.jersey.media.sse.EventSource 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 13 with EventSource

use of org.glassfish.jersey.media.sse.EventSource 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 14 with EventSource

use of org.glassfish.jersey.media.sse.EventSource 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)

Example 15 with EventSource

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

the class ItemStoreResourceITCase method close.

private static void close(final EventSource[] sources) {
    int i = 0;
    for (EventSource source : sources) {
        if (source.isOpen()) {
            assertTrue("Waiting to close a source has timed out.", source.close(1, TimeUnit.SECONDS));
            //                    source.close(100, TimeUnit.MILLISECONDS);
            LOGGER.info("[<--] SOURCE " + i++ + " closed.");
        }
    }
}
Also used : EventSource(org.glassfish.jersey.media.sse.EventSource)

Aggregations

EventSource (org.glassfish.jersey.media.sse.EventSource)15 CountDownLatch (java.util.concurrent.CountDownLatch)11 Test (org.junit.Test)11 InboundEvent (org.glassfish.jersey.media.sse.InboundEvent)10 JerseyTest (org.glassfish.jersey.test.JerseyTest)10 WebTarget (javax.ws.rs.client.WebTarget)9 EventListener (org.glassfish.jersey.media.sse.EventListener)9 ProcessingException (javax.ws.rs.ProcessingException)6 ArrayList (java.util.ArrayList)5 Queue (java.util.Queue)4 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)4 Client (javax.ws.rs.client.Client)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 ClientConfig (org.glassfish.jersey.client.ClientConfig)2 GrizzlyConnectorProvider (org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider)2 ResourceConfig (org.glassfish.jersey.server.ResourceConfig)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 LinkedList (java.util.LinkedList)1