/** * Creates {@code Watch} to monitoring the custom user events. * The underlying Consul client will be created with default options. * This maps to the <a href="https://www.consul.io/docs/agent/http/event.html#event_list">/v1/event/list</a> API internally. * * @param event the event name * @param vertx the {@code Vertx} instance * @return the {@code Watch} instance */ static Watch<EventList> events(String event, Vertx vertx) { return events(event, vertx, new ConsulClientOptions()); }
/** * Creates {@code Watch} to monitoring a prefix of keys in the KV store. * The underlying Consul client will be created with default options. * This maps to the <a href="https://www.consul.io/api/kv.html">/v1/kv/</a> API internally. * * @param keyPrefix the key * @param vertx the {@code Vertx} instance * @return the {@code Watch} instance */ static Watch<KeyValueList> keyPrefix(String keyPrefix, Vertx vertx) { return keyPrefix(keyPrefix, vertx, new ConsulClientOptions()); }
@Test public void connectionRefused() throws InterruptedException { StateConsumer<Long> consumer = new StateConsumer<>(); String key = ConsulContext.KEY_RW_PREFIX + randomAlphaString(10); long t0 = System.currentTimeMillis(); Watch<KeyValue> watch = Watch.key(key, vertx, new ConsulClientOptions().setPort(Utils.getFreePort())) .setHandler(h -> { if (h.succeeded()) { fail(); } else { assertTrue(h.failed()); assertTrue(h.cause().getMessage().contains(CONNECTION_REFUSED)); consumer.consume(System.currentTimeMillis() - t0); } }) .start(); for (int i = 0; i < 5; i++) { consumer.awaitAny(); } consumer.check(); watch.stop(); List<Long> ticks = consumer.getConsumed(); List<Long> diff; diff = diff(ticks); // parabolic diff = diff(diff); // proportionality diff = diff(diff); // constant (~2000) long zero = diff(diff).get(0); // zero System.out.println("zero: " + zero); assertTrue(Math.abs(zero) < 1000); }
@Test public void watchServices() throws InterruptedException { StateConsumer<String> consumer = new StateConsumer<>(); ServiceOptions service = new ServiceOptions() .setId(randomAlphaString(10)) .setName(randomAlphaString(10)); Watch<ServiceList> watch = Watch.services(vertx, ctx.readClientOptions()) .setHandler(list -> { if (list.succeeded()) { consumer.consume(list.nextResult().getList() .stream().map(Service::getName).filter(s -> s.equals(service.getName())) .findFirst().orElse("")); } }) .start(); consumer.await(""); runAsync(h -> ctx.writeClient().registerService(service, h)); consumer.await(service.getName()); consumer.check(); watch.stop(); runAsync(h -> ctx.writeClient().deregisterService(service.getId(), h)); }
@Test public void testKeyPrefix() throws InterruptedException { StateConsumer<String> consumer = new StateConsumer<>(); String keyPrefix = ConsulContext.KEY_RW_PREFIX + randomAlphaString(10); String k1 = keyPrefix + randomAlphaString(10); String k2 = keyPrefix + randomAlphaString(10); String v1 = randomAlphaString(10); String v2 = randomAlphaString(10); assertTrue(getAsync(h -> ctx.writeClient().putValue(k1, v1, h))); Watch<KeyValueList> watch = Watch.keyPrefix(keyPrefix, vertx, ctx.readClientOptions()) .setHandler(kv -> { if (kv.succeeded()) { if (kv.nextResult().isPresent()) { consumer.consume(kv.nextResult().getList().stream().map(KeyValue::getValue).sorted().collect(Collectors.joining("/"))); } else { consumer.consume(EMPTY_MESSAGE); } } else { consumer.consume(kv.cause().getMessage()); } }) .start(); consumer.await(v1); assertTrue(getAsync(h -> ctx.writeClient().putValue(k2, v2, h))); consumer.await(Stream.of(v1, v2).sorted().collect(Collectors.joining("/"))); runAsync(h -> ctx.writeClient().deleteValues(keyPrefix, h)); consumer.await(EMPTY_MESSAGE); consumer.check(); watch.stop(); }
@Test public void watchEvents() throws InterruptedException { StateConsumer<String> consumer = new StateConsumer<>(); String evName = randomAlphaString(10); String p1 = randomAlphaString(10); String p2 = randomAlphaString(10); Watch<EventList> watch = Watch.events(evName, vertx, ctx.readClientOptions()) .setHandler(list -> { if (list.succeeded()) { consumer.consume(list.nextResult().getList() .stream().map(Event::getPayload).collect(Collectors.joining(","))); } }) .start(); consumer.await(""); Utils.<Event>getAsync(h -> ctx.writeClient().fireEventWithOptions(evName, new EventOptions().setPayload(p1), h)); Utils.<Event>getAsync(h -> ctx.writeClient().fireEventWithOptions(randomAlphaString(10), new EventOptions().setPayload(randomAlphaString(10)), h)); Utils.<Event>getAsync(h -> ctx.writeClient().fireEventWithOptions(evName, new EventOptions().setPayload(p2), h)); consumer.await(p1); consumer.await(p1 + "," + p2); consumer.check(); watch.stop(); }
@Test public void watchService() throws InterruptedException { StateConsumer<String> consumer = new StateConsumer<>(); ServiceOptions service = new ServiceOptions() .setCheckOptions(new CheckOptions() .setStatus(CheckStatus.PASSING) .setTtl("4s") .setName(randomAlphaString(10))) .setId(randomAlphaString(10)) .setName(randomAlphaString(10)); Watch<ServiceEntryList> watch = Watch.service(service.getName(), vertx, ctx.readClientOptions()) .setHandler(list -> { if (list.succeeded()) { consumer.consume(list.nextResult().getList() .stream().filter(s -> s.getService().getName().equals(service.getName())) .map(e -> e.getService().getName() + "/" + e.getChecks().stream() .filter(c -> c.getId().equals("service:" + service.getId())) .map(c -> c.getStatus().name()).findFirst().orElse("")) .findFirst().orElse("")); } }) .start(); consumer.await(""); runAsync(h -> ctx.writeClient().registerService(service, h)); consumer.await(service.getName() + "/" + CheckStatus.PASSING.name()); consumer.await(service.getName() + "/" + CheckStatus.CRITICAL.name()); consumer.check(); watch.stop(); runAsync(h -> ctx.writeClient().deregisterService(service.getId(), h)); }
@Test public void watchNodes() throws InterruptedException { StateConsumer<String> consumer = new StateConsumer<>(); String nodeName = randomAlphaString(10); Watch<NodeList> watch = Watch.nodes(vertx, ctx.readClientOptions()) .setHandler(list -> { if (list.succeeded()) { consumer.consume(list.nextResult().getList() .stream().map(Node::getName).filter(s -> s.equals(nodeName)) .findFirst().orElse("")); } }) .start(); consumer.await(""); ConsulAgent attached = ctx.attachAgent(nodeName); ctx.detachAgent(attached); consumer.await(nodeName); consumer.await(""); consumer.check(); watch.stop(); } }
/** * Creates {@code Watch} to monitoring the list of available services. * The underlying Consul client will be created with default options. * This maps to the <a href="https://www.consul.io/docs/agent/http/catalog.html#catalog_services">/v1/catalog/services</a> API internally. * * @param vertx the {@code Vertx} instance * @return the {@code Watch} instance */ static Watch<ServiceList> services(Vertx vertx) { return services(vertx, new ConsulClientOptions()); }
/** * Creates {@code Watch} to monitoring a specific key in the KV store. * The underlying Consul client will be created with default options. * This maps to the <a href="https://www.consul.io/api/kv.html">/v1/kv/</a> API internally. * * @param key the key * @param vertx the {@code Vertx} instance * @return the {@code Watch} instance */ static Watch<KeyValue> key(String key, Vertx vertx) { return key(key, vertx, new ConsulClientOptions()); }
/** * Creates {@code Watch} to monitoring the nodes providing the service. * The underlying Consul client will be created with default options. * This maps to the <a href="https://www.consul.io/docs/agent/http/health.html#health_service">/v1/health/service/<service></a> API internally. * * @param service the service name * @param vertx the {@code Vertx} instance * @return the {@code Watch} instance */ static Watch<ServiceEntryList> service(String service, Vertx vertx) { return service(service, vertx, new ConsulClientOptions()); }
/** * Creates <code>Watch</code> to monitoring the list of available nodes. * The underlying Consul client will be created with default options. * This maps to the <a href="https://www.consul.io/api/catalog.html#list-nodes">/v1/catalog/nodes</a> API internally. * @param vertx the <code>Vertx</code> instance * @return the <code>Watch</code> instance */ public static io.vertx.rxjava.ext.consul.Watch<NodeList> nodes(io.vertx.rxjava.core.Vertx vertx) { io.vertx.rxjava.ext.consul.Watch<NodeList> ret = io.vertx.rxjava.ext.consul.Watch.newInstance(io.vertx.ext.consul.Watch.nodes(vertx.getDelegate()), io.vertx.lang.rx.TypeArg.unknown()); return ret; }
/** * Stop the watch and release its resources */ public void stop() { delegate.stop(); }
/** * Start this <code>Watch</code> * @return reference to this, for fluency */ public io.vertx.rxjava.ext.consul.Watch<T> start() { delegate.start(); return this; }
/** * Set the result handler. As data is changed, the handler will be called with the result. * @param handler the result handler * @return reference to this, for fluency */ public io.vertx.rxjava.ext.consul.Watch<T> setHandler(Handler<io.vertx.rxjava.ext.consul.WatchResult<T>> handler) { delegate.setHandler(new Handler<io.vertx.ext.consul.WatchResult<T>>() { public void handle(io.vertx.ext.consul.WatchResult<T> event) { handler.handle(io.vertx.rxjava.ext.consul.WatchResult.newInstance(event, __typeArg_0)); } }); return this; }
@Test public void watchExistingKey() throws InterruptedException { StateConsumer<String> consumer = new StateConsumer<>(); String key = ConsulContext.KEY_RW_PREFIX + randomAlphaString(10); String v1 = randomAlphaString(10); String v2 = randomAlphaString(10); assertTrue(getAsync(h -> ctx.writeClient().putValue(key, v1, h))); Watch<KeyValue> watch = Watch.key(key, vertx, ctx.readClientOptions()) .setHandler(kv -> { if (kv.succeeded()) { consumer.consume(kv.nextResult().isPresent() ? kv.nextResult().getValue() : EMPTY_MESSAGE); } else { consumer.consume(kv.cause().getMessage()); } }) .start(); consumer.await(v1); assertTrue(getAsync(h -> ctx.writeClient().putValue(key, v2, h))); consumer.await(v2); runAsync(h -> ctx.writeClient().deleteValue(key, h)); consumer.await(EMPTY_MESSAGE); consumer.check(); watch.stop(); }
/** * Creates <code>Watch</code> to monitoring the list of available services. * This maps to the <a href="https://www.consul.io/docs/agent/http/catalog.html#catalog_services">/v1/catalog/services</a> API internally. * @param vertx the <code>Vertx</code> instance * @param options the options to create underlying Consul client * @return the <code>Watch</code> instance */ public static io.vertx.rxjava.ext.consul.Watch<ServiceList> services(io.vertx.rxjava.core.Vertx vertx, ConsulClientOptions options) { io.vertx.rxjava.ext.consul.Watch<ServiceList> ret = io.vertx.rxjava.ext.consul.Watch.newInstance(io.vertx.ext.consul.Watch.services(vertx.getDelegate(), options), io.vertx.lang.rx.TypeArg.unknown()); return ret; }
/** * Creates <code>Watch</code> to monitoring a specific key in the KV store. * This maps to the <a href="https://www.consul.io/api/kv.html">/v1/kv/</a> API internally. * @param key the key * @param vertx the <code>Vertx</code> instance * @param options the options to create underlying Consul client * @return the <code>Watch</code> instance */ public static io.vertx.rxjava.ext.consul.Watch<KeyValue> key(String key, io.vertx.rxjava.core.Vertx vertx, ConsulClientOptions options) { io.vertx.rxjava.ext.consul.Watch<KeyValue> ret = io.vertx.rxjava.ext.consul.Watch.newInstance(io.vertx.ext.consul.Watch.key(key, vertx.getDelegate(), options), io.vertx.lang.rx.TypeArg.unknown()); return ret; }