Пример #1
0
 private static void open(final EventSource[] sources) {
   int i = 0;
   for (EventSource source : sources) {
     source.open();
     LOGGER.info("[-->] SOURCE " + i++ + " opened.");
   }
 }
  @Test
  public void testWithEventSource()
      throws IOException, NoSuchAlgorithmException, InterruptedException {
    final WebTarget target = target().register(SseFeature.class).path("events");
    EventSource eventSource = new EventSource(target, false);
    final CountDownLatch count = new CountDownLatch(MSG_COUNT);

    final EventListener listener =
        new EventListener() {
          @Override
          public void onEvent(InboundEvent inboundEvent) {
            try {
              final Integer data = inboundEvent.getData(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 (IOException e) {
              throw new RuntimeException("Error when deserializing of data.");
            }
          }
        };
    eventSource.register(listener, "message-to-client");
    eventSource.open();
    final boolean sent = latch.await(5, TimeUnit.SECONDS);
    Assert.assertTrue("Awaiting for SSE message has timeout. Not all message were sent.", sent);
    final boolean handled = count.await(5, TimeUnit.SECONDS);
    Assert.assertTrue(
        "Awaiting for SSE message has timeout. Not all message were handled by the listener.",
        handled);
  }
Пример #3
0
 public void removeCallback(String key) {
   // TODO remove an existing callback (if any) for bindings on key.
   // Be sure to close the event stream from the broadcaster.
   EventSource es = callbacks.remove(key);
   if (es != null) {
     es.close();
   }
   // Done
 }
Пример #4
0
 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.");
     }
   }
 }
Пример #5
0
  /**
   * 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");
    final CountDownLatch latch =
        new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2); // countdown only on new item events
    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, 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++;
    }
  }
Пример #6
0
  /**
   * 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");
    final CountDownLatch latch =
        new CountDownLatch(items.size() * MAX_LISTENERS * 2); // countdown on all events
    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
            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, 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());
  }