Merge branch 'master' into dev-metadata

# Conflicts:
#	dubbo-all/pom.xml
#	dubbo-bootstrap/pom.xml
#	dubbo-bootstrap/src/main/java/org/apache/dubbo/bootstrap/DubboBootstrap.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ProtocolConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfiguration.java
#	dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/initializer/DubboApplicationListenerTest.java
#	dubbo-demo/dubbo-demo-consumer/src/main/java/org/apache/dubbo/demo/consumer/Consumer.java
This commit is contained in:
ken.lj 2018-11-15 11:33:24 +08:00
commit dbca54ca23
152 changed files with 1286 additions and 811 deletions

View File

@ -13,6 +13,8 @@ Apache Dubbo (incubating) is a high-performance, Java based open source RPC fram
We are now collecting dubbo user info in order to help us to improve Dubbo better, pls. kindly help us by providing yours on [issue#1012: Wanted: who's using dubbo](https://github.com/apache/incubator-dubbo/issues/1012), thanks :)
各位 Dubboer开源中国正在举办 [2018 年度最受欢迎中国开源软件评比活动](https://www.oschina.net/project/top_cn_2018),请投 Dubbo 一票。
## Architecture
![Architecture](http://dubbo.apache.org/img/architecture.png)

View File

@ -20,5 +20,11 @@
<module name="NoLineWrap"/>
<module name="OuterTypeFilename"/>
<module name="UnusedImports"/>
<module name="CustomImportOrder">
<property name="specialImportsRegExp" value="org.apache.dubbo.*"/>
<property name="sortImportsInGroupAlphabetically" value="false"/>
<property name="customImportOrderRules" value="SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"/>
</module>
</module>
</module>

View File

@ -5,8 +5,6 @@
<value>
<package name="org.apache.dubbo" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="com.taobao" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="javax" withSubpackages="true" static="false"/>

View File

@ -283,11 +283,6 @@
<artifactId>dubbo-serialization-protostuff</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-compatible</artifactId>

View File

@ -196,7 +196,8 @@ public class AbstractConfigTest {
@Test
public void checkNameHasSymbol() throws Exception {
try {
AbstractConfig.checkNameHasSymbol("hello", ":*,/-0123abcdABCD");
AbstractConfig.checkNameHasSymbol("hello", ":*,/ -0123\tabcdABCD");
AbstractConfig.checkNameHasSymbol("mock", "force:return world");
} catch (Exception e) {
TestCase.fail("the value should be legal.");
}

View File

@ -181,63 +181,72 @@ public class AbstractInterfaceConfigTest {
public void checkStubAndMock1() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setLocal(GreetingLocal1.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test(expected = IllegalStateException.class)
public void checkStubAndMock2() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setLocal(GreetingLocal2.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test
public void checkStubAndMock3() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setLocal(GreetingLocal3.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test(expected = IllegalStateException.class)
public void checkStubAndMock4() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setStub(GreetingLocal1.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test(expected = IllegalStateException.class)
public void checkStubAndMock5() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setStub(GreetingLocal2.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test
public void checkStubAndMock6() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setStub(GreetingLocal3.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test(expected = IllegalStateException.class)
public void checkStubAndMock7() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setMock("return {a, b}");
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test(expected = IllegalStateException.class)
public void checkStubAndMock8() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setMock(GreetingMock1.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test(expected = IllegalStateException.class)
public void checkStubAndMock9() throws Exception {
InterfaceConfig interfaceConfig = new InterfaceConfig();
interfaceConfig.setMock(GreetingMock2.class.getName());
interfaceConfig.checkStubAndMock(Greeting.class);
interfaceConfig.checkStub(Greeting.class);
interfaceConfig.checkMock(Greeting.class);
}
@Test

View File

@ -35,6 +35,13 @@ public class AbstractMethodConfigTest {
assertThat(methodConfig.getTimeout(), equalTo(10));
}
@Test
public void testForks() throws Exception {
MethodConfig methodConfig = new MethodConfig();
methodConfig.setForks(10);
assertThat(methodConfig.getForks(), equalTo(10));
}
@Test
public void testRetries() throws Exception {
MethodConfig methodConfig = new MethodConfig();

View File

@ -194,6 +194,18 @@ public class ServiceConfigTest {
service.setGeneric("illegal");
}
@Test(expected = IllegalArgumentException.class)
public void testMock() throws Exception {
ServiceConfig service = new ServiceConfig();
service.setMock("true");
}
@Test(expected = IllegalArgumentException.class)
public void testMock2() throws Exception {
ServiceConfig service = new ServiceConfig();
service.setMock(true);
}
@Test
public void testUniqueServiceName() throws Exception {
ServiceConfig<Greeting> service = new ServiceConfig<Greeting>();

View File

@ -274,6 +274,23 @@ public class Constants {
public static final String HEARTBEAT_KEY = "heartbeat";
/**
* Every heartbeat duration / HEATBEAT_CHECK_TICK, check if a heartbeat should be sent. Every heartbeat timeout
* duration / HEATBEAT_CHECK_TICK, check if a connection should be closed on server side, and if reconnect on
* client side
*/
public static final int HEARTBEAT_CHECK_TICK = 3;
/**
* the least heartbeat during is 1000 ms.
*/
public static final long LEAST_HEARTBEAT_DURATION = 1000;
/**
* ticks per wheel. Currently only contains two tasks, so 16 locations are enough
*/
public static final int TICKS_PER_WHEEL = 16;
public static final String HEARTBEAT_TIMEOUT_KEY = "heartbeat.timeout";
public static final String CONNECT_TIMEOUT_KEY = "connect.timeout";

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.common.compiler;
import org.apache.dubbo.common.extension.SPI;
/**

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.common.compiler.support;
import org.apache.dubbo.common.compiler.Compiler;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;

View File

@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.common.extension;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface DisableInject {
}

View File

@ -542,6 +542,12 @@ public class ExtensionLoader<T> {
if (method.getName().startsWith("set")
&& method.getParameterTypes().length == 1
&& Modifier.isPublic(method.getModifiers())) {
/**
* Check {@link DisableInject} to see if we need auto injection for this property
*/
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
Class<?> pt = method.getParameterTypes()[0];
if (ReflectUtils.isPrimitives(pt)) {
continue;
@ -873,19 +879,8 @@ public class ExtensionLoader<T> {
String[] value = adaptiveAnnotation.value();
// value is not set, use the value generated from class name as the key
if (value.length == 0) {
char[] charArray = type.getSimpleName().toCharArray();
StringBuilder sb = new StringBuilder(128);
for (int i = 0; i < charArray.length; i++) {
if (Character.isUpperCase(charArray[i])) {
if (i != 0) {
sb.append(".");
}
sb.append(Character.toLowerCase(charArray[i]));
} else {
sb.append(charArray[i]);
}
}
value = new String[]{sb.toString()};
String splitName = StringUtils.camelToSplitName(type.getSimpleName(), ".");
value = new String[]{splitName};
}
boolean hasInvocation = false;

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.common.logger.jcl;
import org.apache.dubbo.common.logger.Logger;
import org.apache.commons.logging.Log;
import java.io.Serializable;

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.common.logger.jcl;
import org.apache.dubbo.common.logger.Level;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerAdapter;
import org.apache.commons.logging.LogFactory;
import java.io.File;

View File

@ -17,11 +17,11 @@
package org.apache.dubbo.common.threadpool.support.eager;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
/**

View File

@ -20,17 +20,17 @@ import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ClassHelper;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Queue;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.util.Locale;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
@ -367,6 +367,11 @@ public class HashedWheelTimer implements Timer {
return worker.unprocessedTimeouts();
}
@Override
public boolean isStop() {
return WORKER_STATE_SHUTDOWN == WORKER_STATE_UPDATER.get(this);
}
@Override
public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) {
if (task == null) {

View File

@ -45,4 +45,11 @@ public interface Timer {
* this method
*/
Set<Timeout> stop();
/**
* the timer is stop
*
* @return true for stop
*/
boolean isStop();
}

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.common.utils;
/**
* Contains some methods to check array.
*/
public final class ArrayUtils {
private ArrayUtils() {
}
/**
* <p>Checks if the array is null or empty. <p/>
*
* @param array th array to check
* @return {@code true} if the array is null or empty.
*/
public static boolean isEmpty(final Object[] array) {
return array == null || array.length == 0;
}
/**
* <p>Checks if the array is not null or empty. <p/>
*
* @param array th array to check
* @return {@code true} if the array is not null or empty.
*/
public static boolean isNotEmpty(final Object[] array) {
return !isEmpty(array);
}
}

View File

@ -174,7 +174,7 @@ public final class StringUtils {
* {@code null} if null String input
*/
public static String removeEnd(final String str, final String remove) {
if (isEmpty(str) || isEmpty(remove)) {
if (isAnyEmpty(str, remove)) {
return str;
}
if (str.endsWith(remove)) {
@ -314,7 +314,7 @@ public final class StringUtils {
* {@code null} if null String input
*/
public static String replace(final String text, final String searchString, final String replacement, int max) {
if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
if (isAnyEmpty(text, searchString) || replacement == null || max == 0) {
return text;
}
int start = 0;
@ -340,10 +340,7 @@ public final class StringUtils {
}
public static boolean isBlank(String str) {
if (str == null || str.length() == 0) {
return true;
}
return false;
return isEmpty(str);
}
/**
@ -353,10 +350,57 @@ public final class StringUtils {
* @return is empty.
*/
public static boolean isEmpty(String str) {
if (str == null || str.length() == 0) {
return true;
return str == null || str.isEmpty();
}
/**
* <p>Checks if the strings contain empty or null elements. <p/>
*
* <pre>
* StringUtils.isNoneEmpty(null) = false
* StringUtils.isNoneEmpty("") = false
* StringUtils.isNoneEmpty(" ") = true
* StringUtils.isNoneEmpty("abc") = true
* StringUtils.isNoneEmpty("abc", "def") = true
* StringUtils.isNoneEmpty("abc", null) = false
* StringUtils.isNoneEmpty("abc", "") = false
* StringUtils.isNoneEmpty("abc", " ") = true
* </pre>
*
* @param ss the strings to check
* @return {@code true} if all strings are not empty or null
*/
public static boolean isNoneEmpty(final String... ss) {
if (ArrayUtils.isEmpty(ss)) {
return false;
}
return false;
for (final String s : ss){
if (isEmpty(s)) {
return false;
}
}
return true;
}
/**
* <p>Checks if the strings contain at least on empty or null element. <p/>
*
* <pre>
* StringUtils.isAnyEmpty(null) = true
* StringUtils.isAnyEmpty("") = true
* StringUtils.isAnyEmpty(" ") = false
* StringUtils.isAnyEmpty("abc") = false
* StringUtils.isAnyEmpty("abc", "def") = false
* StringUtils.isAnyEmpty("abc", null) = true
* StringUtils.isAnyEmpty("abc", "") = true
* StringUtils.isAnyEmpty("abc", " ") = false
* </pre>
*
* @param ss the strings to check
* @return {@code true} if at least one in the strings is empty or null
*/
public static boolean isAnyEmpty(final String... ss) {
return !isNoneEmpty(ss);
}
/**
@ -366,7 +410,7 @@ public final class StringUtils {
* @return is not empty.
*/
public static boolean isNotEmpty(String str) {
return str != null && str.length() > 0;
return !isEmpty(str);
}
/**
@ -391,17 +435,11 @@ public final class StringUtils {
* @return is integer
*/
public static boolean isInteger(String str) {
if (str == null || str.length() == 0) {
return false;
}
return INT_PATTERN.matcher(str).matches();
return isNotEmpty(str) && INT_PATTERN.matcher(str).matches();
}
public static int parseInteger(String str) {
if (!isInteger(str)) {
return 0;
}
return Integer.parseInt(str);
return isInteger(str) ? Integer.parseInt(str) : 0;
}
/**
@ -409,7 +447,7 @@ public final class StringUtils {
* <a href="http://www.exampledepot.com/egs/java.lang/IsJavaId.html">more info.</a>
*/
public static boolean isJavaIdentifier(String s) {
if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) {
if (isEmpty(s) || !Character.isJavaIdentifierStart(s.charAt(0))) {
return false;
}
for (int i = 1; i < s.length(); i++) {
@ -421,10 +459,7 @@ public final class StringUtils {
}
public static boolean isContains(String values, String value) {
if (values == null || values.length() == 0) {
return false;
}
return isContains(Constants.COMMA_SPLIT_PATTERN.split(values), value);
return isNotEmpty(values) && isContains(Constants.COMMA_SPLIT_PATTERN.split(values), value);
}
/**
@ -433,7 +468,7 @@ public final class StringUtils {
* @return contains
*/
public static boolean isContains(String[] values, String value) {
if (value != null && value.length() > 0 && values != null && values.length > 0) {
if (isNotEmpty(value) && ArrayUtils.isNotEmpty(values)) {
for (String v : values) {
if (value.equals(v)) {
return true;
@ -449,7 +484,7 @@ public final class StringUtils {
}
int sz = str.length();
for (int i = 0; i < sz; i++) {
if (Character.isDigit(str.charAt(i)) == false) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
@ -494,14 +529,14 @@ public final class StringUtils {
}
/**
* translat.
* translate.
*
* @param src source string.
* @param from src char table.
* @param to target char table.
* @return String.
*/
public static String translat(String src, String from, String to) {
public static String translate(String src, String from, String to) {
if (isEmpty(src)) {
return src;
}
@ -561,8 +596,8 @@ public final class StringUtils {
* @return String.
*/
public static String join(String[] array) {
if (array.length == 0) {
return "";
if (ArrayUtils.isEmpty(array)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (String s : array) {
@ -579,8 +614,8 @@ public final class StringUtils {
* @return String.
*/
public static String join(String[] array, char split) {
if (array.length == 0) {
return "";
if (ArrayUtils.isEmpty(array)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
@ -600,8 +635,8 @@ public final class StringUtils {
* @return String.
*/
public static String join(String[] array, String split) {
if (array.length == 0) {
return "";
if (ArrayUtils.isEmpty(array)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
@ -614,8 +649,8 @@ public final class StringUtils {
}
public static String join(Collection<String> coll, String split) {
if (coll.isEmpty()) {
return "";
if (CollectionUtils.isEmpty(coll)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
@ -643,7 +678,7 @@ public final class StringUtils {
Map<String, String> map = new HashMap<String, String>(tmp.length);
for (int i = 0; i < tmp.length; i++) {
Matcher matcher = KVP_PATTERN.matcher(tmp[i]);
if (matcher.matches() == false) {
if (!matcher.matches()) {
continue;
}
map.put(matcher.group(1), matcher.group(2));
@ -663,7 +698,7 @@ public final class StringUtils {
* @return Parameters instance.
*/
public static Map<String, String> parseQueryString(String qs) {
if (qs == null || qs.length() == 0) {
if (isEmpty(qs)) {
return new HashMap<String, String>();
}
return parseKeyValuePair(qs, "\\&");
@ -672,12 +707,12 @@ public final class StringUtils {
public static String getServiceKey(Map<String, String> ps) {
StringBuilder buf = new StringBuilder();
String group = ps.get(Constants.GROUP_KEY);
if (group != null && group.length() > 0) {
if (isNotEmpty(group)) {
buf.append(group).append("/");
}
buf.append(ps.get(Constants.INTERFACE_KEY));
String version = ps.get(Constants.VERSION_KEY);
if (version != null && version.length() > 0) {
if (isNotEmpty(group)) {
buf.append(":").append(version);
}
return buf.toString();
@ -689,8 +724,7 @@ public final class StringUtils {
for (Map.Entry<String, String> entry : new TreeMap<String, String>(ps).entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (key != null && key.length() > 0
&& value != null && value.length() > 0) {
if (isNoneEmpty(key, value)) {
if (buf.length() > 0) {
buf.append("&");
}
@ -704,7 +738,7 @@ public final class StringUtils {
}
public static String camelToSplitName(String camelName, String split) {
if (camelName == null || camelName.length() == 0) {
if (isEmpty(camelName)) {
return camelName;
}
StringBuilder buf = null;

View File

@ -47,7 +47,8 @@ import org.apache.dubbo.common.extension.ext8_add.impl.AddExt3_ManualAdaptive;
import org.apache.dubbo.common.extension.ext8_add.impl.AddExt4_ManualAdaptive;
import org.apache.dubbo.common.extension.ext9_empty.Ext9Empty;
import org.apache.dubbo.common.extension.ext9_empty.impl.Ext9EmptyImpl;
import org.apache.dubbo.common.extension.injection.InjectExt;
import org.apache.dubbo.common.extension.injection.impl.InjectExtImpl;
import org.junit.Assert;
import org.junit.Test;
@ -425,4 +426,14 @@ public class ExtensionLoaderTest {
Assert.assertTrue(list.get(1).getClass() == OrderActivateExtImpl1.class);
}
@Test
public void testInjectExtension() {
// test default
InjectExt injectExt = ExtensionLoader.getExtensionLoader(InjectExt.class).getExtension("injection");
InjectExtImpl injectExtImpl = (InjectExtImpl) injectExt;
Assert.assertNotNull(injectExtImpl.getSimpleExt());
Assert.assertNull(injectExtImpl.getSimpleExt1());
Assert.assertNull(injectExtImpl.getGenericType());
}
}

View File

@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.common.extension.injection;
import org.apache.dubbo.common.extension.SPI;
/**
*
*/
@SPI("injection")
public interface InjectExt {
String echo(String msg);
}

View File

@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.common.extension.injection.impl;
import org.apache.dubbo.common.extension.DisableInject;
import org.apache.dubbo.common.extension.ext1.SimpleExt;
import org.apache.dubbo.common.extension.injection.InjectExt;
public class InjectExtImpl implements InjectExt {
private SimpleExt simpleExt;
private SimpleExt simpleExt1;
private Object genericType;
public void setSimpleExt(SimpleExt simpleExt) {
this.simpleExt = simpleExt;
}
@DisableInject
public void setSimpleExt1(SimpleExt simpleExt1) {
this.simpleExt1 = simpleExt1;
}
public void setGenericType(Object genericType) {
this.genericType = genericType;
}
@Override
public String echo(String msg) {
return null;
}
public SimpleExt getSimpleExt() {
return simpleExt;
}
public SimpleExt getSimpleExt1() {
return simpleExt1;
}
public Object getGenericType() {
return genericType;
}
}

View File

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.common.utils;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import org.junit.Test;
public class ArrayUtilsTest {
@Test
public void isEmpty() throws Exception {
assertTrue(ArrayUtils.isEmpty(null));
assertTrue(ArrayUtils.isEmpty(new Object[0]));
assertFalse(ArrayUtils.isEmpty(new Object[]{"abc"}));
}
@Test
public void isNotEmpty() throws Exception {
assertFalse(ArrayUtils.isNotEmpty(null));
assertFalse(ArrayUtils.isNotEmpty(new Object[0]));
assertTrue(ArrayUtils.isNotEmpty(new Object[]{"abc"}));
}
}

View File

@ -111,6 +111,30 @@ public class StringUtilsTest {
assertFalse(StringUtils.isEmpty("abc"));
}
@Test
public void testIsNoneEmpty() throws Exception {
assertFalse(StringUtils.isNoneEmpty(null));
assertFalse(StringUtils.isNoneEmpty(""));
assertTrue(StringUtils.isNoneEmpty(" "));
assertTrue(StringUtils.isNoneEmpty("abc"));
assertTrue(StringUtils.isNoneEmpty("abc", "def"));
assertFalse(StringUtils.isNoneEmpty("abc", null));
assertFalse(StringUtils.isNoneEmpty("abc", ""));
assertTrue(StringUtils.isNoneEmpty("abc", " "));
}
@Test
public void testIsAnyEmpty() throws Exception {
assertTrue(StringUtils.isAnyEmpty(null));
assertTrue(StringUtils.isAnyEmpty(""));
assertFalse(StringUtils.isAnyEmpty(" "));
assertFalse(StringUtils.isAnyEmpty("abc"));
assertFalse(StringUtils.isAnyEmpty("abc", "def"));
assertTrue(StringUtils.isAnyEmpty("abc", null));
assertTrue(StringUtils.isAnyEmpty("abc", ""));
assertFalse(StringUtils.isAnyEmpty("abc", " "));
}
@Test
public void testIsNotEmpty() throws Exception {
assertFalse(StringUtils.isNotEmpty(null));
@ -200,10 +224,10 @@ public class StringUtilsTest {
}
@Test
public void testTranslat() throws Exception {
public void testTranslate() throws Exception {
String s = "16314";
assertEquals(StringUtils.translat(s, "123456", "abcdef"), "afcad");
assertEquals(StringUtils.translat(s, "123456", "abcd"), "acad");
assertEquals(StringUtils.translate(s, "123456", "abcdef"), "afcad");
assertEquals(StringUtils.translate(s, "123456", "abcd"), "acad");
}
@Test

View File

@ -0,0 +1 @@
injection=org.apache.dubbo.common.extension.injection.impl.InjectExtImpl

View File

@ -79,71 +79,88 @@ public class URL extends org.apache.dubbo.common.URL {
return org.apache.dubbo.common.URL.decode(value);
}
@Override
public String getProtocol() {
return super.getProtocol();
}
@Override
public URL setProtocol(String protocol) {
return new URL(protocol, super.getUsername(), super.getPassword(), super.getHost(), super.getPort(), super.getPath(), super.getParameters());
}
@Override
public String getUsername() {
return super.getUsername();
}
@Override
public URL setUsername(String username) {
return new URL(super.getProtocol(), username, super.getPassword(), super.getHost(), super.getPort(), super.getPath(), super.getParameters());
}
@Override
public String getPassword() {
return super.getPassword();
}
@Override
public URL setPassword(String password) {
return new URL(super.getProtocol(), super.getUsername(), password, super.getHost(), super.getPort(), super.getPath(), super.getParameters());
}
@Override
public String getAuthority() {
return super.getAuthority();
}
@Override
public String getHost() {
return super.getHost();
}
@Override
public URL setHost(String host) {
return new URL(super.getProtocol(), super.getUsername(), super.getPassword(), host, super.getPort(), super.getPath(), super.getParameters());
}
@Override
public String getIp() {
return super.getIp();
}
@Override
public int getPort() {
return super.getPort();
}
@Override
public URL setPort(int port) {
return new URL(super.getProtocol(), super.getUsername(), super.getPassword(), super.getHost(), port, super.getPath(), super.getParameters());
}
@Override
public int getPort(int defaultPort) {
return super.getPort();
}
@Override
public String getAddress() {
return super.getAddress();
}
@Override
public URL setAddress(String address) {
org.apache.dubbo.common.URL result = super.setAddress(address);
return new URL(result);
}
@Override
public String getBackupAddress() {
return super.getBackupAddress();
}
@Override
public String getBackupAddress(int defaultPort) {
return super.getBackupAddress(defaultPort);
}
@ -153,191 +170,238 @@ public class URL extends org.apache.dubbo.common.URL {
// return res.stream().map(url -> new URL(url)).collect(Collectors.toList());
// }
@Override
public String getPath() {
return super.getPath();
}
@Override
public URL setPath(String path) {
return new URL(super.getProtocol(), super.getUsername(), super.getPassword(), super.getHost(), super.getPort(), path, super.getParameters());
}
@Override
public String getAbsolutePath() {
return super.getAbsolutePath();
}
@Override
public Map<String, String> getParameters() {
return super.getParameters();
}
@Override
public String getParameterAndDecoded(String key) {
return super.getParameterAndDecoded(key);
}
@Override
public String getParameterAndDecoded(String key, String defaultValue) {
return super.decode(getParameter(key, defaultValue));
return org.apache.dubbo.common.URL.decode(getParameter(key, defaultValue));
}
@Override
public String getParameter(String key) {
return super.getParameter(key);
}
@Override
public String getParameter(String key, String defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public String[] getParameter(String key, String[] defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public URL getUrlParameter(String key) {
org.apache.dubbo.common.URL result = super.getUrlParameter(key);
return new URL(result);
}
@Override
public double getParameter(String key, double defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public float getParameter(String key, float defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public long getParameter(String key, long defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public int getParameter(String key, int defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public short getParameter(String key, short defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public byte getParameter(String key, byte defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public float getPositiveParameter(String key, float defaultValue) {
return super.getPositiveParameter(key, defaultValue);
}
@Override
public double getPositiveParameter(String key, double defaultValue) {
return super.getPositiveParameter(key, defaultValue);
}
@Override
public long getPositiveParameter(String key, long defaultValue) {
return super.getPositiveParameter(key, defaultValue);
}
@Override
public int getPositiveParameter(String key, int defaultValue) {
return super.getPositiveParameter(key, defaultValue);
}
@Override
public short getPositiveParameter(String key, short defaultValue) {
return super.getPositiveParameter(key, defaultValue);
}
@Override
public byte getPositiveParameter(String key, byte defaultValue) {
return super.getPositiveParameter(key, defaultValue);
}
@Override
public char getParameter(String key, char defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public boolean getParameter(String key, boolean defaultValue) {
return super.getParameter(key, defaultValue);
}
@Override
public boolean hasParameter(String key) {
return super.hasParameter(key);
}
@Override
public String getMethodParameterAndDecoded(String method, String key) {
return super.getMethodParameterAndDecoded(method, key);
}
@Override
public String getMethodParameterAndDecoded(String method, String key, String defaultValue) {
return super.getMethodParameterAndDecoded(method, key, defaultValue);
}
@Override
public String getMethodParameter(String method, String key) {
return super.getMethodParameter(method, key);
}
@Override
public String getMethodParameter(String method, String key, String defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public double getMethodParameter(String method, String key, double defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public float getMethodParameter(String method, String key, float defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public long getMethodParameter(String method, String key, long defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public int getMethodParameter(String method, String key, int defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public short getMethodParameter(String method, String key, short defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public byte getMethodParameter(String method, String key, byte defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public double getMethodPositiveParameter(String method, String key, double defaultValue) {
return super.getMethodPositiveParameter(method, key, defaultValue);
}
@Override
public float getMethodPositiveParameter(String method, String key, float defaultValue) {
return super.getMethodPositiveParameter(method, key, defaultValue);
}
@Override
public long getMethodPositiveParameter(String method, String key, long defaultValue) {
return super.getMethodPositiveParameter(method, key, defaultValue);
}
@Override
public int getMethodPositiveParameter(String method, String key, int defaultValue) {
return super.getMethodPositiveParameter(method, key, defaultValue);
}
@Override
public short getMethodPositiveParameter(String method, String key, short defaultValue) {
return super.getMethodPositiveParameter(method, key, defaultValue);
}
@Override
public byte getMethodPositiveParameter(String method, String key, byte defaultValue) {
return super.getMethodPositiveParameter(method, key, defaultValue);
}
@Override
public char getMethodParameter(String method, String key, char defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public boolean getMethodParameter(String method, String key, boolean defaultValue) {
return super.getMethodParameter(method, key, defaultValue);
}
@Override
public boolean hasMethodParameter(String method, String key) {
return super.hasMethodParameter(method, key);
}
@Override
public boolean isLocalHost() {
return super.isLocalHost();
}
@Override
public boolean isAnyHost() {
return super.isAnyHost();
}
@Override
public URL addParameterAndEncoded(String key, String value) {
if (value == null || value.length() == 0) {
return this;
@ -345,38 +409,47 @@ public class URL extends org.apache.dubbo.common.URL {
return addParameter(key, encode(value));
}
@Override
public URL addParameter(String key, boolean value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, char value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, byte value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, short value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, int value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, long value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, float value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, double value) {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, Enum<?> value) {
if (value == null) {
return this;
@ -384,6 +457,7 @@ public class URL extends org.apache.dubbo.common.URL {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, Number value) {
if (value == null) {
return this;
@ -391,6 +465,7 @@ public class URL extends org.apache.dubbo.common.URL {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, CharSequence value) {
if (value == null || value.length() == 0) {
return this;
@ -398,60 +473,72 @@ public class URL extends org.apache.dubbo.common.URL {
return addParameter(key, String.valueOf(value));
}
@Override
public URL addParameter(String key, String value) {
org.apache.dubbo.common.URL result = super.addParameter(key, value);
return new URL(result);
}
@Override
public URL addParameterIfAbsent(String key, String value) {
org.apache.dubbo.common.URL result = super.addParameterIfAbsent(key, value);
return new URL(result);
}
@Override
public URL addParameters(Map<String, String> parameters) {
org.apache.dubbo.common.URL result = super.addParameters(parameters);
return new URL(result);
}
@Override
public URL addParametersIfAbsent(Map<String, String> parameters) {
org.apache.dubbo.common.URL result = super.addParametersIfAbsent(parameters);
return new URL(result);
}
@Override
public URL addParameters(String... pairs) {
org.apache.dubbo.common.URL result = super.addParameters(pairs);
return new URL(result);
}
@Override
public URL addParameterString(String query) {
org.apache.dubbo.common.URL result = super.addParameterString(query);
return new URL(result);
}
@Override
public URL removeParameter(String key) {
org.apache.dubbo.common.URL result = super.removeParameter(key);
return new URL(result);
}
@Override
public URL removeParameters(Collection<String> keys) {
org.apache.dubbo.common.URL result = super.removeParameters(keys);
return new URL(result);
}
@Override
public URL removeParameters(String... keys) {
org.apache.dubbo.common.URL result = super.removeParameters(keys);
return new URL(result);
}
@Override
public URL clearParameters() {
org.apache.dubbo.common.URL result = super.clearParameters();
return new URL(result);
}
@Override
public String getRawParameter(String key) {
return super.getRawParameter(key);
}
@Override
public Map<String, String> toMap() {
return super.toMap();
}
@ -461,58 +548,72 @@ public class URL extends org.apache.dubbo.common.URL {
return super.toString();
}
@Override
public String toString(String... parameters) {
return super.toString(parameters);
}
@Override
public String toIdentityString() {
return super.toIdentityString();
}
@Override
public String toIdentityString(String... parameters) {
return super.toIdentityString(parameters);
}
@Override
public String toFullString() {
return super.toFullString();
}
@Override
public String toFullString(String... parameters) {
return super.toFullString(parameters);
}
@Override
public String toParameterString() {
return super.toParameterString();
}
@Override
public String toParameterString(String... parameters) {
return super.toParameterString(parameters);
}
@Override
public java.net.URL toJavaURL() {
return super.toJavaURL();
}
@Override
public InetSocketAddress toInetSocketAddress() {
return super.toInetSocketAddress();
}
@Override
public String getServiceKey() {
return super.getServiceKey();
}
@Override
public String toServiceStringWithoutResolving() {
return super.toServiceStringWithoutResolving();
}
@Override
public String toServiceString() {
return super.toServiceString();
}
@Override
public String getServiceInterface() {
return super.getServiceInterface();
}
@Override
public URL setServiceInterface(String service) {
org.apache.dubbo.common.URL result = super.setServiceInterface(service);
return new URL(result);

View File

@ -20,5 +20,6 @@ package com.alibaba.dubbo.common.status;
@Deprecated
public interface StatusChecker extends org.apache.dubbo.common.status.StatusChecker {
@Override
Status check();
}

View File

@ -20,6 +20,7 @@ package com.alibaba.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.context.annotation.CompatibleDubboComponentScan;
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.Documented;

View File

@ -25,6 +25,7 @@ import java.util.stream.Collectors;
@Deprecated
public interface Monitor extends org.apache.dubbo.monitor.Monitor {
@Override
com.alibaba.dubbo.common.URL getUrl();
void collect(com.alibaba.dubbo.common.URL statistics);

View File

@ -26,6 +26,7 @@ import java.util.stream.Collectors;
@Deprecated
public interface Registry extends org.apache.dubbo.registry.Registry {
@Override
com.alibaba.dubbo.common.URL getUrl();
void register(com.alibaba.dubbo.common.URL url);

View File

@ -20,7 +20,9 @@ package com.alibaba.dubbo.remoting;
@Deprecated
public interface Channel extends org.apache.dubbo.remoting.Channel {
@Override
com.alibaba.dubbo.common.URL getUrl();
@Override
com.alibaba.dubbo.remoting.ChannelHandler getChannelHandler();
}

View File

@ -20,6 +20,7 @@ package com.alibaba.dubbo.rpc;
@Deprecated
public interface Exporter<T> extends org.apache.dubbo.rpc.Exporter<T> {
@Override
Invoker<T> getInvoker();
class CompatibleExporter<T> implements Exporter<T> {

View File

@ -22,6 +22,7 @@ public interface Filter extends org.apache.dubbo.rpc.Filter {
Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException;
@Override
default org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invoker<?> invoker,
org.apache.dubbo.rpc.Invocation invocation)
throws org.apache.dubbo.rpc.RpcException {

View File

@ -22,6 +22,7 @@ import java.util.Map;
@Deprecated
public interface Invocation extends org.apache.dubbo.rpc.Invocation {
@Override
Invoker<?> getInvoker();
default org.apache.dubbo.rpc.Invocation getOriginal() {
@ -71,6 +72,7 @@ public interface Invocation extends org.apache.dubbo.rpc.Invocation {
return new Invoker.CompatibleInvoker(delegate.getInvoker());
}
@Override
public org.apache.dubbo.rpc.Invocation getOriginal() {
return delegate;
}

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.URL;
@Deprecated
public interface Invoker<T> extends org.apache.dubbo.rpc.Invoker<T> {
@Override
Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws RpcException;
default org.apache.dubbo.rpc.Invoker<T> getOriginal() {
@ -61,6 +62,7 @@ public interface Invoker<T> extends org.apache.dubbo.rpc.Invoker<T> {
invoker.destroy();
}
@Override
public org.apache.dubbo.rpc.Invoker<T> getOriginal() {
return invoker;
}

View File

@ -17,18 +17,19 @@
package com.alibaba.dubbo.rpc.cluster;
import com.alibaba.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import com.alibaba.dubbo.common.URL;
import java.util.List;
import java.util.stream.Collectors;
@Deprecated
public interface Directory<T> extends org.apache.dubbo.rpc.cluster.Directory<T> {
@Override
URL getUrl();
List<com.alibaba.dubbo.rpc.Invoker<T>> list(com.alibaba.dubbo.rpc.Invocation invocation) throws com.alibaba.dubbo.rpc.RpcException;

View File

@ -28,6 +28,7 @@ import java.util.stream.Collectors;
@Deprecated
public interface Router extends org.apache.dubbo.rpc.cluster.Router {
@Override
com.alibaba.dubbo.common.URL getUrl();
<T> List<com.alibaba.dubbo.rpc.Invoker<T>> route(List<com.alibaba.dubbo.rpc.Invoker<T>> invokers,

View File

@ -16,9 +16,9 @@
*/
package org.apache.dubbo.config.spring.beans.factory.annotation;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;

View File

@ -16,12 +16,12 @@
*/
package org.apache.dubbo.config.spring.beans.factory.annotation;
import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.ConsumerConfig;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.convert.converter.StringArrayToMapConverter;
import org.apache.dubbo.config.spring.convert.converter.StringArrayToStringConverter;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;

View File

@ -16,12 +16,12 @@
*/
package org.apache.dubbo.config.spring.beans.factory.annotation;
import com.alibaba.dubbo.config.annotation.Service;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleServiceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.util.BeanRegistrar;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;

View File

@ -17,11 +17,10 @@
package org.apache.dubbo.config.spring.schema;
import org.apache.dubbo.config.spring.AnnotationBean;
import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.CompatibleServiceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.util.BeanRegistrar;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;

View File

@ -60,7 +60,7 @@ public abstract class AbstractConfig implements Serializable {
private static final Pattern PATTERN_PATH = Pattern.compile("[/\\-$._0-9a-zA-Z]+");
private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,/\\-._0-9a-zA-Z]+");
private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
private static final Pattern PATTERN_KEY = Pattern.compile("[*,\\-._0-9a-zA-Z]+");
private static final Map<String, String> legacyProperties = new HashMap<String, String>();
@ -589,7 +589,8 @@ public abstract class AbstractConfig implements Serializable {
try {
String name = method.getName();
if ((name.startsWith("get") || name.startsWith("is"))
&& !"getClass".equals(name) && !"get".equals(name) && !"is".equals(name)
&& !"get".equals(name) && !"is".equals(name)
&& !"getClass".equals(name) && !"getObject".equals(name)
&& Modifier.isPublic(method.getModifiers())
&& method.getParameterTypes().length == 0
&& isPrimitive(method.getReturnType())) {

View File

@ -347,7 +347,36 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
}
}
protected void checkStubAndMock(Class<?> interfaceClass) {
void checkMock(Class<?> interfaceClass) {
if (ConfigUtils.isEmpty(mock)) {
return;
}
String normalizedMock = MockInvoker.normalizeMock(mock);
if (normalizedMock.startsWith(Constants.RETURN_PREFIX)) {
normalizedMock = normalizedMock.substring(Constants.RETURN_PREFIX.length()).trim();
try {
MockInvoker.parseMockValue(normalizedMock);
} catch (Exception e) {
throw new IllegalStateException("Illegal mock return in <dubbo:service/reference ... " +
"mock=\"" + mock + "\" />");
}
} else if (normalizedMock.startsWith(Constants.THROW_PREFIX)) {
normalizedMock = normalizedMock.substring(Constants.THROW_PREFIX.length()).trim();
if (ConfigUtils.isNotEmpty(normalizedMock)) {
try {
MockInvoker.getThrowable(normalizedMock);
} catch (Exception e) {
throw new IllegalStateException("Illegal mock throw in <dubbo:service/reference ... " +
"mock=\"" + mock + "\" />");
}
}
} else {
MockInvoker.getMockObject(normalizedMock, interfaceClass);
}
}
void checkStub(Class<?> interfaceClass) {
if (ConfigUtils.isNotEmpty(local)) {
Class<?> localClass = ConfigUtils.isDefault(local) ? ReflectUtils.forName(interfaceClass.getName() + "Local") : ReflectUtils.forName(local);
if (!interfaceClass.isAssignableFrom(localClass)) {
@ -370,26 +399,6 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
}
}
if (ConfigUtils.isNotEmpty(mock)) {
if (mock.startsWith(Constants.RETURN_PREFIX)) {
String value = mock.substring(Constants.RETURN_PREFIX.length());
try {
MockInvoker.parseMockValue(value);
} catch (Exception e) {
throw new IllegalStateException("Illegal mock json value in <dubbo:service ... mock=\"" + mock + "\" />");
}
} else {
Class<?> mockClass = ConfigUtils.isDefault(mock) ? ReflectUtils.forName(interfaceClass.getName() + "Mock") : ReflectUtils.forName(mock);
if (!interfaceClass.isAssignableFrom(mockClass)) {
throw new IllegalStateException("The mock implementation class " + mockClass.getName() + " not implement interface " + interfaceClass.getName());
}
try {
mockClass.getConstructor(new Class<?>[0]);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("No such empty constructor \"public " + mockClass.getSimpleName() + "()\" in mock implementation class " + mockClass.getName());
}
}
}
}
/**

View File

@ -64,6 +64,19 @@ public abstract class AbstractMethodConfig extends AbstractConfig {
// customized parameters
protected Map<String, String> parameters;
/**
* forks for forking cluster
*/
protected Integer forks;
public Integer getForks() {
return forks;
}
public void setForks(Integer forks) {
this.forks = forks;
}
public Integer getTimeout() {
return timeout;
}
@ -127,8 +140,14 @@ public abstract class AbstractMethodConfig extends AbstractConfig {
}
public void setMock(String mock) {
if (mock != null && mock.startsWith(Constants.RETURN_PREFIX)) {
if (mock == null) {
return;
}
if (mock.startsWith(Constants.RETURN_PREFIX) || mock.startsWith(Constants.THROW_PREFIX + " ")) {
checkLength("mock", mock);
} else if (mock.startsWith(Constants.FAIL_PREFIX) || mock.startsWith(Constants.FORCE_PREFIX)) {
checkNameHasSymbol("mock", mock);
} else {
checkName("mock", mock);
}
@ -168,4 +187,4 @@ public abstract class AbstractMethodConfig extends AbstractConfig {
this.parameters = parameters;
}
}
}

View File

@ -476,4 +476,4 @@ public class ProtocolConfig extends AbstractConfig {
public boolean isValid() {
return StringUtils.isNotEmpty(name);
}
}
}

View File

@ -256,7 +256,8 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
return;
}
initialized = true;
checkStubAndMock(interfaceClass);
checkStub(interfaceClass);
checkMock(interfaceClass);
Map<String, String> map = new HashMap<String, String>();
resolveAsyncInterface(interfaceClass, map);

View File

@ -284,7 +284,8 @@ public class ServiceConfig<T> extends AbstractServiceConfig {
throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
}
}
checkStubAndMock(interfaceClass);
checkStub(interfaceClass);
checkMock(interfaceClass);
}
public synchronized void export() {
@ -850,6 +851,16 @@ public class ServiceConfig<T> extends AbstractServiceConfig {
}
}
@Override
public void setMock(Boolean mock) {
throw new IllegalArgumentException("mock doesn't support on provider side");
}
@Override
public void setMock(String mock) {
throw new IllegalArgumentException("mock doesn't support on provider side");
}
public List<URL> getExportedUrls() {
return urls;
}

View File

@ -34,11 +34,6 @@
<artifactId>dubbo-config-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
@ -157,4 +152,4 @@
-->
</plugins>
</build>
</project>
</project>

View File

@ -28,11 +28,11 @@ import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
@ -111,17 +111,16 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
@Override
public void destroy() {
// This will only be called for singleton scope bean, and expected to be called by spring shutdown hook when BeanFactory/ApplicationContext destroys.
// We will guarantee dubbo related resources being released with dubbo shutdown hook.
// for (ServiceConfig<?> serviceConfig : serviceConfigs) {
// try {
// serviceConfig.unexport();
// } catch (Throwable e) {
// logger.error(e.getMessage(), e);
// }
// }
// no need to destroy here
// see org.apache.dubbo.config.spring.extension.SpringExtensionFactory.ShutdownHookListener
/*
for (ServiceConfig<?> serviceConfig : serviceConfigs) {
try {
serviceConfig.unexport();
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
for (ReferenceConfig<?> referenceConfig : referenceConfigs.values()) {
try {
@ -130,6 +129,7 @@ public class AnnotationBean extends AbstractConfig implements DisposableBean, Be
logger.error(e.getMessage(), e);
}
}
*/
}
@Override

View File

@ -26,6 +26,7 @@ import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.apache.dubbo.config.support.Parameter;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;

View File

@ -26,6 +26,7 @@ import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.BeanNameAware;
@ -35,13 +36,13 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.addApplicationListener;
/**
* ServiceFactoryBean
*
@ -73,23 +74,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
SpringExtensionFactory.addApplicationContext(applicationContext);
try {
Method method = applicationContext.getClass().getMethod("addApplicationListener", ApplicationListener.class); // backward compatibility to spring 2.0.1
method.invoke(applicationContext, this);
supportedApplicationListener = true;
} catch (Throwable t) {
if (applicationContext instanceof AbstractApplicationContext) {
try {
Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", ApplicationListener.class); // backward compatibility to spring 2.0.1
if (!method.isAccessible()) {
method.setAccessible(true);
}
method.invoke(applicationContext, this);
supportedApplicationListener = true;
} catch (Throwable t2) {
}
}
}
supportedApplicationListener = addApplicationListener(applicationContext, this);
}
@Override
@ -252,7 +237,6 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
setPath(beanName);
}
}
if (!supportedApplicationListener) {
export();
}
@ -260,9 +244,8 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
@Override
public void destroy() throws Exception {
// This will only be called for singleton scope bean, and expected to be called by spring shutdown hook when BeanFactory/ApplicationContext destroys.
// We will guarantee dubbo related resources being released with dubbo shutdown hook.
//unexport();
// no need to call unexport() here, see
// org.apache.dubbo.config.spring.extension.SpringExtensionFactory.ShutdownHookListener
}
// merged from dubbox

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.config.spring.context.annotation.DubboConfigBindingRegis
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfigBinding;
import org.apache.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
import org.apache.dubbo.config.spring.context.properties.DubboConfigBinder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;

View File

@ -16,12 +16,13 @@
*/
package org.apache.dubbo.config.spring.beans.factory.annotation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
@ -581,7 +582,9 @@ public class ReferenceAnnotationBeanPostProcessor extends InstantiationAwareBean
}
private String toPlainString(String[] array) {
if (array == null || array.length == 0) return "";
if (array == null || array.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < array.length; i++) {
if (i > 0) {

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.convert.converter.StringArrayToMapConverter;
import org.apache.dubbo.config.spring.convert.converter.StringArrayToStringConverter;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;
@ -261,7 +262,7 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
registry.registerBeanDefinition(beanName, serviceBeanDefinition);
if (logger.isInfoEnabled()) {
if (logger.isWarnEnabled()) {
logger.warn("The BeanDefinition[" + serviceBeanDefinition +
"] of ServiceBean has been registered with name : " + beanName);
}
@ -386,7 +387,7 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", "interface");
String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", "interface", "interfaceName");
propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(service, environment, ignoreAttributeNames));

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Annotation;

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.util.BeanRegistrar;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAttributes;

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.Documented;

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Documented;

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.PropertySources;

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.properties;
import org.apache.dubbo.config.AbstractConfig;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.validation.DataBinder;

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.context.properties;
import org.apache.dubbo.config.AbstractConfig;
import org.springframework.context.EnvironmentAware;
/**

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.config.spring.convert.converter;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.ObjectUtils;

View File

@ -16,15 +16,22 @@
*/
package org.apache.dubbo.config.spring.extension;
import java.util.Set;
import org.apache.dubbo.common.extension.ExtensionFactory;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.config.spring.util.BeanFactoryUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import java.util.Set;
/**
* SpringExtensionFactory
@ -33,9 +40,11 @@ public class SpringExtensionFactory implements ExtensionFactory {
private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class);
private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();
private static final ApplicationListener shutdownHookListener = new ShutdownHookListener();
public static void addApplicationContext(ApplicationContext context) {
contexts.add(context);
BeanFactoryUtils.addApplicationListener(context, shutdownHookListener);
}
public static void removeApplicationContext(ApplicationContext context) {
@ -69,13 +78,17 @@ public class SpringExtensionFactory implements ExtensionFactory {
}
}
logger.warn("No spring extension(bean) named:" + name + ", try to find an extension(bean) of type " + type.getName());
logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());
if (Object.class == type) {
return null;
}
for (ApplicationContext context : contexts) {
try {
return context.getBean(type);
} catch (NoUniqueBeanDefinitionException multiBeanExe) {
throw multiBeanExe;
logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type.");
} catch (NoSuchBeanDefinitionException noBeanExe) {
if (logger.isDebugEnabled()) {
logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
@ -83,9 +96,21 @@ public class SpringExtensionFactory implements ExtensionFactory {
}
}
logger.warn("No spring extension(bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");
logger.warn("No spring extension (bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");
return null;
}
private static class ShutdownHookListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextClosedEvent) {
// we call it anyway since dubbo shutdown hook make sure its destroyAll() is re-entrant.
// pls. note we should not remove dubbo shutdown hook when spring framework is present, this is because
// its shutdown hook may not be installed.
DubboShutdownHook shutdownHook = DubboShutdownHook.getDubboShutdownHook();
shutdownHook.destroyAll();
}
}
}
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
/**
* Automatically register {@link DubboApplicationListener} to Spring context
* A {@link org.springframework.web.context.ContextLoaderListener} class is defined in
* src/main/resources/META-INF/web-fragment.xml
* In the web-fragment.xml, {@link DubboApplicationContextInitializer} is defined in context params.
* This file will be discovered if running under a servlet 3.0+ container.
* Even if user specifies {@link org.springframework.web.context.ContextLoaderListener} in web.xml,
* it will be merged to web.xml.
* If user specifies <metadata-complete="true" /> in web.xml, this will no take effect,
* unless user configures {@link DubboApplicationContextInitializer} explicitly in web.xml.
*/
public class DubboApplicationContextInitializer implements ApplicationContextInitializer {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.addApplicationListener(new DubboApplicationListener());
}
}

View File

@ -1,49 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer;
import org.apache.dubbo.bootstrap.DubboBootstrap;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
/**
* An application listener that listens the ContextClosedEvent.
* Upon the event, this listener will do the necessary clean up to avoid memory leak.
*/
public class DubboApplicationListener implements ApplicationListener<ApplicationEvent> {
private DubboBootstrap dubboBootstrap;
public DubboApplicationListener() {
dubboBootstrap = new DubboBootstrap(false);
}
public DubboApplicationListener(DubboBootstrap dubboBootstrap) {
this.dubboBootstrap = dubboBootstrap;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
if (applicationEvent instanceof ContextRefreshedEvent) {
dubboBootstrap.start();
} else if (applicationEvent instanceof ContextClosedEvent) {
dubboBootstrap.stop();
}
}
}

View File

@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* A Dubbo context listener is a delegation to org.springframework.web.context.ContextLoaderListener. This is necessary,
* because Dubbo is packaged into all-in-one jar, therefore it contains a web-fragment.xml from this sub module which's
* used for helping to assemble spring context listener automatically when it's not configured explicitly by user in
* web.xml. It works fine with spring, but it will lead to ClassNotFound exception and fail tomcat's bootup when user
* doesn't depend on spring framework.
*/
public class DubboContextListener implements ServletContextListener {
private static final Log logger = LogFactory.getLog(DubboContextListener.class);
private static final String SPRING_CONTEXT_LISTENER = "org.springframework.web.context.ContextLoaderListener";
private static final String SPRING_CONTEXT_ROOT = "org.springframework.web.context.WebApplicationContext.ROOT";
private ServletContextListener springContextListener;
private boolean executed = false;
public DubboContextListener() {
try {
Class c = Class.forName(SPRING_CONTEXT_LISTENER);
springContextListener = (ServletContextListener) c.newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
logger.warn("Servlet container detects dubbo's web fragment configuration, and tries to load " +
"org.springframework.web.context.ContextLoaderListener but fails to find the class. " +
"If the application don't rely on Spring framework, pls. simply ignore");
}
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
if (springContextListener != null) {
// if spring context listener has already been registered, then do nothing
ServletContext context = servletContextEvent.getServletContext();
if (context.getAttribute(SPRING_CONTEXT_ROOT) == null) {
executed = true;
springContextListener.contextInitialized(servletContextEvent);
}
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
if (springContextListener != null && executed) {
springContextListener.contextDestroyed(servletContextEvent);
}
}
}

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.config.spring.AnnotationBean;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.util.BeanRegistrar;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.status.Status;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.context.ApplicationContext;
import javax.sql.DataSource;

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.status.Status;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.Lifecycle;

View File

@ -17,10 +17,15 @@
package org.apache.dubbo.config.spring.util;
import org.apache.dubbo.common.utils.StringUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.AbstractApplicationContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -89,4 +94,27 @@ public class BeanFactoryUtils {
}
public static boolean addApplicationListener(ApplicationContext applicationContext, ApplicationListener listener) {
try {
// backward compatibility to spring 2.0.1
Method method = applicationContext.getClass().getMethod("addApplicationListener", ApplicationListener.class);
method.invoke(applicationContext, listener);
return true;
} catch (Throwable t) {
if (applicationContext instanceof AbstractApplicationContext) {
try {
// backward compatibility to spring 2.0.1
Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", ApplicationListener.class);
if (!method.isAccessible()) {
method.setAccessible(true);
}
method.invoke(applicationContext, listener);
return true;
} catch (Throwable t2) {
// ignore
}
}
}
return false;
}
}

View File

@ -101,6 +101,11 @@
<xsd:documentation><![CDATA[ Use cluster strategy. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="forks" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ ForkingCluster forks. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="filter" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The filter. ]]></xsd:documentation>
@ -492,6 +497,11 @@
<xsd:documentation><![CDATA[ The registry cluster type. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="forks" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ ForkingCluster forks. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="group" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The registry group. ]]></xsd:documentation>

View File

@ -101,6 +101,11 @@
<xsd:documentation><![CDATA[ Use cluster strategy. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="forks" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ ForkingCluster forks. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="filter" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The filter. ]]></xsd:documentation>
@ -486,6 +491,11 @@
<xsd:documentation><![CDATA[ The registry cluster type. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="forks" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ ForkingCluster forks. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="group" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The registry group. ]]></xsd:documentation>

View File

@ -1,22 +0,0 @@
<web-fragment version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">
<name>dubbo_fragment</name>
<ordering>
<before>
<others/>
</before>
</ordering>
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>org.apache.dubbo.config.spring.initializer.DubboApplicationContextInitializer</param-value>
</context-param>
<listener>
<listener-class>org.apache.dubbo.config.spring.initializer.DubboContextListener</listener-class>
</listener>
</web-fragment>

View File

@ -33,6 +33,7 @@ import org.apache.dubbo.config.spring.action.DemoActionBySetter;
import org.apache.dubbo.config.spring.annotation.consumer.AnnotationAction;
import org.apache.dubbo.config.spring.api.DemoService;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.provider.ProviderConfiguration;
import org.apache.dubbo.config.spring.filter.MockFilter;
import org.apache.dubbo.config.spring.impl.DemoServiceImpl;
import org.apache.dubbo.config.spring.impl.HelloServiceImpl;
@ -50,6 +51,7 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Collection;
@ -105,6 +107,23 @@ public class ConfigTest {
}
}
@Test
public void testServiceAnnotation() {
AnnotationConfigApplicationContext providerContext = new AnnotationConfigApplicationContext();
providerContext.register(ProviderConfiguration.class);
providerContext.refresh();
ReferenceConfig<HelloService> reference = new ReferenceConfig<HelloService>();
reference.setApplication(new ApplicationConfig("consumer"));
reference.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));
reference.setInterface(HelloService.class);
reference.setUrl("dubbo://127.0.0.1:12345");
String hello = reference.get().sayHello("hello");
assertEquals("Hello, hello", hello);
}
@Test
@SuppressWarnings("unchecked")
public void testProviderNestedService() {
@ -147,6 +166,20 @@ public class ConfigTest {
assertTrue(str.endsWith(" />"));
}
@Test
public void testForks() {
ReferenceConfig<DemoService> reference = new ReferenceConfig<DemoService>();
reference.setApplication(new ApplicationConfig("consumer"));
reference.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));
reference.setInterface(DemoService.class);
reference.setUrl("dubbo://127.0.0.1:20881");
int forks = 10;
reference.setForks(forks);
String str = reference.toString();
assertTrue(str.contains("forks=\"" + forks + "\""));
}
@Test
public void testMultiProtocol() {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(ConfigTest.class.getPackage().getName().replace('.', '/') + "/multi-protocol.xml");

View File

@ -24,7 +24,7 @@ import org.apache.dubbo.config.spring.api.HelloService;
*
* @since 2.5.9
*/
@Service
@Service(interfaceName = "org.apache.dubbo.config.spring.api.HelloService")
public class HelloServiceImpl implements HelloService {
@Override

View File

@ -1,88 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.ContextConfig;
import org.apache.catalina.startup.Tomcat;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.web.context.ContextLoaderListener;
public class DubboApplicationContextInitializerTest {
@Test
public void testSpringContextLoaderListenerInWebXml() throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setBaseDir("target/test-classes");
tomcat.setPort(12345);
StandardContext context = new StandardContext();
context.setName("test");
context.setDocBase("test");
context.setPath("/test");
context.addLifecycleListener(new ContextConfig());
tomcat.getHost().addChild(context);
tomcat.start();
// there should be 2 application listeners, one is spring context listener,
// the other is its wrapper dubbo introduces.
Assert.assertEquals(2, context.getApplicationLifecycleListeners().length);
// the first one should be Spring's built in ContextLoaderListener.
Assert.assertTrue(context.getApplicationLifecycleListeners()[0] instanceof ContextLoaderListener);
tomcat.stop();
tomcat.destroy();
}
@Test
public void testNoListenerInWebXml() throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setBaseDir("target/test-classes");
tomcat.setPort(12345);
StandardContext context = new StandardContext();
context.setName("test2");
context.setDocBase("test2");
context.setPath("/test2");
context.addLifecycleListener(new ContextConfig());
tomcat.getHost().addChild(context);
tomcat.start();
// there should be 1 application listener, which is spring context listener's wrapper introduced by dubbo
Assert.assertEquals(1, context.getApplicationLifecycleListeners().length);
// the first one should be Spring's built in ContextLoaderListener.
Assert.assertTrue(context.getApplicationLifecycleListeners()[0] instanceof DubboContextListener);
tomcat.stop();
tomcat.destroy();
}
@Test
public void testMetadataComplete() throws Exception {
Tomcat tomcat = new Tomcat();
tomcat.setBaseDir("target/test-classes");
tomcat.setPort(12345);
StandardContext context = new StandardContext();
context.setName("test3");
context.setDocBase("test3");
context.setPath("/test3");
context.addLifecycleListener(new ContextConfig());
tomcat.getHost().addChild(context);
tomcat.start();
// there should be no application listeners
Assert.assertEquals(0, context.getApplicationLifecycleListeners().length);
tomcat.stop();
tomcat.destroy();
}
}

View File

@ -1,59 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.config.spring.initializer;
import org.apache.dubbo.bootstrap.DubboBootstrap;
import org.apache.dubbo.bootstrap.DubboShutdownHook;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DubboApplicationListenerTest {
@Test
public void testTwoShutdownHook() {
DubboShutdownHook spyHook = Mockito.spy(DubboShutdownHook.getDubboShutdownHook());
ClassPathXmlApplicationContext applicationContext = getApplicationContext(spyHook, true);
applicationContext.refresh();
applicationContext.close();
// shutdown hook can't be verified, because it will executed after main thread has finished.
// so we can only verify it by manually run it.
try {
spyHook.start();
spyHook.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Mockito.verify(spyHook, Mockito.times(2)).destroyAll();
}
@Test
public void testOneShutdownHook() {
DubboShutdownHook spyHook = Mockito.spy(DubboShutdownHook.getDubboShutdownHook());
ClassPathXmlApplicationContext applicationContext = getApplicationContext(spyHook, false);
applicationContext.refresh();
applicationContext.close();
Mockito.verify(spyHook, Mockito.times(1)).destroyAll();
}
private ClassPathXmlApplicationContext getApplicationContext(DubboShutdownHook hook, boolean registerHook) {
DubboBootstrap bootstrap = new DubboBootstrap(registerHook, hook);
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
applicationContext.addApplicationListener(new DubboApplicationListener(bootstrap));
return applicationContext;
}
}

View File

@ -38,10 +38,5 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-spring</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>
</project>

View File

@ -19,7 +19,6 @@ package org.apache.dubbo.container.spring;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.config.spring.initializer.DubboApplicationListener;
import org.apache.dubbo.container.Container;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@ -44,10 +43,7 @@ public class SpringContainer implements Container {
if (configPath == null || configPath.length() == 0) {
configPath = DEFAULT_SPRING_CONFIG;
}
context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"), false);
context.addApplicationListener(new DubboApplicationListener());
context.registerShutdownHook();
context.refresh();
context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"));
context.start();
}

View File

@ -250,11 +250,6 @@
<artifactId>dubbo-compatible</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>hessian-lite</artifactId>

View File

@ -16,8 +16,6 @@
*/
package org.apache.dubbo.cache.filter;
import java.io.Serializable;
import org.apache.dubbo.cache.Cache;
import org.apache.dubbo.cache.CacheFactory;
import org.apache.dubbo.common.Constants;
@ -31,6 +29,8 @@ import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.RpcResult;
import java.io.Serializable;
/**
* CacheFilter
*/

View File

@ -16,9 +16,9 @@
*/
package org.apache.dubbo.cache.support.expiring;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

View File

@ -38,7 +38,7 @@ public class JCacheFactoryTest extends AbstractCacheFactoryTest {
@Test
public void testJCacheGetExpired() throws Exception {
URL url = URL.valueOf("test://test:11/test?cache=jacache&.cache.write.expire=1");
URL url = URL.valueOf("test://test:12/test?cache=jacache&.cache.write.expire=1");
AbstractCacheFactory cacheFactory = getCacheFactory();
Invocation invocation = new RpcInvocation();
Cache cache = cacheFactory.getCache(url, invocation);

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.metrics;
import java.util.Map;
import java.util.Set;

View File

@ -75,13 +75,10 @@ public class QosProtocolWrapper implements Protocol {
@Override
public void destroy() {
protocol.destroy();
stopServer();
}
private void startQosServer(URL url) {
if (!hasStarted.compareAndSet(false, true)) {
return;
}
try {
boolean qosEnable = url.getParameter(QOS_ENABLE,true);
if (!qosEnable) {
@ -91,6 +88,10 @@ public class QosProtocolWrapper implements Protocol {
return;
}
if (!hasStarted.compareAndSet(false, true)) {
return;
}
int port = url.getParameter(QOS_PORT, QosConstants.DEFAULT_PORT);
boolean acceptForeignIp = Boolean.parseBoolean(url.getParameter(ACCEPT_FOREIGN_IP,"false"));
Server server = Server.getInstance();

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.qos.server;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.qos.server.handler.QosProcessHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.qos.command.CommandExecutor;
import org.apache.dubbo.qos.command.DefaultCommandExecutor;
import org.apache.dubbo.qos.command.NoSuchCommandException;
import org.apache.dubbo.qos.command.decoder.HttpCommandDecoder;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.qos.server.handler;
import org.apache.dubbo.qos.common.QosConstants;
import io.netty.buffer.ByteBuf;

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.qos.server.handler;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.StringUtils;

View File

@ -21,13 +21,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.String.format;
import static org.apache.dubbo.common.utils.StringUtils.EMPTY;
import static org.apache.dubbo.common.utils.StringUtils.length;
import static org.apache.dubbo.common.utils.StringUtils.repeat;
import static org.apache.dubbo.common.utils.StringUtils.replace;
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.String.format;
/**
* Table

View File

@ -21,10 +21,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import static java.lang.System.currentTimeMillis;
import static org.apache.dubbo.common.utils.StringUtils.EMPTY;
import static org.apache.dubbo.common.utils.StringUtils.length;
import static org.apache.dubbo.common.utils.StringUtils.repeat;
import static java.lang.System.currentTimeMillis;
/**
* tree

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -180,6 +181,28 @@ public class FailbackRegistryTest {
assertEquals(2, count.get());
}
@Test
public void testRecover() throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(4);
final AtomicReference<Boolean> notified = new AtomicReference<Boolean>(false);
NotifyListener listener = new NotifyListener() {
@Override
public void notify(List<URL> urls) {
notified.set(Boolean.TRUE);
}
};
MockRegistry mockRegistry = new MockRegistry(registryUrl, countDownLatch);
mockRegistry.register(serviceUrl);
mockRegistry.subscribe(serviceUrl, listener);
Assert.assertEquals(1, mockRegistry.getRegistered().size());
Assert.assertEquals(1, mockRegistry.getSubscribed().size());
mockRegistry.recover();
countDownLatch.await();
Assert.assertEquals(0, mockRegistry.getFailedRegistered().size());
Assert.assertEquals(null, mockRegistry.getFailedSubscribed().get(registryUrl));
Assert.assertEquals(countDownLatch.getCount(), 0);
}
private static class MockRegistry extends FailbackRegistry {
CountDownLatch latch;

Some files were not shown because too many files have changed in this diff Show More