Search in sources :

Example 1 with NotifyListener

use of org.apache.dubbo.registry.NotifyListener in project dubbo by alibaba.

the class EtcdRegistry method doSubscribe.

@Override
public void doSubscribe(URL url, NotifyListener listener) {
    try {
        if (ANY_VALUE.equals(url.getServiceInterface())) {
            String root = toRootPath();
            /*
                 *  if we are interested in all interfaces,
                 *  find out the current container or create one for the url, put or get only once.
                 */
            ConcurrentMap<NotifyListener, ChildListener> listeners = Optional.ofNullable(etcdListeners.get(url)).orElseGet(() -> {
                ConcurrentMap<NotifyListener, ChildListener> container, prev;
                prev = etcdListeners.putIfAbsent(url, container = new ConcurrentHashMap<>());
                return prev != null ? prev : container;
            });
            /*
                 *  if we have no interface watcher listener,
                 *  find the current listener or create one for the current root, put or get only once.
                 */
            ChildListener interfaceListener = Optional.ofNullable(listeners.get(listener)).orElseGet(() -> {
                ChildListener childListener, prev;
                prev = listeners.putIfAbsent(listener, childListener = (parentPath, currentChildren) -> {
                    /*
                                         *  because etcd3 does not support direct children watch events,
                                         *  we should filter not interface events. if we watch /dubbo
                                         *  and /dubbo/interface, when we put a key-value pair {/dubbo/interface/hello hello},
                                         *  we will got events in watching path /dubbo.
                                         */
                    for (String child : currentChildren) {
                        child = URL.decode(child);
                        if (!anyServices.contains(child)) {
                            anyServices.add(child);
                            /*
                                                 *  if new interface event arrived, we watch their direct children,
                                                 *  eg: /dubbo/interface, /dubbo/interface and so on.
                                                 */
                            subscribe(url.setPath(child).addParameters(INTERFACE_KEY, child, CHECK_KEY, String.valueOf(false)), listener);
                        }
                    }
                });
                return prev != null ? prev : childListener;
            });
            etcdClient.create(root);
            /*
                 * at the first time, we want to pull already interface and then watch their direct children,
                 *  eg: /dubbo/interface, /dubbo/interface and so on.
                 */
            List<String> services = etcdClient.addChildListener(root, interfaceListener);
            for (String service : services) {
                service = URL.decode(service);
                anyServices.add(service);
                subscribe(url.setPath(service).addParameters(INTERFACE_KEY, service, CHECK_KEY, String.valueOf(false)), listener);
            }
        } else {
            List<URL> urls = new ArrayList<>();
            for (String path : toCategoriesPath(url)) {
                /*
                     *  if we are interested in special categories (providers, consumers, routers and so on),
                     *  we find out the current container or create one for the url, put or get only once.
                     */
                ConcurrentMap<NotifyListener, ChildListener> listeners = Optional.ofNullable(etcdListeners.get(url)).orElseGet(() -> {
                    ConcurrentMap<NotifyListener, ChildListener> container, prev;
                    prev = etcdListeners.putIfAbsent(url, container = new ConcurrentHashMap<>());
                    return prev != null ? prev : container;
                });
                /*
                     *  if we have no category watcher listener,
                     *  we find out the current listener or create one for the current category, put or get only once.
                     */
                ChildListener childListener = Optional.ofNullable(listeners.get(listener)).orElseGet(() -> {
                    ChildListener watchListener, prev;
                    prev = listeners.putIfAbsent(listener, watchListener = (parentPath, currentChildren) -> EtcdRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChildren)));
                    return prev != null ? prev : watchListener;
                });
                etcdClient.create(path);
                /*
                     * at the first time, we want to pull already category and then watch their direct children,
                     *  eg: /dubbo/interface/providers, /dubbo/interface/consumers and so on.
                     */
                List<String> children = etcdClient.addChildListener(path, childListener);
                if (children != null) {
                    urls.addAll(toUrlsWithEmpty(url, path, children));
                }
            }
            notify(url, listener, urls);
        }
    } catch (Throwable e) {
        throw new RpcException("Failed to subscribe " + url + " to etcd " + getUrl() + ", cause: " + (OptionUtil.isProtocolError(e) ? "etcd3 registry may not be supported yet or etcd3 registry is not available." : e.getMessage()), e);
    }
}
Also used : ChildListener(org.apache.dubbo.remoting.etcd.ChildListener) RpcException(org.apache.dubbo.rpc.RpcException) ArrayList(java.util.ArrayList) URL(org.apache.dubbo.common.URL) NotifyListener(org.apache.dubbo.registry.NotifyListener)

