Search in sources :

Example 6 with InboundEvent

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

the class EventOutputTest method testReadCommentsOnlySseEvents.

/**
     * Reproducer for JERSEY-2912: Sending and receiving comments-only events.
     *
     * @throws Exception
     */
@Test
public void testReadCommentsOnlySseEvents() throws Exception {
    ClientConfig clientConfig = new ClientConfig();
    clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 15000);
    clientConfig.property(ClientProperties.READ_TIMEOUT, 0);
    clientConfig.property(ClientProperties.ASYNC_THREADPOOL_SIZE, 8);
    clientConfig.connectorProvider(new GrizzlyConnectorProvider());
    Client client = ClientBuilder.newBuilder().withConfig(clientConfig).build();
    final CountDownLatch latch = new CountDownLatch(2);
    final Queue<String> eventComments = new ArrayBlockingQueue<>(2);
    WebTarget single = client.target(getBaseUri()).path("test/comments-only");
    EventSource es = EventSource.target(single).build();
    es.register(new EventListener() {

        @Override
        public void onEvent(InboundEvent inboundEvent) {
            eventComments.add(inboundEvent.getComment());
            latch.countDown();
        }
    });
    boolean latchTimedOut;
    boolean closeTimedOut;
    try {
        es.open();
        latchTimedOut = latch.await(5 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS);
    } finally {
        closeTimedOut = es.close(5, TimeUnit.SECONDS);
    }
    assertEquals("Unexpected event count", 2, eventComments.size());
    for (int i = 1; i <= 2; i++) {
        assertEquals("Unexpected comment data on event #" + i, "No comment #" + i, eventComments.poll());
    }
    assertTrue("Event latch has timed out", latchTimedOut);
    assertTrue("EventSource.close() has timed out", closeTimedOut);
}
Also used : GrizzlyConnectorProvider(org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider) Matchers.containsString(org.hamcrest.Matchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) EventSource(org.glassfish.jersey.media.sse.EventSource) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) InboundEvent(org.glassfish.jersey.media.sse.InboundEvent) WebTarget(javax.ws.rs.client.WebTarget) EventListener(org.glassfish.jersey.media.sse.EventListener) ClientConfig(org.glassfish.jersey.client.ClientConfig) Client(javax.ws.rs.client.Client) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 7 with InboundEvent

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

the class EventSourceWithNamedEventsTest method testWithEventSource.

@Test
public void testWithEventSource() throws IOException, NoSuchAlgorithmException, InterruptedException {
    final WebTarget endpoint = target().register(SseFeature.class).path("events");
    EventSource eventSource = EventSource.target(endpoint).build();
    final CountDownLatch count = new CountDownLatch(MSG_COUNT);
    final EventListener listener = new EventListener() {

        @Override
        public void onEvent(InboundEvent inboundEvent) {
            try {
                final Integer data = inboundEvent.readData(Integer.class);
                System.out.println(inboundEvent.getName() + "; " + data);
                Assert.assertEquals(SSE_NAME, inboundEvent.getName());
                Assert.assertEquals(MSG_COUNT - count.getCount(), data.intValue());
                count.countDown();
            } catch (ProcessingException ex) {
                throw new RuntimeException("Error when deserializing of data.", ex);
            }
        }
    };
    eventSource.register(listener, "message-to-client");
    eventSource.open();
    final boolean sent = latch.await(5 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS);
    Assert.assertTrue("Awaiting for SSE message has timeout. Not all message were sent.", sent);
    final boolean handled = count.await(5 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS);
    Assert.assertTrue("Awaiting for SSE message has timeout. Not all message were handled by the listener.", handled);
}
Also used : 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) CountDownLatch(java.util.concurrent.CountDownLatch) SseFeature(org.glassfish.jersey.media.sse.SseFeature) ProcessingException(javax.ws.rs.ProcessingException) Test(org.junit.Test) JerseyTest(org.glassfish.jersey.test.JerseyTest)

Example 8 with InboundEvent

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

the class ServerSentEventsTest method testInboundEventReader.

/**
     * Test consuming multiple SSE events sequentially using event input.
     *
     * @throws Exception in case of a failure during the test execution.
     */
@Test
public void testInboundEventReader() throws Exception {
    final int MAX_MESSAGES = 5;
    final CountDownLatch startLatch = new CountDownLatch(1);
    final ExecutorService executor = Executors.newSingleThreadExecutor();
    try {
        final Future<List<String>> futureMessages = executor.submit(new Callable<List<String>>() {

            @Override
            public List<String> call() throws Exception {
                final EventInput eventInput = target(App.ROOT_PATH).register(SseFeature.class).request().get(EventInput.class);
                startLatch.countDown();
                final List<String> messages = new ArrayList<String>(MAX_MESSAGES);
                try {
                    for (int i = 0; i < MAX_MESSAGES; i++) {
                        InboundEvent event = eventInput.read();
                        messages.add(event.readData());
                    }
                } finally {
                    if (eventInput != null) {
                        eventInput.close();
                    }
                }
                return messages;
            }
        });
        assertTrue("Waiting for receiver thread to start has timed out.", startLatch.await(5, TimeUnit.SECONDS));
        for (int i = 0; i < MAX_MESSAGES; i++) {
            target(App.ROOT_PATH).request().post(Entity.text("message " + i));
        }
        int i = 0;
        for (String message : futureMessages.get(5000, TimeUnit.SECONDS)) {
            assertThat("Unexpected SSE event data value.", message, equalTo("message " + i++));
        }
    } finally {
        executor.shutdownNow();
    }
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) ProcessingException(javax.ws.rs.ProcessingException) SseFeature(org.glassfish.jersey.media.sse.SseFeature) InboundEvent(org.glassfish.jersey.media.sse.InboundEvent) EventInput(org.glassfish.jersey.media.sse.EventInput) ExecutorService(java.util.concurrent.ExecutorService) ArrayList(java.util.ArrayList) List(java.util.List) JerseyTest(org.glassfish.jersey.test.JerseyTest) Test(org.junit.Test)

Example 9 with InboundEvent

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

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

Aggregations

InboundEvent (org.glassfish.jersey.media.sse.InboundEvent)12 CountDownLatch (java.util.concurrent.CountDownLatch)11 Test (org.junit.Test)11 EventSource (org.glassfish.jersey.media.sse.EventSource)10 JerseyTest (org.glassfish.jersey.test.JerseyTest)10 WebTarget (javax.ws.rs.client.WebTarget)8 EventListener (org.glassfish.jersey.media.sse.EventListener)8 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 SseFeature (org.glassfish.jersey.media.sse.SseFeature)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 LinkedList (java.util.LinkedList)1