blob: 07b9b5ee18a0f4d0ed17da1bc9b59db1b8d90185 [file] [log] [blame]
/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.registry.support;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Before;
import org.junit.Test;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.registry.NotifyListener;
/**
*
* @author liuchao
*/
public class FailbackRegistryTest {
MockRegistry registry;
static String service;
static URL serviceUrl;
static URL registryUrl;
private int FAILED_PERIOD = 200;
private int sleeptime = 100;
private int trytimes = 5;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
service = "com.alibaba.dubbo.test.DemoService";
serviceUrl = URL.valueOf("remote://127.0.0.1/demoservice?method=get");
registryUrl = URL.valueOf("http://1.2.3.4:9090/registry?check=false&file=N/A").addParameter(Constants.REGISTRY_RETRY_PERIOD_KEY,String.valueOf(FAILED_PERIOD));
}
/**
* Test method for
* {@link com.alibaba.dubbo.registry.internal.FailbackRegistry#doRetry()}.
*
* @throws Exception
*/
@Test
public void testDoRetry() throws Exception {
final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
final CountDownLatch latch = new CountDownLatch(3);//全部共调用3次。成功才会减1. subscribe register的失败尝试不会在做了
NotifyListener listner = new NotifyListener() {
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(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
registry.unsubscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
//失败的情况不能调用到listener.
assertEquals(false, notified.get());
assertEquals(3, 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());
//unsubscribe时会清除failedsubcribe对应key
assertEquals(false, notified.get());
}
@Test
public void testDoRetry_subscribe() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);//全部共调用4次。成功才会减1. subscribe的失败尝试不会在做了
registry = new MockRegistry(registryUrl, latch);
registry.setBad(true);
registry.register(serviceUrl);
registry.setBad(false);
for (int i = 0; i < trytimes; i++) {
System.out.println("failback registry retry ,times:" + i);
if (latch.getCount() == 0)
break;
Thread.sleep(sleeptime);
}
assertEquals(0, latch.getCount());
}
@Test
public void testDoRetry_register() throws Exception {
final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
final CountDownLatch latch = new CountDownLatch(1);//全部共调用4次。成功才会减1. subscribe的失败尝试不会在做了
NotifyListener listner = new NotifyListener() {
public void notify(List<URL> urls) {
notified.set(Boolean.TRUE);
}
};
registry = new MockRegistry(registryUrl, latch);
registry.setBad(true);
registry.subscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
//失败的情况不能调用到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());
//unsubscribe时会清除failedsubcribe对应key
assertEquals(true, notified.get());
}
@Test
public void testDoRetry_nofify() throws Exception {
//初始值0
final AtomicInteger count = new AtomicInteger(0);
NotifyListener listner = new NotifyListener() {
public void notify(List<URL> urls) {
count.incrementAndGet();
//第一次抛出异常,看后面是否会再次调用到incrementAndGet
if(count.get() == 1l ){
throw new RuntimeException("test exception please ignore");
}
}
};
registry = new MockRegistry(registryUrl, new CountDownLatch(0));
registry.subscribe(serviceUrl.setProtocol(Constants.CONSUMER_PROTOCOL).addParameters(CollectionUtils.toStringMap("check", "false")), listner);
assertEquals(1, count.get()); //确保subscribe调用完成后刚调用过一次count.incrementAndGet
//等定时器.
for (int i = 0; i < trytimes; i++) {
System.out.println("failback notify retry ,times:" + i);
if (count.get() == 2)
break;
Thread.sleep(sleeptime);
}
assertEquals(2, count.get());
}
private static class MockRegistry extends FailbackRegistry {
CountDownLatch latch;
/**
* @param url
*/
public MockRegistry(URL url, CountDownLatch latch) {
super(url);
this.latch = latch;
}
private boolean bad = false;
/**
* @param bad the bad to set
*/
public void setBad(boolean bad) {
this.bad = bad;
}
@Override
protected void doRegister(URL url) {
if (bad) {
throw new RuntimeException("can not invoke!");
}
//System.out.println("do doRegister");
latch.countDown();
}
@Override
protected void doUnregister(URL url) {
if (bad) {
throw new RuntimeException("can not invoke!");
}
//System.out.println("do doUnregister");
latch.countDown();
}
@Override
protected void doSubscribe(URL url, NotifyListener listener) {
if (bad) {
throw new RuntimeException("can not invoke!");
}
//System.out.println("do doSubscribe");
super.notify(url, listener, Arrays.asList(new URL[] { serviceUrl }));
latch.countDown();
}
@Override
protected void doUnsubscribe(URL url, NotifyListener listener) {
if (bad) {
throw new RuntimeException("can not invoke!");
}
//System.out.println("do doUnsubscribe");
latch.countDown();
}
@Override
protected void retry() {
super.retry();
if (bad) {
throw new RuntimeException("can not invoke!");
}
//System.out.println("do retry");
latch.countDown();
}
public boolean isAvailable() {
return true;
}
}
}