Example 2 with NotifyListener

use of org.apache.dubbo.registry.NotifyListener in project dubbo by alibaba.

the class FailbackRegistryTest method testDoRetry_register.

@Test
public void testDoRetry_register() throws Exception {
    final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
    // All of them are called 4 times. A successful attempt to lose 1. subscribe will not be done
    final CountDownLatch latch = new CountDownLatch(1);
    NotifyListener listner = new NotifyListener() {

        @Override
        public void notify(List<URL> urls) {
            notified.set(Boolean.TRUE);
        }
    };
    registry = new MockRegistry(registryUrl, latch);
    registry.setBad(true);
    registry.subscribe(serviceUrl.setProtocol(CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
    // Failure can not be called to listener.
    assertEquals(false, notified.get());
    assertEquals(1, latch.getCount());
    registry.setBad(false);
    for (int i = 0; i < trytimes; i++) {
        System.out.println("failback registry retry ,times:" + i);
        // System.out.println(latch.getCount());
        if (latch.getCount() == 0)
            break;
        Thread.sleep(sleeptime);
    }
    // Thread.sleep(100000);
    assertEquals(0, latch.getCount());
    // The failedsubcribe corresponding key will be cleared when unsubscribing
    assertEquals(true, notified.get());
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) List(java.util.List) CountDownLatch(java.util.concurrent.CountDownLatch) NotifyListener(org.apache.dubbo.registry.NotifyListener) Test(org.junit.jupiter.api.Test)

Example 3 with NotifyListener

use of org.apache.dubbo.registry.NotifyListener in project dubbo by alibaba.

the class FailbackRegistryTest method testDoRetry.

/**
 * Test method for retry
 *
 * @throws Exception
 */
@Test
public void testDoRetry() throws Exception {
    final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
    // the latest latch just for 3. Because retry method has been removed.
    final CountDownLatch latch = new CountDownLatch(2);
    NotifyListener listner = new NotifyListener() {

        @Override
        public void notify(List<URL> urls) {
            notified.set(Boolean.TRUE);
        }
    };
    registry = new MockRegistry(registryUrl, latch);
    registry.setBad(true);
    registry.register(serviceUrl);
    registry.unregister(serviceUrl);
    registry.subscribe(serviceUrl.setProtocol(CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
    registry.unsubscribe(serviceUrl.setProtocol(CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
    // Failure can not be called to listener.
    assertEquals(false, notified.get());
    assertEquals(2, latch.getCount());
    registry.setBad(false);
    for (int i = 0; i < trytimes; i++) {
        System.out.println("failback registry retry ,times:" + i);
        // System.out.println(latch.getCount());
        if (latch.getCount() == 0)
            break;
        Thread.sleep(sleeptime);
    }
    // Thread.sleep(100000);//for debug
    assertEquals(0, latch.getCount());
    // The failedsubcribe corresponding key will be cleared when unsubscribing
    assertEquals(false, notified.get());
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) List(java.util.List) CountDownLatch(java.util.concurrent.CountDownLatch) NotifyListener(org.apache.dubbo.registry.NotifyListener) Test(org.junit.jupiter.api.Test)

Example 4 with NotifyListener

use of org.apache.dubbo.registry.NotifyListener in project dubbo by alibaba.

the class AbstractRegistryTest method testSubscribeIfListenerNull.

@Test
public void testSubscribeIfListenerNull() throws Exception {
    Assertions.assertThrows(IllegalArgumentException.class, () -> {
        final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
        NotifyListener listener = urls -> notified.set(Boolean.TRUE);
        URL url = new URL("dubbo", "192.168.0.1", 2200);
        abstractRegistry.subscribe(url, null);
        Assertions.fail("listener url == null");
    });
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Matchers(org.hamcrest.Matchers) Set(java.util.Set) NotifyListener(org.apache.dubbo.registry.NotifyListener) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) Test(org.junit.jupiter.api.Test) LinkedHashMap(java.util.LinkedHashMap) Objects(java.util.Objects) URL(org.apache.dubbo.common.URL) AfterEach(org.junit.jupiter.api.AfterEach) List(java.util.List) MatcherAssert(org.hamcrest.MatcherAssert) EMPTY_PROTOCOL(org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL) Map(java.util.Map) Assertions(org.junit.jupiter.api.Assertions) AtomicReference(java.util.concurrent.atomic.AtomicReference) URL(org.apache.dubbo.common.URL) NotifyListener(org.apache.dubbo.registry.NotifyListener) Test(org.junit.jupiter.api.Test)

Example 5 with NotifyListener

use of org.apache.dubbo.registry.NotifyListener in project dubbo by alibaba.

the class AbstractRegistryTest method testNotifyIfNotifyNull.

@Test
public void testNotifyIfNotifyNull() {
    Assertions.assertThrows(IllegalArgumentException.class, () -> {
        final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
        NotifyListener listener1 = urls -> notified.set(Boolean.TRUE);
        URL url1 = new URL("dubbo", "192.168.0.1", 2200, parametersConsumer);
        abstractRegistry.subscribe(url1, listener1);
        NotifyListener listener2 = urls -> notified.set(Boolean.TRUE);
        URL url2 = new URL("dubbo", "192.168.0.2", 2201, parametersConsumer);
        abstractRegistry.subscribe(url2, listener2);
        NotifyListener listener3 = urls -> notified.set(Boolean.TRUE);
        URL url3 = new URL("dubbo", "192.168.0.3", 2202, parametersConsumer);
        abstractRegistry.subscribe(url3, listener3);
        List<URL> urls = new ArrayList<>();
        urls.add(url1);
        urls.add(url2);
        urls.add(url3);
        abstractRegistry.notify(url1, null, urls);
        Assertions.fail("notify listener == null");
    });
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Matchers(org.hamcrest.Matchers) Set(java.util.Set) NotifyListener(org.apache.dubbo.registry.NotifyListener) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) Test(org.junit.jupiter.api.Test) LinkedHashMap(java.util.LinkedHashMap) Objects(java.util.Objects) URL(org.apache.dubbo.common.URL) AfterEach(org.junit.jupiter.api.AfterEach) List(java.util.List) MatcherAssert(org.hamcrest.MatcherAssert) EMPTY_PROTOCOL(org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL) Map(java.util.Map) Assertions(org.junit.jupiter.api.Assertions) ArrayList(java.util.ArrayList) AtomicReference(java.util.concurrent.atomic.AtomicReference) URL(org.apache.dubbo.common.URL) NotifyListener(org.apache.dubbo.registry.NotifyListener) Test(org.junit.jupiter.api.Test)

Aggregations

NotifyListener (org.apache.dubbo.registry.NotifyListener)51 URL (org.apache.dubbo.common.URL)43 Test (org.junit.jupiter.api.Test)29 Set (java.util.Set)28 Map (java.util.Map)21 ArrayList (java.util.ArrayList)19 List (java.util.List)17 AtomicReference (java.util.concurrent.atomic.AtomicReference)16 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)13 ConcurrentMap (java.util.concurrent.ConcurrentMap)11 HashSet (java.util.HashSet)9 CountDownLatch (java.util.concurrent.CountDownLatch)9 EMPTY_PROTOCOL (org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL)9 LinkedHashMap (java.util.LinkedHashMap)8 Objects (java.util.Objects)8 BeforeEach (org.junit.jupiter.api.BeforeEach)8 HashMap (java.util.HashMap)7 MatcherAssert (org.hamcrest.MatcherAssert)7 Matchers (org.hamcrest.Matchers)7 AfterEach (org.junit.jupiter.api.AfterEach)7