Search in sources :

Example 1 with KvClient

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")));
    }
}
Also used : KeyValue(com.ibm.etcd.api.KeyValue) KvClient(com.ibm.etcd.client.kv.KvClient) PutResult(com.ibm.etcd.client.utils.RangeCache.PutResult) Test(org.junit.Test)

Example 2 with KvClient

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()));
        }
    }
}
Also used : KvClient(com.ibm.etcd.client.kv.KvClient) Test(org.junit.Test)

Example 3 with KvClient

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();
    }
}
Also used : StreamObserver(io.grpc.stub.StreamObserver) AfterClass(org.junit.AfterClass) WatchUpdate(com.ibm.etcd.client.kv.WatchUpdate) BeforeClass(org.junit.BeforeClass) Watch(com.ibm.etcd.client.kv.KvClient.Watch) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) KvClient(com.ibm.etcd.client.kv.KvClient) BlockingQueue(java.util.concurrent.BlockingQueue) Test(org.junit.Test) WatchIterator(com.ibm.etcd.client.kv.KvClient.WatchIterator) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) AtomicReference(java.util.concurrent.atomic.AtomicReference) WatchCreateException(com.ibm.etcd.client.watch.WatchCreateException) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) ByteString(com.google.protobuf.ByteString) StreamObserver(io.grpc.stub.StreamObserver) Map(java.util.Map) Phaser(java.util.concurrent.Phaser) EventType(com.ibm.etcd.api.Event.EventType) KvTest.bs(com.ibm.etcd.client.KvTest.bs) Assert(org.junit.Assert) NoSuchElementException(java.util.NoSuchElementException) PutResponse(com.ibm.etcd.api.PutResponse) KvTest.t(com.ibm.etcd.client.KvTest.t) WatchUpdate(com.ibm.etcd.client.kv.WatchUpdate) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Watch(com.ibm.etcd.client.kv.KvClient.Watch) KvClient(com.ibm.etcd.client.kv.KvClient) NoSuchElementException(java.util.NoSuchElementException) WatchIterator(com.ibm.etcd.client.kv.KvClient.WatchIterator) Test(org.junit.Test)

Example 4 with KvClient

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();
    }
}
Also used : KvStoreClient(com.ibm.etcd.client.KvStoreClient) RangeResponse(com.ibm.etcd.api.RangeResponse) ByteString(com.google.protobuf.ByteString) KvClient(com.ibm.etcd.client.kv.KvClient) PutRequest(com.ibm.etcd.api.PutRequest) TxnResponse(com.ibm.etcd.api.TxnResponse) Test(org.junit.Test)

Example 5 with KvClient

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()))));
        }
    }
}
Also used : LocalNettyProxy(com.ibm.etcd.client.LocalNettyProxy) EtcdClient(com.ibm.etcd.client.EtcdClient) HashMap(java.util.HashMap) ByteString(com.google.protobuf.ByteString) KvClient(com.ibm.etcd.client.kv.KvClient) Test(org.junit.Test)

Aggregations

KvClient (com.ibm.etcd.client.kv.KvClient)8 Test (org.junit.Test)8 ByteString (com.google.protobuf.ByteString)6 PutResponse (com.ibm.etcd.api.PutResponse)3 Watch (com.ibm.etcd.client.kv.KvClient.Watch)3 WatchIterator (com.ibm.etcd.client.kv.KvClient.WatchIterator)3 WatchCreateException (com.ibm.etcd.client.watch.WatchCreateException)3 NoSuchElementException (java.util.NoSuchElementException)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ExecutionException (java.util.concurrent.ExecutionException)3 Phaser (java.util.concurrent.Phaser)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 EventType (com.ibm.etcd.api.Event.EventType)2 KeyValue (com.ibm.etcd.api.KeyValue)2 EtcdClient (com.ibm.etcd.client.EtcdClient)2 KvTest.bs (com.ibm.etcd.client.KvTest.bs)2 KvTest.t (com.ibm.etcd.client.KvTest.t)2 WatchUpdate (com.ibm.etcd.client.kv.WatchUpdate)2 StreamObserver (io.grpc.stub.StreamObserver)2 Map (java.util.Map)2