use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class WatchTest method testResiliency.
@Test
public void testResiliency() throws Exception {
try (EtcdClient directClient = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build();
EtcdClient client = EtcdClient.forEndpoint("localhost", 2396).withPlainText().build()) {
directClient.getKvClient().delete(bs("watch-tr-test/")).asPrefix().sync();
try (final LocalNettyProxy prox = new LocalNettyProxy(2396)) {
Thread proxyThread = new Thread() {
{
setDaemon(true);
}
@Override
public void run() {
try {
int N = 4;
for (int i = 1; i <= N; i++) {
prox.start();
Thread.sleep(1000L + (long) (Math.random() * 5000));
System.out.println("killing proxy " + i);
// finish in running state
if (i < N)
prox.kill();
Thread.sleep((long) (Math.random() * 4000));
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
proxyThread.start();
KvClient directKv = directClient.getKvClient();
Phaser p = new Phaser(1);
Map<ByteString, Object> watchedKeys = new ConcurrentHashMap<>();
int i = 0;
// the proxy is stopped/started
while (proxyThread.isAlive()) {
// put a key
ByteString key = bs("watch-tr-test/" + Math.random());
ByteString value = bs("value " + (i++));
PutResponse pr = directKv.put(key, value).sync();
watchedKeys.put(key, "pending");
p.register();
final int ii = i;
AtomicReference<Watch> w = new AtomicReference<>();
w.set(client.getKvClient().watch(key).startRevision(pr.getHeader().getRevision()).start((ListenerObserver<WatchUpdate>) (complete, wu, err) -> {
if (complete) {
if (err != null) {
watchedKeys.replace(key, err);
err.printStackTrace();
} else
watchedKeys.remove(key);
if (w.get() == null)
p.arrive();
} else if (!wu.getEvents().isEmpty()) {
if (value.equals(wu.getEvents().get(0).getKv().getValue())) {
if (ii % 2 == 0) {
// cancel every other watch
w.get().close();
w.set(null);
} else {
watchedKeys.remove(key);
p.arrive();
}
} else {
watchedKeys.replace(key, "unexpected watch event value");
p.arrive();
}
}
}));
Thread.sleep((long) (Math.random() * 500));
}
p.arrive();
p.awaitAdvanceInterruptibly(0, 8, TimeUnit.SECONDS);
System.out.println("created " + i + " watches; left incomplete: " + watchedKeys.size());
watchedKeys.entrySet().forEach(e -> System.out.println("** " + e.getKey().toStringUtf8() + "=" + e.getValue()));
assertTrue(watchedKeys.isEmpty());
}
}
}
use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class WatchTest method testCreateFail.
@Test
public void testCreateFail() throws Exception {
KvStoreClient client = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build();
try {
KvClient kvc = client.getKvClient();
// range end before start => should fail
Watch watch2 = kvc.watch(ByteString.copyFromUtf8("/watchtest2")).rangeEnd(ByteString.copyFromUtf8("/watchtest1")).startRevision(-5000L).start((ListenerObserver<WatchUpdate>) (c, v, t) -> {
});
try {
watch2.get(1000, TimeUnit.SECONDS);
fail("watch future should fail");
} catch (ExecutionException e) {
System.out.println("watch creation failed with exception: " + e);
assertTrue(e.getCause() instanceof WatchCreateException);
}
} finally {
client.close();
}
}
use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class PersistentLeaseKeyTest method testLeaseKey.
@Test
public void testLeaseKey() throws Exception {
try (EtcdClient client = EtcdClient.forEndpoint("localhost", 2392).withPlainText().build();
EtcdClient directClient = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build()) {
KvClient directKvClient = directClient.getKvClient();
ByteString mykey = bs("mykeyy");
PersistentLeaseKey plk = new PersistentLeaseKey(client, mykey, bs("defaultdata"), null);
ListenableFuture<ByteString> startFuture = plk.startWithFuture();
Thread.sleep(300L);
// network conn to server not established yet
assertFalse(startFuture.isDone());
// key won't exist yet
assertEquals(0, directKvClient.get(mykey).countOnly().sync().getCount());
// reestablish network
proxy.start();
assertEquals(mykey, startFuture.get(3000, MILLISECONDS));
// check key is present via other client
assertEquals(bs("defaultdata"), directKvClient.get(mykey).sync().getKvs(0).getValue());
plk.closeWithFuture().get(500, MILLISECONDS);
// key should now be gone
assertEquals(0, directKvClient.get(bs("mykeyy")).countOnly().sync().getCount());
// -----------------
PersistentLease pl = client.getLeaseClient().maintain().minTtl(2).start();
System.out.println("PL state: " + pl.getState());
plk = new PersistentLeaseKey(client, pl, mykey, bs("somedata"), null);
plk.start();
assertFalse(pl.isDone());
Long leaseId = pl.get(1, TimeUnit.SECONDS);
assertNotNull(leaseId);
System.out.println("PL state: " + pl.getState());
// will take a small amount of time after lease is created for PLK to be
// created
assertFalse(plk.isDone());
plk.get(1, TimeUnit.SECONDS);
KeyValue kv = directKvClient.get(mykey).sync().getKvs(0);
assertEquals(bs("somedata"), kv.getValue());
assertEquals((long) leaseId, kv.getLease());
plk.setDefaultValue(bs("updateddata"));
Thread.sleep(200L);
// data doesn't change until key has to be recreated
assertEquals(bs("somedata"), directKvClient.get(mykey).sync().getKvs(0).getValue());
proxy.kill();
long ttl = pl.getCurrentTtlSecs();
System.out.println("TTL after kill is " + ttl);
Thread.sleep(1000L);
// key should still be there (lease not yet expired)
kv = directKvClient.get(mykey).sync().getKvs(0);
assertEquals(bs("somedata"), kv.getValue());
assertEquals((long) leaseId, kv.getLease());
Thread.sleep((pl.getCurrentTtlSecs() + 2) * 1000L);
// lease should have now expired and key should be gone
assertEquals(0, directKvClient.get(bs("mykeyy")).sync().getCount());
proxy.start();
long before = System.nanoTime();
try (WatchIterator it = directKvClient.watch(bs("mykeyy")).start()) {
for (int i = 0; i < 5; i++) {
List<Event> events = it.next().getEvents();
if (!events.isEmpty()) {
// key should be updated with new value once
// connection is reestablished
assertEquals(bs("updateddata"), events.get(0).getKv().getValue());
System.out.println("took " + (System.nanoTime() - before) / 1000_000L + "ms for key to re-appear");
break;
}
}
}
}
}
Aggregations