use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class RangeCacheTest method testBasics.
@Test
public void testBasics() throws Exception {
KvClient kvc = client.getKvClient();
kvc.delete(bs("tmp/")).asPrefix().sync();
try (RangeCache rc = new RangeCache(client, bs("tmp/"), false)) {
PutResult pr = rc.put(bs("tmp/a"), bs("val1"), 0L);
assertTrue(pr.succ());
assertEquals(bs("val1"), pr.kv().getValue());
rc.start().get(1L, TimeUnit.SECONDS);
assertTrue(rc.delete(bs("tmp/a")));
assertFalse(rc.delete(bs("tmp/c")));
assertTrue(rc.put(bs("tmp/a"), bs("val1"), 0L).succ());
assertEquals(bs("val1"), rc.get(bs("tmp/a")).getValue());
assertEquals(bs("val1"), rc.getRemote(bs("tmp/a")).getValue());
assertEquals(1, Iterators.size(rc.iterator()));
Iterator<KeyValue> it = rc.iterator(), sit = rc.strongIterator();
assertTrue(Iterators.elementsEqual(it, sit));
KvClient directKv = directClient.getKvClient();
directKv.put(bs("tmp/d"), bs("val2")).sync();
Thread.sleep(80L);
assertEquals(bs("val2"), rc.get(bs("tmp/d")).getValue());
directKv.put(bs("tmp/d"), bs("valX")).sync();
Thread.sleep(80L);
assertEquals(bs("valX"), rc.get(bs("tmp/d")).getValue());
directKv.delete(bs("tmp/d")).sync();
Thread.sleep(80L);
assertNull(rc.get(bs("tmp/d")));
}
}
use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class RangeCacheTest method testStrongIterator.
@Test
public void testStrongIterator() throws Exception {
KvClient kvc = directClient.getKvClient();
kvc.delete(bs("sit-test/")).asPrefix().sync();
kvc.delete(bs("sit-test")).sync();
kvc.put(bs("sit-test/a"), bs("val")).sync();
kvc.put(bs("sit-test/d"), bs("val")).sync();
try (RangeCache rc = new RangeCache(directClient, bs("sit-test/"), false)) {
// NOTE first RangeCache has NOT been started
assertEquals(0, Iterators.size(rc.iterator()));
assertEquals(2, Iterators.size(rc.strongIterator()));
try (RangeCache rc2 = new RangeCache(directClient, bs("sit-test/"), false)) {
rc2.delete(bs("sit-test/d"));
assertEquals(0, Iterators.size(rc.iterator()));
assertEquals(1, Iterators.size(rc.strongIterator()));
// assertEquals(1, Iterators.size(rc.iterator()));
}
}
}
use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class WatchTest method testWatch.
@Test
public void testWatch() throws Exception {
proxy.start();
try (KvStoreClient directClient = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build();
KvStoreClient client = EtcdClient.forEndpoint("localhost", 2390).withPlainText().build()) {
KvClient kvc = client.getKvClient();
long start = System.currentTimeMillis();
final BlockingQueue<Object> watchEvents = new LinkedBlockingQueue<>();
final Object COMPLETED = new Object();
final StreamObserver<WatchUpdate> observer = new StreamObserver<WatchUpdate>() {
@Override
public void onNext(WatchUpdate value) {
System.out.println(t(start) + "watch event: " + value);
watchEvents.add(value);
}
@Override
public void onError(Throwable t) {
System.out.println(t(start) + "watch error: " + t);
watchEvents.add(t);
}
@Override
public void onCompleted() {
System.out.println(t(start) + "watch completed");
watchEvents.add(COMPLETED);
}
};
Watch watch = kvc.watch(bs("/watchtest")).asPrefix().start(observer);
// assertFalse(watch.isDone());
// test blocking watch at the same time
WatchIterator watchIterator = kvc.watch(bs("/watchtest")).asPrefix().start();
assertTrue(watch.get(1, TimeUnit.SECONDS));
kvc.put(bs("/watchtest/a"), bs("a value")).sync();
directClient.getKvClient().put(bs("/watchtest/b"), bs("b value")).sync();
WatchUpdate wu = getNextSkipEmpty(watchEvents);
assertNotNull(wu);
assertEquals("event: " + wu, 1, wu.getEvents().size());
assertEquals(EventType.PUT, wu.getEvents().get(0).getType());
assertEquals(bs("a value"), wu.getEvents().get(0).getKv().getValue());
assertEquals(bs("/watchtest/a"), wu.getEvents().get(0).getKv().getKey());
WatchUpdate wu2 = getNextSkipEmpty(watchIterator);
assertEquals(EventType.PUT, wu2.getEvents().get(0).getType());
assertEquals(bs("a value"), wu2.getEvents().get(0).getKv().getValue());
assertEquals(bs("/watchtest/a"), wu2.getEvents().get(0).getKv().getKey());
watchEvents.poll(500, TimeUnit.MILLISECONDS);
watch.close();
assertEquals(COMPLETED, watchEvents.poll(500, TimeUnit.MILLISECONDS));
kvc.put(bs("/watchtest/c"), bs("c value")).sync();
assertNull(watchEvents.poll(500, TimeUnit.MILLISECONDS));
assertTrue(watchIterator.hasNext());
assertTrue(watchIterator.hasNext());
assertEquals(bs("b value"), watchIterator.next().getEvents().get(0).getKv().getValue());
assertEquals(EventType.PUT, watchIterator.next().getEvents().get(0).getType());
// fresh new watch
watch = kvc.watch(ByteString.copyFromUtf8("/watchtest")).asPrefix().start(observer);
assertTrue(watch.get(1, TimeUnit.SECONDS));
kvc.batch().put(kvc.put(bs("/watchtest/d"), bs("d value")).asRequest()).delete(kvc.delete(bs("/watchtest/a")).asRequest()).sync();
wu = getNextSkipEmpty(watchEvents);
assertEquals(2, wu.getEvents().size());
assertTrue(wu.getEvents().stream().anyMatch(e -> e.getType() == EventType.DELETE));
assertTrue(wu.getEvents().stream().anyMatch(e -> e.getType() == EventType.PUT));
// kill path to server
proxy.kill();
Thread.sleep(1000L);
// while disconnected, put a new key
directClient.getKvClient().put(bs("/watchtest/e"), bs("e value")).sync();
Thread.sleep(1000L);
// reinstate path to server
proxy.start();
// watch should be unaffected - next event seen should be the missed one
wu = (WatchUpdate) watchEvents.poll(3000L, TimeUnit.MILLISECONDS);
assertEquals(bs("/watchtest/e"), wu.getEvents().get(0).getKv().getKey());
watch.close();
// (earlier batch update)
assertEquals(2, watchIterator.next().getEvents().size());
assertEquals(bs("/watchtest/e"), watchIterator.next().getEvents().get(0).getKv().getKey());
watchIterator.close();
assertNull(watchIterator.next().getHeader());
assertFalse(watchIterator.hasNext());
try {
watchIterator.next();
fail("should throw NSEE here");
} catch (NoSuchElementException nsee) {
}
} finally {
proxy.kill();
}
}
use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class KvTest method testKvOps.
@Test
public void testKvOps() throws Exception {
proxy.start();
try (KvStoreClient directClient = EtcdClient.forEndpoint("localhost", 2379).withPlainText().build();
KvStoreClient client = EtcdClient.forEndpoint("localhost", 2391).withPlainText().build()) {
KvClient kvc = client.getKvClient();
assertEquals(0L, kvc.delete(bs("notthere")).sync().getDeleted());
ByteString a = bs("a"), b = bs("b"), v1 = bs("v1"), v2 = bs("v2");
// basic put
assertTrue(kvc.put(a, v1).sync().getHeader().getRevision() > 0);
// basic get
RangeResponse rr = kvc.get(bs("a")).sync();
assertEquals(1L, rr.getCount());
assertEquals(v1, rr.getKvs(0).getValue());
// basic delete
assertEquals(v1, kvc.delete(a).prevKv().sync().getPrevKvs(0).getValue());
assertEquals(0, kvc.get(bs("a")).sync().getCount());
PutRequest pr1 = kvc.put(a, v1).asRequest(), pr2 = kvc.put(b, v2).asRequest();
// batch put
assertEquals(2, kvc.batch().put(pr1).put(pr2).sync().getResponsesCount());
assertEquals(v1, kvc.get(a).sync().getKvs(0).getValue());
assertEquals(v2, kvc.get(b).sync().getKvs(0).getValue());
// basic transaction
ListenableFuture<TxnResponse> tresp = kvc.txnIf().cmpEqual(a).value(v1).and().cmpNotEqual(b).version(10).then().put(kvc.put(bs("new"), bs("newval")).asRequest()).async();
assertNotNull(tresp.get().getResponses(0).getResponsePut().getHeader());
// test disconnected behaviour
proxy.kill();
Thread.sleep(200L);
// should fail
ListenableFuture<RangeResponse> rrFut1 = kvc.get(bs("new")).async();
ListenableFuture<RangeResponse> rrFut2 = kvc.get(bs("new")).backoffRetry().async();
try {
rrFut1.get(1000, TimeUnit.SECONDS);
fail("expected get to fail while disconnected");
} catch (Exception e) {
// TODO
System.out.println("failed with: " + e);
}
// this one should still be retrying
assertFalse(rrFut2.isDone());
// reconnect
proxy.start();
// should succeed once network path is there again
long before = System.nanoTime();
RangeResponse rr2 = rrFut2.get(2000, TimeUnit.SECONDS);
long took = (System.nanoTime() - before) / 1000_000L;
assertEquals(bs("newval"), rr2.getKvs(0).getValue());
System.out.println("took " + took + "ms after network was reestablished");
} finally {
proxy.close();
}
}
use of com.ibm.etcd.client.kv.KvClient in project etcd-java by IBM.
the class RangeCacheTest method testResiliency.
@Test
public void testResiliency() throws Exception {
directClient.getKvClient().delete(bs("tmp2/")).asPrefix().sync();
try (EtcdClient rcClient = EtcdClient.forEndpoint("localhost", 2395).withPlainText().build();
RangeCache rc = new RangeCache(rcClient, bs("tmp2/"), false)) {
rc.start();
Map<ByteString, ByteString> localMap = new HashMap<>();
try (final LocalNettyProxy prox = new LocalNettyProxy(2395)) {
Thread proxyThread = new Thread() {
{
setDaemon(true);
}
@Override
public void run() {
try {
int N = 6;
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();
int i = 0;
// the proxy is stopped/started
while (proxyThread.isAlive()) {
// put a key
ByteString key = bs("tmp2/" + Math.random());
ByteString value = bs("value " + (i++));
directKv.put(key, value).sync();
localMap.put(key, value);
if (i > 5 && !localMap.isEmpty()) {
// delete a key
Thread.sleep(((long) (Math.random() * 100)));
ByteString randomKey = Iterables.get(localMap.keySet(), (int) (Math.random() * localMap.size()));
directKv.delete(randomKey).sync();
localMap.remove(randomKey);
Thread.sleep(((long) (Math.random() * 100)));
}
if (i > 3) {
// perform batch update (3 puts, 1 delete)
FluentTxnOps<?> batch = directKv.batch();
if (!localMap.isEmpty()) {
ByteString randomKey = Iterables.get(localMap.keySet(), (int) (Math.random() * localMap.size()));
batch.delete(directKv.delete(randomKey).asRequest());
localMap.remove(randomKey);
}
for (int j = 0; j < 3; j++) {
key = bs("tmp2/" + Math.random());
value = bs("value " + (i++));
batch.put(directKv.put(key, value).asRequest());
localMap.put(key, value);
}
// commit batch txn
batch.sync();
Thread.sleep(((long) (Math.random() * 100)));
}
}
int ls = localMap.size(), rs = (int) directKv.get(bs("tmp2/")).asPrefix().countOnly().sync().getCount();
System.out.println("local map size is " + localMap.size());
System.out.println("remote size is " + rs);
assertEquals(ls, rs);
// wait until connected and to catch up
rcClient.getKvClient().get(bs("tmp/")).backoffRetry().sync();
Thread.sleep(5_000L);
System.out.println("rc size is " + rc.size());
// check contents of cache == contents of local map
assertEquals(localMap.entrySet(), Sets.newHashSet(Iterables.transform(rc, kv -> Maps.immutableEntry(kv.getKey(), kv.getValue()))));
}
}
}
Aggregations