Merge branch 'performance-tuning-2.7.x'
This commit is contained in:
commit
0872090fa4
|
|
@ -38,16 +38,15 @@ import java.util.Set;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.ADDRESS_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.FORCE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.PRIORITY_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.RUNTIME_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY_PREFIX;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHOD_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
|
||||
/**
|
||||
* ConditionRouter
|
||||
|
|
@ -238,7 +237,7 @@ public class ConditionRouter extends AbstractRouter {
|
|||
} else {
|
||||
sampleValue = sample.get(key);
|
||||
if (sampleValue == null) {
|
||||
sampleValue = sample.get(DEFAULT_KEY_PREFIX + key);
|
||||
sampleValue = sample.get(key);
|
||||
}
|
||||
}
|
||||
if (sampleValue != null) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ public class MockDirInvocation implements Invocation {
|
|||
return "echo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return "DemoService";
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return new Class[]{String.class};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ import java.util.Map;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_AVAILABLE_CHECK_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
|
|
@ -493,21 +493,21 @@ public class AbstractClusterInvokerTest {
|
|||
Directory<DemoService> directory = new StaticDirectory<DemoService>(invokers);
|
||||
FailoverClusterInvoker<DemoService> failoverClusterInvoker = new FailoverClusterInvoker<DemoService>(directory);
|
||||
try {
|
||||
failoverClusterInvoker.invoke(new RpcInvocation("sayHello", new Class<?>[0], new Object[0]));
|
||||
failoverClusterInvoker.invoke(new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[0], new Object[0]));
|
||||
Assertions.fail();
|
||||
} catch (RpcException e) {
|
||||
Assertions.assertEquals(RpcException.TIMEOUT_EXCEPTION, e.getCode());
|
||||
}
|
||||
ForkingClusterInvoker<DemoService> forkingClusterInvoker = new ForkingClusterInvoker<DemoService>(directory);
|
||||
try {
|
||||
forkingClusterInvoker.invoke(new RpcInvocation("sayHello", new Class<?>[0], new Object[0]));
|
||||
forkingClusterInvoker.invoke(new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[0], new Object[0]));
|
||||
Assertions.fail();
|
||||
} catch (RpcException e) {
|
||||
Assertions.assertEquals(RpcException.TIMEOUT_EXCEPTION, e.getCode());
|
||||
}
|
||||
FailfastClusterInvoker<DemoService> failfastClusterInvoker = new FailfastClusterInvoker<DemoService>(directory);
|
||||
try {
|
||||
failfastClusterInvoker.invoke(new RpcInvocation("sayHello", new Class<?>[0], new Object[0]));
|
||||
failfastClusterInvoker.invoke(new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[0], new Object[0]));
|
||||
Assertions.fail();
|
||||
} catch (RpcException e) {
|
||||
Assertions.assertEquals(RpcException.TIMEOUT_EXCEPTION, e.getCode());
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY_PREFIX;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
|
||||
|
|
@ -108,10 +108,14 @@ class URL implements Serializable {
|
|||
|
||||
private final Map<String, String> parameters;
|
||||
|
||||
private final Map<String, Map<String, String>> methodParameters;
|
||||
|
||||
// ==== cache ====
|
||||
|
||||
private volatile transient Map<String, Number> numbers;
|
||||
|
||||
private volatile transient Map<String, Map<String, Number>> methodNumbers;
|
||||
|
||||
private volatile transient Map<String, URL> urls;
|
||||
|
||||
private volatile transient String ip;
|
||||
|
|
@ -124,6 +128,10 @@ class URL implements Serializable {
|
|||
|
||||
private volatile transient String string;
|
||||
|
||||
private final transient String serviceKey;
|
||||
|
||||
private final transient String serviceInterface;
|
||||
|
||||
protected URL() {
|
||||
this.protocol = null;
|
||||
this.username = null;
|
||||
|
|
@ -132,6 +140,9 @@ class URL implements Serializable {
|
|||
this.port = 0;
|
||||
this.path = null;
|
||||
this.parameters = null;
|
||||
this.methodParameters = null;
|
||||
this.serviceKey = null;
|
||||
this.serviceInterface = null;
|
||||
}
|
||||
|
||||
public URL(String protocol, String host, int port) {
|
||||
|
|
@ -166,7 +177,24 @@ class URL implements Serializable {
|
|||
this(protocol, username, password, host, port, path, CollectionUtils.toStringMap(pairs));
|
||||
}
|
||||
|
||||
public URL(String protocol, String username, String password, String host, int port, String path, Map<String, String> parameters) {
|
||||
public URL(String protocol,
|
||||
String username,
|
||||
String password,
|
||||
String host,
|
||||
int port,
|
||||
String path,
|
||||
Map<String, String> parameters) {
|
||||
this (protocol, username, password, host, port, path, parameters, toMethodParameters(parameters));
|
||||
}
|
||||
|
||||
public URL(String protocol,
|
||||
String username,
|
||||
String password,
|
||||
String host,
|
||||
int port,
|
||||
String path,
|
||||
Map<String, String> parameters,
|
||||
Map<String, Map<String, String>> methodParameters) {
|
||||
if (StringUtils.isEmpty(username)
|
||||
&& StringUtils.isNotEmpty(password)) {
|
||||
throw new IllegalArgumentException("Invalid url, password without username!");
|
||||
|
|
@ -187,6 +215,14 @@ class URL implements Serializable {
|
|||
parameters = new HashMap<>(parameters);
|
||||
}
|
||||
this.parameters = Collections.unmodifiableMap(parameters);
|
||||
this.methodParameters = Collections.unmodifiableMap(methodParameters);
|
||||
|
||||
this.serviceInterface = getParameter(INTERFACE_KEY, path);
|
||||
if (this.serviceInterface == null) {
|
||||
this.serviceKey = null;
|
||||
} else {
|
||||
this.serviceKey = buildKey(serviceInterface, getParameter(GROUP_KEY), getParameter(VERSION_KEY));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -273,9 +309,41 @@ class URL implements Serializable {
|
|||
if (url.length() > 0) {
|
||||
host = url;
|
||||
}
|
||||
|
||||
return new URL(protocol, username, password, host, port, path, parameters);
|
||||
}
|
||||
|
||||
public static Map<String, Map<String, String>> toMethodParameters(Map<String, String> parameters) {
|
||||
Map<String, Map<String, String>> methodParameters = new HashMap<>();
|
||||
if (parameters != null) {
|
||||
String methodsString = parameters.get(METHODS_KEY);
|
||||
if (StringUtils.isNotEmpty(methodsString)) {
|
||||
String[] methods = methodsString.split(",");
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
for (String method : methods) {
|
||||
String methodPrefix = method + ".";
|
||||
if (key.startsWith(methodPrefix)) {
|
||||
String realKey = key.substring(methodPrefix.length());
|
||||
URL.putMethodParameter(method, realKey, entry.getValue(), methodParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
int methodSeparator = key.indexOf(".");
|
||||
if (methodSeparator > 0) {
|
||||
String method = key.substring(0, methodSeparator);
|
||||
String realKey = key.substring(methodSeparator + 1);
|
||||
URL.putMethodParameter(method, realKey, entry.getValue(), methodParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return methodParameters;
|
||||
}
|
||||
|
||||
public static URL valueOf(String url, String... reserveParams) {
|
||||
URL result = valueOf(url);
|
||||
if (reserveParams == null || reserveParams.length == 0) {
|
||||
|
|
@ -483,6 +551,10 @@ class URL implements Serializable {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
public Map<String, Map<String, String>> getMethodParameters() {
|
||||
return methodParameters;
|
||||
}
|
||||
|
||||
public String getParameterAndDecoded(String key) {
|
||||
return getParameterAndDecoded(key, null);
|
||||
}
|
||||
|
|
@ -492,8 +564,7 @@ class URL implements Serializable {
|
|||
}
|
||||
|
||||
public String getParameter(String key) {
|
||||
String value = parameters.get(key);
|
||||
return StringUtils.isEmpty(value) ? parameters.get(DEFAULT_KEY_PREFIX + key) : value;
|
||||
return parameters.get(key);
|
||||
}
|
||||
|
||||
public String getParameter(String key, String defaultValue) {
|
||||
|
|
@ -520,6 +591,13 @@ class URL implements Serializable {
|
|||
return numbers == null ? new ConcurrentHashMap<>() : numbers;
|
||||
}
|
||||
|
||||
private Map<String, Map<String, Number>> getMethodNumbers() {
|
||||
if (methodNumbers == null) { // concurrent initialization is tolerant
|
||||
methodNumbers = new ConcurrentHashMap<>();
|
||||
}
|
||||
return methodNumbers;
|
||||
}
|
||||
|
||||
private Map<String, URL> getUrls() {
|
||||
// concurrent initialization is tolerant
|
||||
return urls == null ? new ConcurrentHashMap<>() : urls;
|
||||
|
|
@ -695,8 +773,15 @@ class URL implements Serializable {
|
|||
}
|
||||
|
||||
public String getMethodParameter(String method, String key) {
|
||||
String value = parameters.get(method + "." + key);
|
||||
return StringUtils.isEmpty(value) ? getParameter(key) : value;
|
||||
Map<String, String> keyMap = methodParameters.get(method);
|
||||
String value = null;
|
||||
if (keyMap != null) {
|
||||
value = keyMap.get(key);
|
||||
}
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
value = parameters.get(key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getMethodParameter(String method, String key, String defaultValue) {
|
||||
|
|
@ -705,8 +790,7 @@ class URL implements Serializable {
|
|||
}
|
||||
|
||||
public double getMethodParameter(String method, String key, double defaultValue) {
|
||||
String methodKey = method + "." + key;
|
||||
Number n = getNumbers().get(methodKey);
|
||||
Number n = getCachedNumber(method, key);
|
||||
if (n != null) {
|
||||
return n.doubleValue();
|
||||
}
|
||||
|
|
@ -715,13 +799,12 @@ class URL implements Serializable {
|
|||
return defaultValue;
|
||||
}
|
||||
double d = Double.parseDouble(value);
|
||||
getNumbers().put(methodKey, d);
|
||||
updateCachedNumber(method, key, d);
|
||||
return d;
|
||||
}
|
||||
|
||||
public float getMethodParameter(String method, String key, float defaultValue) {
|
||||
String methodKey = method + "." + key;
|
||||
Number n = getNumbers().get(methodKey);
|
||||
Number n = getCachedNumber(method, key);
|
||||
if (n != null) {
|
||||
return n.floatValue();
|
||||
}
|
||||
|
|
@ -730,13 +813,12 @@ class URL implements Serializable {
|
|||
return defaultValue;
|
||||
}
|
||||
float f = Float.parseFloat(value);
|
||||
getNumbers().put(methodKey, f);
|
||||
updateCachedNumber(method, key, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
public long getMethodParameter(String method, String key, long defaultValue) {
|
||||
String methodKey = method + "." + key;
|
||||
Number n = getNumbers().get(methodKey);
|
||||
Number n = getCachedNumber(method, key);
|
||||
if (n != null) {
|
||||
return n.longValue();
|
||||
}
|
||||
|
|
@ -745,13 +827,12 @@ class URL implements Serializable {
|
|||
return defaultValue;
|
||||
}
|
||||
long l = Long.parseLong(value);
|
||||
getNumbers().put(methodKey, l);
|
||||
updateCachedNumber(method, key, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
public int getMethodParameter(String method, String key, int defaultValue) {
|
||||
String methodKey = method + "." + key;
|
||||
Number n = getNumbers().get(methodKey);
|
||||
Number n = getCachedNumber(method, key);
|
||||
if (n != null) {
|
||||
return n.intValue();
|
||||
}
|
||||
|
|
@ -760,13 +841,12 @@ class URL implements Serializable {
|
|||
return defaultValue;
|
||||
}
|
||||
int i = Integer.parseInt(value);
|
||||
getNumbers().put(methodKey, i);
|
||||
updateCachedNumber(method, key, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
public short getMethodParameter(String method, String key, short defaultValue) {
|
||||
String methodKey = method + "." + key;
|
||||
Number n = getNumbers().get(methodKey);
|
||||
Number n = getCachedNumber(method, key);
|
||||
if (n != null) {
|
||||
return n.shortValue();
|
||||
}
|
||||
|
|
@ -775,13 +855,12 @@ class URL implements Serializable {
|
|||
return defaultValue;
|
||||
}
|
||||
short s = Short.parseShort(value);
|
||||
getNumbers().put(methodKey, s);
|
||||
updateCachedNumber(method, key, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public byte getMethodParameter(String method, String key, byte defaultValue) {
|
||||
String methodKey = method + "." + key;
|
||||
Number n = getNumbers().get(methodKey);
|
||||
Number n = getCachedNumber(method, key);
|
||||
if (n != null) {
|
||||
return n.byteValue();
|
||||
}
|
||||
|
|
@ -790,10 +869,23 @@ class URL implements Serializable {
|
|||
return defaultValue;
|
||||
}
|
||||
byte b = Byte.parseByte(value);
|
||||
getNumbers().put(methodKey, b);
|
||||
updateCachedNumber(method, key, b);
|
||||
return b;
|
||||
}
|
||||
|
||||
private Number getCachedNumber(String method, String key) {
|
||||
Map<String, Number> keyNumber = getMethodNumbers().get(method);
|
||||
if (keyNumber != null) {
|
||||
return keyNumber.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateCachedNumber(String method, String key, Number n) {
|
||||
Map<String, Number> keyNumber = getMethodNumbers().computeIfAbsent(method, m -> new HashMap<>());
|
||||
keyNumber.put(key, n);
|
||||
}
|
||||
|
||||
public double getMethodPositiveParameter(String method, String key, double defaultValue) {
|
||||
if (defaultValue <= 0) {
|
||||
throw new IllegalArgumentException("defaultValue <= 0");
|
||||
|
|
@ -875,6 +967,13 @@ class URL implements Serializable {
|
|||
return value != null && value.length() > 0;
|
||||
}
|
||||
|
||||
public boolean hasMethodParameter(String method) {
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
return getMethodParameters().containsKey(method);
|
||||
}
|
||||
|
||||
public boolean isLocalHost() {
|
||||
return NetUtils.isLocalHost(host) || getParameter(LOCALHOST_KEY, false);
|
||||
}
|
||||
|
|
@ -955,6 +1054,7 @@ class URL implements Serializable {
|
|||
|
||||
Map<String, String> map = new HashMap<>(getParameters());
|
||||
map.put(key, value);
|
||||
|
||||
return new URL(protocol, username, password, host, port, path, map);
|
||||
}
|
||||
|
||||
|
|
@ -968,9 +1068,43 @@ class URL implements Serializable {
|
|||
}
|
||||
Map<String, String> map = new HashMap<>(getParameters());
|
||||
map.put(key, value);
|
||||
|
||||
return new URL(protocol, username, password, host, port, path, map);
|
||||
}
|
||||
|
||||
public URL addMethodParameter(String method, String key, String value) {
|
||||
if (StringUtils.isEmpty(method)
|
||||
|| StringUtils.isEmpty(key)
|
||||
|| StringUtils.isEmpty(value)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Map<String, String> map = new HashMap<>(getParameters());
|
||||
map.put(method + "." + key, value);
|
||||
Map<String, Map<String, String>> methodMap = toMethodParameters(map);
|
||||
URL.putMethodParameter(method, key, value, methodMap);
|
||||
|
||||
return new URL(protocol, username, password, host, port, path, map, methodMap);
|
||||
}
|
||||
|
||||
public URL addMethodParameterIfAbsent(String method, String key, String value) {
|
||||
if (StringUtils.isEmpty(method)
|
||||
|| StringUtils.isEmpty(key)
|
||||
|| StringUtils.isEmpty(value)) {
|
||||
return this;
|
||||
}
|
||||
if (hasMethodParameter(method, key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Map<String, String> map = new HashMap<>(getParameters());
|
||||
map.put(method + "." + key, value);
|
||||
Map<String, Map<String, String>> methodMap = toMethodParameters(map);
|
||||
URL.putMethodParameter(method, key, value, methodMap);
|
||||
|
||||
return new URL(protocol, username, password, host, port, path, map, methodMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add parameters to a new url.
|
||||
*
|
||||
|
|
@ -1274,11 +1408,7 @@ class URL implements Serializable {
|
|||
* @return
|
||||
*/
|
||||
public String getServiceKey() {
|
||||
String inf = getServiceInterface();
|
||||
if (inf == null) {
|
||||
return null;
|
||||
}
|
||||
return buildKey(inf, getParameter(GROUP_KEY), getParameter(VERSION_KEY));
|
||||
return serviceKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1496,4 +1626,9 @@ class URL implements Serializable {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static void putMethodParameter(String method, String key, String value, Map<String, Map<String, String>> methodParameters) {
|
||||
Map<String, String> subParameter = methodParameters.computeIfAbsent(method, k -> new HashMap<>());
|
||||
subParameter.put(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY_PREFIX;
|
||||
|
||||
public final class URLBuilder {
|
||||
private String protocol;
|
||||
|
||||
|
|
@ -43,6 +41,8 @@ public final class URLBuilder {
|
|||
|
||||
private Map<String, String> parameters;
|
||||
|
||||
private Map<String, Map<String, String>> methodParameters;
|
||||
|
||||
public URLBuilder() {
|
||||
protocol = null;
|
||||
username = null;
|
||||
|
|
@ -51,6 +51,7 @@ public final class URLBuilder {
|
|||
port = 0;
|
||||
path = null;
|
||||
parameters = new HashMap<>();
|
||||
methodParameters = new HashMap<>();
|
||||
}
|
||||
|
||||
public URLBuilder(String protocol, String host, int port) {
|
||||
|
|
@ -77,7 +78,22 @@ public final class URLBuilder {
|
|||
this(protocol, null, null, host, port, path, parameters);
|
||||
}
|
||||
|
||||
public URLBuilder(String protocol, String username, String password, String host, int port, String path, Map<String, String> parameters) {
|
||||
public URLBuilder(String protocol,
|
||||
String username,
|
||||
String password,
|
||||
String host,
|
||||
int port,
|
||||
String path, Map<String, String> parameters) {
|
||||
this(protocol, username, password, host, port, path, parameters, URL.toMethodParameters(parameters));
|
||||
}
|
||||
|
||||
public URLBuilder(String protocol,
|
||||
String username,
|
||||
String password,
|
||||
String host,
|
||||
int port,
|
||||
String path, Map<String, String> parameters,
|
||||
Map<String, Map<String, String>> methodParameters) {
|
||||
this.protocol = protocol;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
|
|
@ -85,6 +101,7 @@ public final class URLBuilder {
|
|||
this.port = port;
|
||||
this.path = path;
|
||||
this.parameters = parameters != null ? parameters : new HashMap<>();
|
||||
this.methodParameters = (methodParameters != null ? methodParameters : new HashMap<>());
|
||||
}
|
||||
|
||||
public static URLBuilder from(URL url) {
|
||||
|
|
@ -95,6 +112,7 @@ public final class URLBuilder {
|
|||
int port = url.getPort();
|
||||
String path = url.getPath();
|
||||
Map<String, String> parameters = new HashMap<>(url.getParameters());
|
||||
Map<String, Map<String, String>> methodParameters = new HashMap<>(url.getMethodParameters());
|
||||
return new URLBuilder(
|
||||
protocol,
|
||||
username,
|
||||
|
|
@ -102,7 +120,8 @@ public final class URLBuilder {
|
|||
host,
|
||||
port,
|
||||
path,
|
||||
parameters);
|
||||
parameters,
|
||||
methodParameters);
|
||||
}
|
||||
|
||||
public URL build() {
|
||||
|
|
@ -122,7 +141,7 @@ public final class URLBuilder {
|
|||
path = path.substring(firstNonSlash);
|
||||
}
|
||||
}
|
||||
return new URL(protocol, username, password, host, port, path, parameters);
|
||||
return new URL(protocol, username, password, host, port, path, parameters, methodParameters);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -235,15 +254,19 @@ public final class URLBuilder {
|
|||
if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
|
||||
return this;
|
||||
}
|
||||
// if value doesn't change, return immediately
|
||||
if (value.equals(parameters.get(key))) { // value != null
|
||||
return this;
|
||||
}
|
||||
|
||||
parameters.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public URLBuilder addMethodParameter(String method, String key, String value) {
|
||||
if (StringUtils.isEmpty(method) || StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
|
||||
return this;
|
||||
}
|
||||
URL.putMethodParameter(method, key, value, methodParameters);
|
||||
return this;
|
||||
}
|
||||
|
||||
public URLBuilder addParameterIfAbsent(String key, String value) {
|
||||
if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
|
||||
return this;
|
||||
|
|
@ -255,6 +278,17 @@ public final class URLBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public URLBuilder addMethodParameterIfAbsent(String method, String key, String value) {
|
||||
if (StringUtils.isEmpty(method) || StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
|
||||
return this;
|
||||
}
|
||||
if (hasMethodParameter(method, key)) {
|
||||
return this;
|
||||
}
|
||||
URL.putMethodParameter(method, key, value, methodParameters);
|
||||
return this;
|
||||
}
|
||||
|
||||
public URLBuilder addParameters(Map<String, String> parameters) {
|
||||
if (CollectionUtils.isEmptyMap(parameters)) {
|
||||
return this;
|
||||
|
|
@ -278,6 +312,15 @@ public final class URLBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public URLBuilder addMethodParameters(Map<String, Map<String, String>> methodParameters) {
|
||||
if (CollectionUtils.isEmptyMap(methodParameters)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.methodParameters.putAll(methodParameters);
|
||||
return this;
|
||||
}
|
||||
|
||||
public URLBuilder addParametersIfAbsent(Map<String, String> parameters) {
|
||||
if (CollectionUtils.isEmptyMap(parameters)) {
|
||||
return this;
|
||||
|
|
@ -342,10 +385,38 @@ public final class URLBuilder {
|
|||
return value != null && value.length() > 0;
|
||||
}
|
||||
|
||||
public boolean hasMethodParameter(String method, String key) {
|
||||
if (method == null) {
|
||||
String suffix = "." + key;
|
||||
for (String fullKey : parameters.keySet()) {
|
||||
if (fullKey.endsWith(suffix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (key == null) {
|
||||
String prefix = method + ".";
|
||||
for (String fullKey : parameters.keySet()) {
|
||||
if (fullKey.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
String value = getMethodParameter(method, key);
|
||||
return value != null && value.length() > 0;
|
||||
}
|
||||
|
||||
public String getParameter(String key) {
|
||||
String value = parameters.get(key);
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
value = parameters.get(DEFAULT_KEY_PREFIX + key);
|
||||
return parameters.get(key);
|
||||
}
|
||||
|
||||
public String getMethodParameter(String method, String key) {
|
||||
Map<String, String> keyMap = methodParameters.get(method);
|
||||
String value = null;
|
||||
if (keyMap != null) {
|
||||
value = keyMap.get(key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ public interface CommonConstants {
|
|||
|
||||
int DEFAULT_THREADS = 200;
|
||||
|
||||
String EXECUTOR_SERVICE_COMPONENT_KEY = ExecutorService.class.getName();
|
||||
|
||||
String THREADPOOL_KEY = "threadpool";
|
||||
|
||||
String THREAD_NAME_KEY = "threadname";
|
||||
|
|
@ -171,6 +173,12 @@ public interface CommonConstants {
|
|||
*/
|
||||
String PROXY_CLASS_REF = "refClass";
|
||||
|
||||
/**
|
||||
* generic call
|
||||
*/
|
||||
String $INVOKE = "$invoke";
|
||||
String $INVOKE_ASYNC = "$invokeAsync";
|
||||
|
||||
/**
|
||||
* package version in the manifest
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
|
||||
|
||||
/**
|
||||
* Consider implementing {@link Licycle} to enable executors shutdown when the process stops.
|
||||
* Consider implementing {@code Licycle} to enable executors shutdown when the process stops.
|
||||
*/
|
||||
public class DefaultExecutorRepository implements ExecutorRepository {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultExecutorRepository.class);
|
||||
|
|
@ -50,15 +50,15 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
|
||||
private ScheduledExecutorService reconnectScheduledExecutor;
|
||||
|
||||
private ConcurrentMap<String, ConcurrentMap<String, ExecutorService>> data = new ConcurrentHashMap<>();
|
||||
private ConcurrentMap<String, ConcurrentMap<Integer, ExecutorService>> data = new ConcurrentHashMap<>();
|
||||
|
||||
public DefaultExecutorRepository() {
|
||||
for (int i = 0; i < DEFAULT_SCHEDULER_SIZE; i++) {
|
||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Dubbo-framework-scheduler"));
|
||||
scheduledExecutors.addItem(scheduler);
|
||||
}
|
||||
|
||||
reconnectScheduledExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Dubbo-reconnect-scheduler"));
|
||||
// for (int i = 0; i < DEFAULT_SCHEDULER_SIZE; i++) {
|
||||
// ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Dubbo-framework-scheduler"));
|
||||
// scheduledExecutors.addItem(scheduler);
|
||||
// }
|
||||
//
|
||||
// reconnectScheduledExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Dubbo-reconnect-scheduler"));
|
||||
}
|
||||
|
||||
public ExecutorService createExecutorIfAbsent(URL url) {
|
||||
|
|
@ -66,8 +66,20 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
if (CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(SIDE_KEY))) {
|
||||
componentKey = CONSUMER_SIDE;
|
||||
}
|
||||
Map<String, ExecutorService> executors = data.computeIfAbsent(componentKey, k -> new ConcurrentHashMap<>());
|
||||
return executors.computeIfAbsent(Integer.toString(url.getPort()), k -> (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url));
|
||||
Map<Integer, ExecutorService> executors = data.computeIfAbsent(componentKey, k -> new ConcurrentHashMap<>());
|
||||
return executors.computeIfAbsent(url.getPort(), k -> (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url));
|
||||
}
|
||||
|
||||
public ExecutorService getExecutor(URL url) {
|
||||
String componentKey = EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
if (CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(SIDE_KEY))) {
|
||||
componentKey = CONSUMER_SIDE;
|
||||
}
|
||||
Map<Integer, ExecutorService> executors = data.get(componentKey);
|
||||
if (executors == null) {
|
||||
return null;
|
||||
}
|
||||
return executors.get(url.getPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public interface ExecutorRepository {
|
|||
*/
|
||||
ExecutorService createExecutorIfAbsent(URL url);
|
||||
|
||||
ExecutorService getExecutor(URL url);
|
||||
|
||||
/**
|
||||
* Modify some of the threadpool's properties according to the url, for example, coreSize, maxSize, ...
|
||||
*
|
||||
|
|
|
|||
|
|
@ -180,6 +180,17 @@ public class NetUtils {
|
|||
return address;
|
||||
}
|
||||
|
||||
private static volatile String HOST_ADDRESS;
|
||||
|
||||
public static String getHostAddress () {
|
||||
if (HOST_ADDRESS != null) {
|
||||
return HOST_ADDRESS;
|
||||
}
|
||||
|
||||
HOST_ADDRESS = getLocalHost();
|
||||
return HOST_ADDRESS;
|
||||
}
|
||||
|
||||
public static String getLocalHost() {
|
||||
InetAddress address = getLocalAddress();
|
||||
return address == null ? LOCALHOST_VALUE : address.getHostAddress();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package org.apache.dubbo.common.beanutil;
|
||||
|
||||
import org.apache.dubbo.common.model.person.FullAddress;
|
||||
import org.apache.dubbo.common.model.person.PersonStatus;
|
||||
import org.apache.dubbo.common.model.person.Phone;
|
||||
import org.apache.dubbo.rpc.model.person.FullAddress;
|
||||
import org.apache.dubbo.rpc.model.person.PersonStatus;
|
||||
import org.apache.dubbo.rpc.model.person.Phone;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.beanutil;
|
||||
|
||||
import org.apache.dubbo.common.model.person.BigPerson;
|
||||
import org.apache.dubbo.common.model.person.FullAddress;
|
||||
import org.apache.dubbo.common.model.person.PersonInfo;
|
||||
import org.apache.dubbo.common.model.person.PersonStatus;
|
||||
import org.apache.dubbo.common.model.person.Phone;
|
||||
import org.apache.dubbo.common.utils.PojoUtilsTest;
|
||||
import org.apache.dubbo.rpc.model.person.BigPerson;
|
||||
import org.apache.dubbo.rpc.model.person.FullAddress;
|
||||
import org.apache.dubbo.rpc.model.person.PersonInfo;
|
||||
import org.apache.dubbo.rpc.model.person.PersonStatus;
|
||||
import org.apache.dubbo.rpc.model.person.Phone;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
|
|||
|
|
@ -16,14 +16,15 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.model.Person;
|
||||
import org.apache.dubbo.common.model.SerializablePerson;
|
||||
import org.apache.dubbo.common.model.User;
|
||||
import org.apache.dubbo.common.model.person.BigPerson;
|
||||
import org.apache.dubbo.common.model.person.FullAddress;
|
||||
import org.apache.dubbo.common.model.person.PersonInfo;
|
||||
import org.apache.dubbo.common.model.person.PersonStatus;
|
||||
import org.apache.dubbo.common.model.person.Phone;
|
||||
import org.apache.dubbo.rpc.model.Person;
|
||||
import org.apache.dubbo.rpc.model.SerializablePerson;
|
||||
import org.apache.dubbo.rpc.model.User;
|
||||
import org.apache.dubbo.rpc.model.person.BigPerson;
|
||||
import org.apache.dubbo.rpc.model.person.FullAddress;
|
||||
import org.apache.dubbo.rpc.model.person.PersonInfo;
|
||||
import org.apache.dubbo.rpc.model.person.PersonStatus;
|
||||
import org.apache.dubbo.rpc.model.person.Phone;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -41,13 +42,13 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class PojoUtilsTest {
|
||||
|
|
@ -696,7 +697,7 @@ public class PojoUtilsTest {
|
|||
assertTrue(personInfo.isMale());
|
||||
assertFalse(personInfo.isFemale());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRealizeCollectionWithNullElement() {
|
||||
LinkedList<String> listStr = new LinkedList<>();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model;
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model;
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.common.model;
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.media;
|
||||
package org.apache.dubbo.rpc.model.media;
|
||||
|
||||
|
||||
public class Image implements java.io.Serializable {
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.media;
|
||||
package org.apache.dubbo.rpc.model.media;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.person;
|
||||
package org.apache.dubbo.rpc.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.person;
|
||||
package org.apache.dubbo.rpc.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.person;
|
||||
package org.apache.dubbo.rpc.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
/*
|
||||
* 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.model.person;
|
||||
|
||||
public enum PersonStatus {
|
||||
ENABLED,
|
||||
DISABLED
|
||||
/*
|
||||
* 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.rpc.model.person;
|
||||
|
||||
public enum PersonStatus {
|
||||
ENABLED,
|
||||
DISABLED
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.model.person;
|
||||
package org.apache.dubbo.rpc.model.person;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
|
@ -38,6 +38,11 @@ public interface Invocation extends org.apache.dubbo.rpc.Invocation {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
default String getServiceName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
class CompatibleInvocation implements Invocation {
|
||||
|
||||
private org.apache.dubbo.rpc.Invocation delegate;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,14 @@
|
|||
|
||||
package com.alibaba.dubbo.rpc;
|
||||
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Deprecated
|
||||
public interface Result extends org.apache.dubbo.rpc.Result {
|
||||
|
|
@ -36,7 +42,27 @@ public interface Result extends org.apache.dubbo.rpc.Result {
|
|||
abstract class AbstractResult extends org.apache.dubbo.rpc.AbstractResult implements Result {
|
||||
|
||||
@Override
|
||||
public org.apache.dubbo.rpc.Result whenCompleteWithContext(BiConsumer<org.apache.dubbo.rpc.Result, Throwable> fn) {
|
||||
public void setValue(Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.dubbo.rpc.Result thenApplyWithContext(Function<AppResponse, AppResponse> fn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> CompletableFuture<U> thenApply(Function<org.apache.dubbo.rpc.Result, ? extends U> fn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.dubbo.rpc.Result get() throws InterruptedException, ExecutionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.dubbo.rpc.Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -83,32 +109,32 @@ public interface Result extends org.apache.dubbo.rpc.Result {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttachments() {
|
||||
public Map<String, String> getAttachments() {
|
||||
return delegate.getAttachments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAttachments(Map<String, Object> map) {
|
||||
public void addAttachments(Map<String, String> map) {
|
||||
delegate.addAttachments(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachments(Map<String, Object> map) {
|
||||
public void setAttachments(Map<String, String> map) {
|
||||
delegate.setAttachments(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttachment(String key) {
|
||||
public String getAttachment(String key) {
|
||||
return delegate.getAttachment(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttachment(String key, Object defaultValue) {
|
||||
public String getAttachment(String key, String defaultValue) {
|
||||
return delegate.getAttachment(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachment(String key, Object value) {
|
||||
public void setAttachment(String key, String value) {
|
||||
delegate.setAttachment(key, value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ConsumerMethodModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerModel;
|
||||
import org.apache.dubbo.service.Person;
|
||||
|
||||
import com.alibaba.dubbo.config.ArgumentConfig;
|
||||
|
|
@ -43,7 +43,6 @@ import static org.hamcrest.Matchers.hasKey;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class MethodConfigTest {
|
||||
@Test
|
||||
|
|
@ -113,7 +112,7 @@ public class MethodConfigTest {
|
|||
methodConfig.setOninvokeMethod("setName");
|
||||
methodConfig.setOninvoke(new Person());
|
||||
|
||||
ConsumerMethodModel.AsyncMethodInfo methodInfo = org.apache.dubbo.config.MethodConfig.convertMethodConfig2AsyncInfo(methodConfig);
|
||||
ConsumerModel.AsyncMethodInfo methodInfo = org.apache.dubbo.config.MethodConfig.convertMethodConfig2AyncInfo(methodConfig);
|
||||
|
||||
assertEquals(methodInfo.getOninvokeMethod(), Person.class.getMethod("setName", String.class));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,11 @@ public class MockInvocation implements Invocation {
|
|||
return "echo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return "DemoService";
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return new Class[]{String.class};
|
||||
}
|
||||
|
|
@ -100,4 +105,4 @@ public class MockInvocation implements Invocation {
|
|||
return getAttachments().get(key);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,11 +179,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
str = URL.encode(str);
|
||||
}
|
||||
if (parameter != null && parameter.append()) {
|
||||
String pre = parameters.get(DEFAULT_KEY + "." + key);
|
||||
if (pre != null && pre.length() > 0) {
|
||||
str = pre + "," + str;
|
||||
}
|
||||
pre = parameters.get(key);
|
||||
String pre = parameters.get(key);
|
||||
if (pre != null && pre.length() > 0) {
|
||||
str = pre + "," + str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ import org.apache.dubbo.rpc.support.ProtocolUtils;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -327,7 +326,7 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
|
|||
appendParameters(map, this);
|
||||
Map<String, Object> attributes = null;
|
||||
if (CollectionUtils.isNotEmpty(methods)) {
|
||||
attributes = new HashMap<String, Object>();
|
||||
attributes = new HashMap<>();
|
||||
for (MethodConfig methodConfig : methods) {
|
||||
appendParameters(map, methodConfig, methodConfig.getName());
|
||||
String retryKey = methodConfig.getName() + ".retry";
|
||||
|
|
@ -383,6 +382,7 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
|
|||
}
|
||||
}
|
||||
return new ConsumerModel(attributes, metadata);
|
||||
return new ConsumerModel(serviceKey, interfaceClass, ref, ApplicationModel.registerServiceModel(interfaceClass), attributes);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
|
||||
|
|
|
|||
|
|
@ -476,6 +476,7 @@ public class ServiceConfig<T> extends AbstractServiceConfig {
|
|||
String pathKey = URL.buildKey(getContextPath(protocolConfig).map(p -> p + "/" + path).orElse(path), group, version);
|
||||
serviceMetadata.setServiceKey(pathKey);
|
||||
ProviderModel providerModel = new ProviderModel(ref, serviceMetadata);
|
||||
ProviderModel providerModel = new ProviderModel(pathKey, ref, ApplicationModel.registerServiceModel(interfaceClass));
|
||||
ApplicationModel.initProviderModel(pathKey, providerModel);
|
||||
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class CacheTest {
|
|||
parameters.put("findCache.cache", "threadlocal");
|
||||
URL url = new URL("dubbo", "127.0.0.1", 29582, "org.apache.dubbo.config.cache.CacheService", parameters);
|
||||
|
||||
Invocation invocation = new RpcInvocation("findCache", new Class[]{String.class}, new String[]{"0"}, null, null);
|
||||
Invocation invocation = new RpcInvocation("findCache", "org.apache.dubbo.config.cache.CacheService", new Class[]{String.class}, new String[]{"0"}, null, null);
|
||||
|
||||
Cache cache = cacheFactory.getCache(url, invocation);
|
||||
assertTrue(cache instanceof ThreadLocalCache);
|
||||
|
|
|
|||
|
|
@ -22,5 +22,8 @@ public interface DemoService {
|
|||
|
||||
String sayHello(String name);
|
||||
|
||||
CompletableFuture<String> sayHelloAsync(String name);
|
||||
default CompletableFuture<String> sayHelloAsync(String name) {
|
||||
return CompletableFuture.completedFuture(sayHello(name));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,12 +20,18 @@ import org.apache.dubbo.demo.DemoService;
|
|||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
/**
|
||||
* In order to make sure multicast registry works, need to specify '-Djava.net.preferIPv4Stack=true' before
|
||||
* launch the application
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
|
||||
context.start();
|
||||
DemoService demoService = context.getBean("demoService", DemoService.class);
|
||||
String hello = demoService.sayHello("world");
|
||||
System.out.println("result: " + hello);
|
||||
CompletableFuture<String> hello = demoService.sayHelloAsync("world");
|
||||
System.out.println("result: " + hello.get());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,17 +30,24 @@ public class DemoServiceImpl implements DemoService {
|
|||
@Override
|
||||
public String sayHello(String name) {
|
||||
logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
|
||||
return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> sayHelloAsync(String name) {
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CompletableFuture.completedFuture("future return value!");
|
||||
return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> sayHelloAsync(String name) {
|
||||
CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "async result";
|
||||
});
|
||||
return cf;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public class MonitorFilterTest {
|
|||
public void testFilter() throws Exception {
|
||||
MonitorFilter monitorFilter = new MonitorFilter();
|
||||
monitorFilter.setMonitorFactory(monitorFactory);
|
||||
Invocation invocation = new RpcInvocation("aaa", new Class<?>[0], new Object[0]);
|
||||
Invocation invocation = new RpcInvocation("aaa", MonitorService.class.getName(), new Class<?>[0], new Object[0]);
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
Result result = monitorFilter.invoke(serviceInvoker, invocation);
|
||||
result.whenCompleteWithContext((r, t) -> {
|
||||
|
|
@ -149,7 +149,7 @@ public class MonitorFilterTest {
|
|||
MonitorFilter monitorFilter = new MonitorFilter();
|
||||
MonitorFactory mockMonitorFactory = mock(MonitorFactory.class);
|
||||
monitorFilter.setMonitorFactory(mockMonitorFactory);
|
||||
Invocation invocation = new RpcInvocation("aaa", new Class<?>[0], new Object[0]);
|
||||
Invocation invocation = new RpcInvocation("aaa", MonitorService.class.getName(), new Class<?>[0], new Object[0]);
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
given(invoker.getUrl()).willReturn(URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":20880?" + APPLICATION_KEY + "=abc&" + SIDE_KEY + "=" + CONSUMER_SIDE));
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ public class MonitorFilterTest {
|
|||
public void testGenericFilter() throws Exception {
|
||||
MonitorFilter monitorFilter = new MonitorFilter();
|
||||
monitorFilter.setMonitorFactory(monitorFactory);
|
||||
Invocation invocation = new RpcInvocation("$invoke", new Class<?>[]{String.class, String[].class, Object[].class}, new Object[]{"xxx", new String[]{}, new Object[]{}});
|
||||
Invocation invocation = new RpcInvocation("$invoke", MonitorService.class.getName(), new Class<?>[]{String.class, String[].class, Object[].class}, new Object[]{"xxx", new String[]{}, new Object[]{}});
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
Result result = monitorFilter.invoke(serviceInvoker, invocation);
|
||||
result.whenCompleteWithContext((r, t) -> {
|
||||
|
|
@ -196,7 +196,7 @@ public class MonitorFilterTest {
|
|||
|
||||
monitorFilter.setMonitorFactory(mockMonitorFactory);
|
||||
given(mockMonitorFactory.getMonitor(any(URL.class))).willReturn(mockMonitor);
|
||||
Invocation invocation = new RpcInvocation("aaa", new Class<?>[0], new Object[0]);
|
||||
Invocation invocation = new RpcInvocation("aaa", MonitorService.class.getName(), new Class<?>[0], new Object[0]);
|
||||
|
||||
monitorFilter.invoke(serviceInvoker, invocation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ import org.apache.dubbo.monitor.support.AbstractMonitorFactory;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CHECK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.REFERENCE_FILTER_KEY;
|
||||
|
||||
|
|
@ -63,6 +64,7 @@ public class DubboMonitorFactory extends AbstractMonitorFactory {
|
|||
}
|
||||
urlBuilder.addParameters(CHECK_KEY, String.valueOf(false),
|
||||
REFERENCE_FILTER_KEY, filter + "-monitor");
|
||||
ApplicationModel.registerServiceModel(MonitorService.class);
|
||||
Invoker<MonitorService> monitorInvoker = protocol.refer(MonitorService.class, urlBuilder.build());
|
||||
MonitorService monitorService = proxyFactory.getProxy(monitorInvoker);
|
||||
return new DubboMonitor(monitorInvoker, monitorService);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.Protocol;
|
|||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
|
@ -56,6 +57,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
import static org.apache.dubbo.monitor.Constants.DUBBO_CONSUMER;
|
||||
import static org.apache.dubbo.monitor.Constants.DUBBO_CONSUMER_METHOD;
|
||||
import static org.apache.dubbo.monitor.Constants.DUBBO_GROUP;
|
||||
|
|
@ -65,7 +67,6 @@ import static org.apache.dubbo.monitor.Constants.METHOD;
|
|||
import static org.apache.dubbo.monitor.Constants.METRICS_PORT;
|
||||
import static org.apache.dubbo.monitor.Constants.METRICS_PROTOCOL;
|
||||
import static org.apache.dubbo.monitor.Constants.SERVICE;
|
||||
import static org.apache.dubbo.remoting.Constants.EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
|
||||
public class MetricsFilter implements Filter {
|
||||
|
||||
|
|
@ -88,6 +89,7 @@ public class MetricsFilter implements Filter {
|
|||
Invoker<MetricsService> metricsInvoker = initMetricsInvoker();
|
||||
|
||||
try {
|
||||
ApplicationModel.registerServiceModel(MetricsService.class);
|
||||
protocol.export(metricsInvoker);
|
||||
} catch (RuntimeException e) {
|
||||
logger.error("Metrics Service need to be configured" +
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public class MetricsFilterTest {
|
|||
IMetricManager metricManager = MetricManager.getIMetricManager();
|
||||
metricManager.clear();
|
||||
MetricsFilter metricsFilter = new MetricsFilter();
|
||||
Invocation invocation = new RpcInvocation("sayName", new Class<?>[]{Integer.class}, new Object[0]);
|
||||
Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), new Class<?>[]{Integer.class}, new Object[0]);
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, CONSUMER_SIDE));
|
||||
AppResponse response = AppResponseBuilder.create()
|
||||
|
|
@ -146,7 +146,7 @@ public class MetricsFilterTest {
|
|||
IMetricManager metricManager = MetricManager.getIMetricManager();
|
||||
metricManager.clear();
|
||||
MetricsFilter metricsFilter = new MetricsFilter();
|
||||
Invocation invocation = new RpcInvocation("timeoutException", null, null);
|
||||
Invocation invocation = new RpcInvocation("timeoutException", DemoService.class.getName(), null, null);
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
RpcContext.getContext().setUrl(timeoutInvoker.getUrl().addParameter(SIDE_KEY, CONSUMER_SIDE)
|
||||
.addParameter(TIMEOUT_KEY, 300));
|
||||
|
|
@ -179,7 +179,7 @@ public class MetricsFilterTest {
|
|||
IMetricManager metricManager = MetricManager.getIMetricManager();
|
||||
metricManager.clear();
|
||||
MetricsFilter metricsFilter = new MetricsFilter();
|
||||
Invocation invocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
|
||||
Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), new Class<?>[0], new Object[0]);
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, PROVIDER));
|
||||
AppResponse response = AppResponseBuilder.create()
|
||||
|
|
@ -206,7 +206,7 @@ public class MetricsFilterTest {
|
|||
IMetricManager metricManager = MetricManager.getIMetricManager();
|
||||
metricManager.clear();
|
||||
MetricsFilter metricsFilter = new MetricsFilter();
|
||||
Invocation invocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
|
||||
Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), new Class<?>[0], new Object[0]);
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, PROVIDER_SIDE)
|
||||
.addParameter(TIMEOUT_KEY, 300));
|
||||
|
|
@ -224,7 +224,7 @@ public class MetricsFilterTest {
|
|||
Protocol protocol = new DubboProtocol();
|
||||
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":20880/" + MetricsService.class.getName());
|
||||
Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url);
|
||||
invocation = new RpcInvocation("getMetricsByGroup", new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP});
|
||||
invocation = new RpcInvocation("getMetricsByGroup", DemoService.class.getName(), new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP});
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (Exception e) {
|
||||
|
|
@ -253,8 +253,8 @@ public class MetricsFilterTest {
|
|||
IMetricManager metricManager = MetricManager.getIMetricManager();
|
||||
metricManager.clear();
|
||||
MetricsFilter metricsFilter = new MetricsFilter();
|
||||
Invocation sayNameInvocation = new RpcInvocation("sayName", new Class<?>[0], new Object[0]);
|
||||
Invocation echoInvocation = new RpcInvocation("echo", new Class<?>[]{Integer.class}, new Integer[]{1});
|
||||
Invocation sayNameInvocation = new RpcInvocation("sayName", DemoService.class.getName(), new Class<?>[0], new Object[0]);
|
||||
Invocation echoInvocation = new RpcInvocation("echo", DemoService.class.getName(), new Class<?>[]{Integer.class}, new Integer[]{1});
|
||||
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
|
||||
RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, PROVIDER_SIDE)
|
||||
.addParameter(TIMEOUT_KEY, 300));
|
||||
|
|
@ -279,7 +279,7 @@ public class MetricsFilterTest {
|
|||
Protocol protocol = new DubboProtocol();
|
||||
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":20880/" + MetricsService.class.getName());
|
||||
Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url);
|
||||
Invocation invocation = new RpcInvocation("getMetricsByGroup", new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP});
|
||||
Invocation invocation = new RpcInvocation("getMetricsByGroup", DemoService.class.getName(), new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP});
|
||||
try {
|
||||
Thread.sleep(15000);
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class Ls implements BaseCommand {
|
|||
|
||||
//Content
|
||||
for (ProviderModel providerModel : providerModelList) {
|
||||
tTable.addRow(providerModel.getServiceName(), isRegistered(providerModel.getServiceName()) ? "Y" : "N");
|
||||
tTable.addRow(providerModel.getServiceKey(), isRegistered(providerModel.getServiceKey()) ? "Y" : "N");
|
||||
}
|
||||
stringBuilder.append(tTable.rendering());
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ public class Ls implements BaseCommand {
|
|||
//Content
|
||||
//TODO to calculate consumerAddressNum
|
||||
for (ConsumerModel consumerModel : consumerModelList) {
|
||||
tTable.addRow(consumerModel.getServiceName(), getConsumerAddressNum(consumerModel.getServiceName()));
|
||||
tTable.addRow(consumerModel.getServiceKey(), getConsumerAddressNum(consumerModel.getServiceKey()));
|
||||
}
|
||||
|
||||
stringBuilder.append(tTable.rendering());
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ public class Offline implements BaseCommand {
|
|||
|
||||
Collection<ProviderModel> providerModelList = ApplicationModel.allProviderModels();
|
||||
for (ProviderModel providerModel : providerModelList) {
|
||||
if (providerModel.getServiceName().matches(servicePattern)) {
|
||||
if (providerModel.getServiceKey().matches(servicePattern)) {
|
||||
hasService = true;
|
||||
Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceName());
|
||||
Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceKey());
|
||||
for (ProviderInvokerWrapper providerInvokerWrapper : providerInvokerWrapperSet) {
|
||||
if (!providerInvokerWrapper.isReg()) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ public class Online implements BaseCommand {
|
|||
|
||||
Collection<ProviderModel> providerModelList = ApplicationModel.allProviderModels();
|
||||
for (ProviderModel providerModel : providerModelList) {
|
||||
if (providerModel.getServiceName().matches(servicePattern)) {
|
||||
if (providerModel.getServiceKey().matches(servicePattern)) {
|
||||
hasService = true;
|
||||
Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceName());
|
||||
Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceKey());
|
||||
for (ProviderInvokerWrapper providerInvokerWrapper : providerInvokerWrapperSet) {
|
||||
if (providerInvokerWrapper.isReg()) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -25,14 +25,15 @@ import org.apache.dubbo.rpc.Invoker;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.registry.support.ProviderConsumerRegTable.getProviderInvoker;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
|
@ -40,9 +41,9 @@ public class LsTest {
|
|||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
ConsumerModel consumerModel = mock(ConsumerModel.class);
|
||||
when(consumerModel.getServiceName()).thenReturn("org.apache.dubbo.FooService");
|
||||
when(consumerModel.getServiceKey()).thenReturn("org.apache.dubbo.FooService");
|
||||
ProviderModel providerModel = mock(ProviderModel.class);
|
||||
when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.BarService");
|
||||
when(providerModel.getServiceKey()).thenReturn("org.apache.dubbo.BarService");
|
||||
ApplicationModel.initConsumerModel("org.apache.dubbo.FooService", consumerModel);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.BarService", providerModel);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@ import org.apache.dubbo.registry.support.ProviderInvokerWrapper;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.apache.dubbo.registry.support.ProviderConsumerRegTable.getProviderInvoker;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ public class OfflineTest {
|
|||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
ProviderModel providerModel = mock(ProviderModel.class);
|
||||
when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.BarService");
|
||||
when(providerModel.getServiceKey()).thenReturn("org.apache.dubbo.BarService");
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.BarService", providerModel);
|
||||
|
||||
Invoker providerInvoker = mock(Invoker.class);
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ import org.apache.dubbo.registry.support.ProviderInvokerWrapper;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.registry.support.ProviderConsumerRegTable.getProviderInvoker;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
|
@ -37,7 +38,7 @@ public class OnlineTest {
|
|||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
ProviderModel providerModel = mock(ProviderModel.class);
|
||||
when(providerModel.getServiceName()).thenReturn("org.apache.dubbo.BarService");
|
||||
when(providerModel.getServiceKey()).thenReturn("org.apache.dubbo.BarService");
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.BarService", providerModel);
|
||||
|
||||
Invoker providerInvoker = mock(Invoker.class);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.apache.dubbo.registry.integration;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.URLBuilder;
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -35,7 +34,6 @@ import org.apache.dubbo.remoting.Constants;
|
|||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.cluster.Cluster;
|
||||
import org.apache.dubbo.rpc.cluster.Configurator;
|
||||
import org.apache.dubbo.rpc.cluster.Router;
|
||||
|
|
@ -571,43 +569,44 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
|
|||
|
||||
@Override
|
||||
public List<Invoker<T>> doList(Invocation invocation) {
|
||||
if (forbidden) {
|
||||
// 1. No service provider 2. Service providers are disabled
|
||||
throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, "No provider available from registry " +
|
||||
getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " +
|
||||
NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() +
|
||||
", please check status of providers(disabled, not registered or in blacklist).");
|
||||
}
|
||||
|
||||
if (multiGroup) {
|
||||
return this.invokers == null ? Collections.emptyList() : this.invokers;
|
||||
}
|
||||
|
||||
List<Invoker<T>> invokers = null;
|
||||
try {
|
||||
// Get invokers from cache, only runtime routers will be executed.
|
||||
invokers = routerChain.route(getConsumerUrl(), invocation);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
|
||||
}
|
||||
|
||||
|
||||
// FIXME Is there any need of failing back to Constants.ANY_VALUE or the first available method invokers when invokers is null?
|
||||
/*Map<String, List<Invoker<T>>> localMethodInvokerMap = this.methodInvokerMap; // local reference
|
||||
if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) {
|
||||
String methodName = RpcUtils.getMethodName(invocation);
|
||||
invokers = localMethodInvokerMap.get(methodName);
|
||||
if (invokers == null) {
|
||||
invokers = localMethodInvokerMap.get(Constants.ANY_VALUE);
|
||||
}
|
||||
if (invokers == null) {
|
||||
Iterator<List<Invoker<T>>> iterator = localMethodInvokerMap.values().iterator();
|
||||
if (iterator.hasNext()) {
|
||||
invokers = iterator.next();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return invokers == null ? Collections.emptyList() : invokers;
|
||||
// if (forbidden) {
|
||||
// // 1. No service provider 2. Service providers are disabled
|
||||
// throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, "No provider available from registry " +
|
||||
// getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " +
|
||||
// NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() +
|
||||
// ", please check status of providers(disabled, not registered or in blacklist).");
|
||||
// }
|
||||
//
|
||||
// if (multiGroup) {
|
||||
// return this.invokers == null ? Collections.emptyList() : this.invokers;
|
||||
// }
|
||||
//
|
||||
// List<Invoker<T>> invokers = null;
|
||||
// try {
|
||||
// // Get invokers from cache, only runtime routers will be executed.
|
||||
// invokers = routerChain.route(getConsumerUrl(), invocation);
|
||||
// } catch (Throwable t) {
|
||||
// logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // FIXME Is there any need of failing back to Constants.ANY_VALUE or the first available method invokers when invokers is null?
|
||||
// /*Map<String, List<Invoker<T>>> localMethodInvokerMap = this.methodInvokerMap; // local reference
|
||||
// if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) {
|
||||
// String methodName = RpcUtils.getMethodName(invocation);
|
||||
// invokers = localMethodInvokerMap.get(methodName);
|
||||
// if (invokers == null) {
|
||||
// invokers = localMethodInvokerMap.get(Constants.ANY_VALUE);
|
||||
// }
|
||||
// if (invokers == null) {
|
||||
// Iterator<List<Invoker<T>>> iterator = localMethodInvokerMap.values().iterator();
|
||||
// if (iterator.hasNext()) {
|
||||
// invokers = iterator.next();
|
||||
// }
|
||||
// }
|
||||
// }*/
|
||||
// return invokers == null ? Collections.emptyList() : invokers;
|
||||
return invokers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance;
|
|||
import org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance;
|
||||
import org.apache.dubbo.rpc.cluster.router.script.ScriptRouterFactory;
|
||||
import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
@ -49,27 +50,27 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.LOADBALANCE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.MOCK_PROTOCOL;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.TYPE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.LOADBALANCE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.MOCK_PROTOCOL;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.TYPE_KEY;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
|
|
@ -482,7 +483,7 @@ public class RegistryDirectoryTest {
|
|||
registryDirectory.notify(serviceUrls);
|
||||
|
||||
// Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;
|
||||
invocation = new RpcInvocation($INVOKE, new Class[]{String.class, String[].class, Object[].class},
|
||||
invocation = new RpcInvocation($INVOKE, GenericService.class.getName(), new Class[]{String.class, String[].class, Object[].class},
|
||||
new Object[]{"getXXX1", "", new Object[]{}});
|
||||
|
||||
List<Invoker> invokers = registryDirectory.list(invocation);
|
||||
|
|
@ -509,7 +510,7 @@ public class RegistryDirectoryTest {
|
|||
|
||||
registryDirectory.notify(serviceUrls);
|
||||
|
||||
invocation = new RpcInvocation($INVOKE,
|
||||
invocation = new RpcInvocation($INVOKE, GenericService.class.getName(),
|
||||
new Class[]{String.class, String[].class, Object[].class},
|
||||
new Object[]{"getXXX1", new String[]{"Enum"}, new Object[]{Param.MORGAN}});
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@
|
|||
package org.apache.dubbo.remoting;
|
||||
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public interface Constants {
|
||||
|
||||
String BUFFER_KEY = "buffer";
|
||||
|
|
@ -117,8 +115,6 @@ public interface Constants {
|
|||
|
||||
String CHANNEL_SEND_READONLYEVENT_KEY = "channel.readonly.send";
|
||||
|
||||
String EXECUTOR_SERVICE_COMPONENT_KEY = ExecutorService.class.getName();
|
||||
|
||||
String RECONNECT_KEY = "reconnect";
|
||||
|
||||
int DEFAULT_RECONNECT_PERIOD = 2000;
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ public abstract class AbstractTimerTask implements TimerTask {
|
|||
}
|
||||
|
||||
static Long lastRead(Channel channel) {
|
||||
return (Long) channel.getAttribute(HeaderExchangeHandler.KEY_READ_TIMESTAMP);
|
||||
return (Long) channel.getAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP);
|
||||
}
|
||||
|
||||
static Long lastWrite(Channel channel) {
|
||||
return (Long) channel.getAttribute(HeaderExchangeHandler.KEY_WRITE_TIMESTAMP);
|
||||
return (Long) channel.getAttribute(HeartbeatHandler.KEY_WRITE_TIMESTAMP);
|
||||
}
|
||||
|
||||
static Long now() {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,12 @@ final class HeaderExchangeChannel implements ExchangeChannel {
|
|||
}
|
||||
}
|
||||
|
||||
static void removeChannel(Channel ch) {
|
||||
if (ch != null) {
|
||||
ch.removeAttribute(CHANNEL_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object message) throws RemotingException {
|
||||
send(message, false);
|
||||
|
|
|
|||
|
|
@ -44,10 +44,6 @@ public class HeaderExchangeHandler implements ChannelHandlerDelegate {
|
|||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(HeaderExchangeHandler.class);
|
||||
|
||||
public static final String KEY_READ_TIMESTAMP = HeartbeatHandler.KEY_READ_TIMESTAMP;
|
||||
|
||||
public static final String KEY_WRITE_TIMESTAMP = HeartbeatHandler.KEY_WRITE_TIMESTAMP;
|
||||
|
||||
private final ExchangeHandler handler;
|
||||
|
||||
public HeaderExchangeHandler(ExchangeHandler handler) {
|
||||
|
|
@ -112,8 +108,6 @@ public class HeaderExchangeHandler implements ChannelHandlerDelegate {
|
|||
channel.send(res);
|
||||
} catch (RemotingException e) {
|
||||
logger.warn("Send result to consumer failed, channel is " + channel + ", msg is " + e);
|
||||
} finally {
|
||||
// HeaderExchangeChannel.removeChannelIfDisconnected(channel);
|
||||
}
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
|
|
@ -125,26 +119,18 @@ public class HeaderExchangeHandler implements ChannelHandlerDelegate {
|
|||
|
||||
@Override
|
||||
public void connected(Channel channel) throws RemotingException {
|
||||
channel.setAttribute(KEY_READ_TIMESTAMP, System.currentTimeMillis());
|
||||
channel.setAttribute(KEY_WRITE_TIMESTAMP, System.currentTimeMillis());
|
||||
ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
|
||||
try {
|
||||
handler.connected(exchangeChannel);
|
||||
} finally {
|
||||
HeaderExchangeChannel.removeChannelIfDisconnected(channel);
|
||||
}
|
||||
handler.connected(exchangeChannel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(Channel channel) throws RemotingException {
|
||||
channel.setAttribute(KEY_READ_TIMESTAMP, System.currentTimeMillis());
|
||||
channel.setAttribute(KEY_WRITE_TIMESTAMP, System.currentTimeMillis());
|
||||
ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
|
||||
try {
|
||||
handler.disconnected(exchangeChannel);
|
||||
} finally {
|
||||
DefaultFuture.closeChannel(channel);
|
||||
HeaderExchangeChannel.removeChannelIfDisconnected(channel);
|
||||
HeaderExchangeChannel.removeChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,15 +138,11 @@ public class HeaderExchangeHandler implements ChannelHandlerDelegate {
|
|||
public void sent(Channel channel, Object message) throws RemotingException {
|
||||
Throwable exception = null;
|
||||
try {
|
||||
channel.setAttribute(KEY_WRITE_TIMESTAMP, System.currentTimeMillis());
|
||||
ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
|
||||
try {
|
||||
handler.sent(exchangeChannel, message);
|
||||
} finally {
|
||||
HeaderExchangeChannel.removeChannelIfDisconnected(channel);
|
||||
}
|
||||
handler.sent(exchangeChannel, message);
|
||||
} catch (Throwable t) {
|
||||
exception = t;
|
||||
HeaderExchangeChannel.removeChannelIfDisconnected(channel);
|
||||
}
|
||||
if (message instanceof Request) {
|
||||
Request request = (Request) message;
|
||||
|
|
@ -180,38 +162,33 @@ public class HeaderExchangeHandler implements ChannelHandlerDelegate {
|
|||
|
||||
@Override
|
||||
public void received(Channel channel, Object message) throws RemotingException {
|
||||
channel.setAttribute(KEY_READ_TIMESTAMP, System.currentTimeMillis());
|
||||
final ExchangeChannel exchangeChannel = HeaderExchangeChannel.getOrAddChannel(channel);
|
||||
try {
|
||||
if (message instanceof Request) {
|
||||
// handle request.
|
||||
Request request = (Request) message;
|
||||
if (request.isEvent()) {
|
||||
handlerEvent(channel, request);
|
||||
} else {
|
||||
if (request.isTwoWay()) {
|
||||
handleRequest(exchangeChannel, request);
|
||||
} else {
|
||||
handler.received(exchangeChannel, request.getData());
|
||||
}
|
||||
}
|
||||
} else if (message instanceof Response) {
|
||||
handleResponse(channel, (Response) message);
|
||||
} else if (message instanceof String) {
|
||||
if (isClientSide(channel)) {
|
||||
Exception e = new Exception("Dubbo client can not supported string message: " + message + " in channel: " + channel + ", url: " + channel.getUrl());
|
||||
logger.error(e.getMessage(), e);
|
||||
} else {
|
||||
String echo = handler.telnet(channel, (String) message);
|
||||
if (echo != null && echo.length() > 0) {
|
||||
channel.send(echo);
|
||||
}
|
||||
}
|
||||
if (message instanceof Request) {
|
||||
// handle request.
|
||||
Request request = (Request) message;
|
||||
if (request.isEvent()) {
|
||||
handlerEvent(channel, request);
|
||||
} else {
|
||||
handler.received(exchangeChannel, message);
|
||||
if (request.isTwoWay()) {
|
||||
handleRequest(exchangeChannel, request);
|
||||
} else {
|
||||
handler.received(exchangeChannel, request.getData());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
HeaderExchangeChannel.removeChannelIfDisconnected(channel);
|
||||
} else if (message instanceof Response) {
|
||||
handleResponse(channel, (Response) message);
|
||||
} else if (message instanceof String) {
|
||||
if (isClientSide(channel)) {
|
||||
Exception e = new Exception("Dubbo client can not supported string message: " + message + " in channel: " + channel + ", url: " + channel.getUrl());
|
||||
logger.error(e.getMessage(), e);
|
||||
} else {
|
||||
String echo = handler.telnet(channel, (String) message);
|
||||
if (echo != null && echo.length() > 0) {
|
||||
channel.send(echo);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handler.received(exchangeChannel, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_CLIENT_THREADPOOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
|
||||
|
||||
|
|
@ -193,7 +192,7 @@ public abstract class AbstractClient extends AbstractEndpoint implements Client
|
|||
|
||||
} else {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Succeed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
|
||||
logger.info("Successed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
|
||||
+ NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()
|
||||
+ ", channel is " + this.getChannel());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,11 +35,10 @@ import java.util.concurrent.ExecutorService;
|
|||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.IDLE_TIMEOUT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.DEFAULT_IDLE_TIMEOUT;
|
||||
import static org.apache.dubbo.remoting.Constants.ACCEPTS_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.DEFAULT_ACCEPTS;
|
||||
import static org.apache.dubbo.remoting.Constants.DEFAULT_IDLE_TIMEOUT;
|
||||
import static org.apache.dubbo.remoting.Constants.IDLE_TIMEOUT_KEY;
|
||||
|
||||
/**
|
||||
* AbstractServer
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.timer.HashedWheelTimer;
|
||||
import org.apache.dubbo.remoting.Channel;
|
||||
import org.apache.dubbo.remoting.exchange.Request;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -63,10 +64,8 @@ public class HeartBeatTaskTest {
|
|||
long now = System.currentTimeMillis();
|
||||
|
||||
url = url.addParameter(DUBBO_VERSION_KEY, "2.1.1");
|
||||
channel.setAttribute(
|
||||
HeaderExchangeHandler.KEY_READ_TIMESTAMP, now);
|
||||
channel.setAttribute(
|
||||
HeaderExchangeHandler.KEY_WRITE_TIMESTAMP, now);
|
||||
channel.setAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP, now);
|
||||
channel.setAttribute(HeartbeatHandler.KEY_WRITE_TIMESTAMP, now);
|
||||
|
||||
heartbeatTimer.newTimeout(heartbeatTimerTask, 250, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.net.InetSocketAddress;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
|
||||
|
|
@ -50,6 +51,9 @@ final class NettyChannel extends AbstractChannel {
|
|||
private final Channel channel;
|
||||
|
||||
private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
private final AtomicBoolean active = new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* The constructor of NettyChannel.
|
||||
* It is private so NettyChannel usually create by {@link NettyChannel#getOrAddChannel(Channel, URL, ChannelHandler)}
|
||||
|
|
@ -82,6 +86,7 @@ final class NettyChannel extends AbstractChannel {
|
|||
if (ret == null) {
|
||||
NettyChannel nettyChannel = new NettyChannel(ch, url, handler);
|
||||
if (ch.isActive()) {
|
||||
nettyChannel.markActive(true);
|
||||
ret = CHANNEL_MAP.putIfAbsent(ch, nettyChannel);
|
||||
}
|
||||
if (ret == null) {
|
||||
|
|
@ -97,7 +102,19 @@ final class NettyChannel extends AbstractChannel {
|
|||
*/
|
||||
static void removeChannelIfDisconnected(Channel ch) {
|
||||
if (ch != null && !ch.isActive()) {
|
||||
CHANNEL_MAP.remove(ch);
|
||||
NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);
|
||||
if (nettyChannel != null) {
|
||||
nettyChannel.markActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void removeChannel(Channel ch) {
|
||||
if (ch != null) {
|
||||
NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);
|
||||
if (nettyChannel != null) {
|
||||
nettyChannel.markActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +130,15 @@ final class NettyChannel extends AbstractChannel {
|
|||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return !isClosed() && channel.isActive();
|
||||
return !isClosed() && active.get();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active.get();
|
||||
}
|
||||
|
||||
public void markActive(boolean isActive) {
|
||||
active.set(isActive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -142,6 +167,7 @@ final class NettyChannel extends AbstractChannel {
|
|||
throw cause;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
removeChannelIfDisconnected(channel);
|
||||
throw new RemotingException(this, "Failed to send message " + message + " to " + getRemoteAddress() + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
if (!success) {
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@ import io.netty.handler.proxy.Socks5ProxyHandler;
|
|||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
/**
|
||||
* NettyClient.
|
||||
*/
|
||||
|
|
@ -192,7 +192,7 @@ public class NettyClient extends AbstractClient {
|
|||
@Override
|
||||
protected org.apache.dubbo.remoting.Channel getChannel() {
|
||||
Channel c = channel;
|
||||
if (c == null || !c.isActive()) {
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
return NettyChannel.getOrAddChannel(c, getUrl(), this);
|
||||
|
|
|
|||
|
|
@ -55,11 +55,7 @@ public class NettyClientHandler extends ChannelDuplexHandler {
|
|||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
|
||||
try {
|
||||
handler.connected(channel);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
}
|
||||
handler.connected(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -68,18 +64,14 @@ public class NettyClientHandler extends ChannelDuplexHandler {
|
|||
try {
|
||||
handler.disconnected(channel);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
NettyChannel.removeChannel(ctx.channel());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
|
||||
try {
|
||||
handler.received(channel, msg);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
}
|
||||
handler.received(channel, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -92,21 +84,17 @@ public class NettyClientHandler extends ChannelDuplexHandler {
|
|||
// If our out bound event has an error (in most cases the encoder fails),
|
||||
// we need to have the request return directly instead of blocking the invoke process.
|
||||
promise.addListener(future -> {
|
||||
try {
|
||||
if (future.isSuccess()) {
|
||||
// if our future is success, mark the future to sent.
|
||||
handler.sent(channel, msg);
|
||||
return;
|
||||
}
|
||||
if (future.isSuccess()) {
|
||||
// if our future is success, mark the future to sent.
|
||||
handler.sent(channel, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
Throwable t = future.cause();
|
||||
if (t != null && isRequest) {
|
||||
Request request = (Request) msg;
|
||||
Response response = buildErrorResponse(request, t);
|
||||
handler.received(channel, response);
|
||||
}
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
Throwable t = future.cause();
|
||||
if (t != null && isRequest) {
|
||||
Request request = (Request) msg;
|
||||
Response response = buildErrorResponse(request, t);
|
||||
handler.received(channel, response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,11 +66,7 @@ final public class NettyCodecAdapter {
|
|||
org.apache.dubbo.remoting.buffer.ChannelBuffer buffer = new NettyBackedChannelBuffer(out);
|
||||
Channel ch = ctx.channel();
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);
|
||||
try {
|
||||
codec.encode(channel, buffer, msg);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ch);
|
||||
}
|
||||
codec.encode(channel, buffer, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,27 +79,23 @@ final public class NettyCodecAdapter {
|
|||
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
|
||||
|
||||
try {
|
||||
// decode object.
|
||||
do {
|
||||
int saveReaderIndex = message.readerIndex();
|
||||
Object msg = codec.decode(channel, message);
|
||||
if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {
|
||||
message.readerIndex(saveReaderIndex);
|
||||
break;
|
||||
} else {
|
||||
//is it possible to go here ?
|
||||
if (saveReaderIndex == message.readerIndex()) {
|
||||
throw new IOException("Decode without read data.");
|
||||
}
|
||||
if (msg != null) {
|
||||
out.add(msg);
|
||||
}
|
||||
// decode object.
|
||||
do {
|
||||
int saveReaderIndex = message.readerIndex();
|
||||
Object msg = codec.decode(channel, message);
|
||||
if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {
|
||||
message.readerIndex(saveReaderIndex);
|
||||
break;
|
||||
} else {
|
||||
//is it possible to go here ?
|
||||
if (saveReaderIndex == message.readerIndex()) {
|
||||
throw new IOException("Decode without read data.");
|
||||
}
|
||||
} while (message.readable());
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
}
|
||||
if (msg != null) {
|
||||
out.add(msg);
|
||||
}
|
||||
}
|
||||
} while (message.readable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,14 +66,10 @@ public class NettyServerHandler extends ChannelDuplexHandler {
|
|||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
|
||||
try {
|
||||
if (channel != null) {
|
||||
channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel);
|
||||
}
|
||||
handler.connected(channel);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
if (channel != null) {
|
||||
channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel);
|
||||
}
|
||||
handler.connected(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -83,18 +79,14 @@ public class NettyServerHandler extends ChannelDuplexHandler {
|
|||
channels.remove(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()));
|
||||
handler.disconnected(channel);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
NettyChannel.removeChannel(ctx.channel());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
|
||||
try {
|
||||
handler.received(channel, msg);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
}
|
||||
handler.received(channel, msg);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -102,11 +94,7 @@ public class NettyServerHandler extends ChannelDuplexHandler {
|
|||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
super.write(ctx, msg, promise);
|
||||
NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
|
||||
try {
|
||||
handler.sent(channel, msg);
|
||||
} finally {
|
||||
NettyChannel.removeChannelIfDisconnected(ctx.channel());
|
||||
}
|
||||
handler.sent(channel, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractResult extends CompletableFuture<Result> implements Result {
|
||||
public abstract class AbstractResult implements Result {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ package org.apache.dubbo.rpc;
|
|||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* {@link AsyncRpcResult} is introduced in 3.0.0 to replace RpcResult, and RpcResult is replaced with {@link AppResponse}:
|
||||
|
|
@ -158,7 +158,22 @@ public class AppResponse extends AbstractResult implements Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result whenCompleteWithContext(BiConsumer<Result, Throwable> fn) {
|
||||
public Result thenApplyWithContext(Function<AppResponse, AppResponse> fn) {
|
||||
throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> CompletableFuture<U> thenApply(Function<Result, ? extends U> fn) {
|
||||
throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result get() throws InterruptedException, ExecutionException {
|
||||
throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.apache.dubbo.rpc;
|
|||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.threadpool.ThreadlessExecutor;
|
||||
import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
@ -27,7 +26,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* This class represents an unfinished RPC call, it will hold some context information for this call, for example RpcContext and Invocation,
|
||||
|
|
@ -56,18 +55,15 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
|
||||
private Invocation invocation;
|
||||
|
||||
public AsyncRpcResult(Invocation invocation) {
|
||||
private CompletableFuture<AppResponse> responseFuture;
|
||||
|
||||
public AsyncRpcResult(CompletableFuture<AppResponse> future, Invocation invocation) {
|
||||
this.responseFuture = future;
|
||||
this.invocation = invocation;
|
||||
this.storedContext = RpcContext.getContext();
|
||||
this.storedServerContext = RpcContext.getServerContext();
|
||||
}
|
||||
|
||||
public AsyncRpcResult(AsyncRpcResult asyncRpcResult) {
|
||||
this.invocation = asyncRpcResult.getInvocation();
|
||||
this.storedContext = asyncRpcResult.getStoredContext();
|
||||
this.storedServerContext = asyncRpcResult.getStoredServerContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice the return type of {@link #getValue} is the actual type of the RPC method, not {@link AppResponse}
|
||||
*
|
||||
|
|
@ -91,12 +87,12 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
@Override
|
||||
public void setValue(Object value) {
|
||||
try {
|
||||
if (this.isDone()) {
|
||||
this.get().setValue(value);
|
||||
if (responseFuture.isDone()) {
|
||||
responseFuture.get().setValue(value);
|
||||
} else {
|
||||
AppResponse appResponse = new AppResponse();
|
||||
appResponse.setValue(value);
|
||||
this.complete(appResponse);
|
||||
responseFuture.complete(appResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// This should never happen;
|
||||
|
|
@ -112,12 +108,12 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
@Override
|
||||
public void setException(Throwable t) {
|
||||
try {
|
||||
if (this.isDone()) {
|
||||
this.get().setException(t);
|
||||
if (responseFuture.isDone()) {
|
||||
responseFuture.get().setException(t);
|
||||
} else {
|
||||
AppResponse appResponse = new AppResponse();
|
||||
appResponse.setException(t);
|
||||
this.complete(appResponse);
|
||||
responseFuture.complete(appResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// This should never happen;
|
||||
|
|
@ -130,10 +126,18 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
return getAppResponse().hasException();
|
||||
}
|
||||
|
||||
public CompletableFuture<AppResponse> getResponseFuture() {
|
||||
return responseFuture;
|
||||
}
|
||||
|
||||
public void setResponseFuture(CompletableFuture<AppResponse> responseFuture) {
|
||||
this.responseFuture = responseFuture;
|
||||
}
|
||||
|
||||
public Result getAppResponse() {
|
||||
try {
|
||||
if (this.isDone()) {
|
||||
return this.get();
|
||||
if (responseFuture.isDone()) {
|
||||
return responseFuture.get();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// This should never happen;
|
||||
|
|
@ -142,7 +146,6 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
return new AppResponse();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will always return after a maximum 'timeout' waiting:
|
||||
* 1. if value returns before timeout, return normally.
|
||||
|
|
@ -158,12 +161,12 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
ThreadlessExecutor threadlessExecutor = (ThreadlessExecutor) executor;
|
||||
threadlessExecutor.waitAndDrain();
|
||||
}
|
||||
return super.get();
|
||||
return responseFuture.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return this.get();
|
||||
return responseFuture.get(timeout, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -178,27 +181,14 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
return getAppResponse().recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result whenCompleteWithContext(BiConsumer<Result, Throwable> fn) {
|
||||
CompletableFuture<Result> future = this.whenComplete((v, t) -> {
|
||||
beforeContext.accept(v, t);
|
||||
fn.accept(v, t);
|
||||
afterContext.accept(v, t);
|
||||
});
|
||||
|
||||
AsyncRpcResult nextStage = new AsyncRpcResult(this);
|
||||
nextStage.subscribeTo(future);
|
||||
return nextStage;
|
||||
public Result thenApplyWithContext(Function<AppResponse, AppResponse> fn) {
|
||||
this.responseFuture = responseFuture.thenApply(fn.compose(beforeContext).andThen(afterContext));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void subscribeTo(CompletableFuture<?> future) {
|
||||
future.whenComplete((obj, t) -> {
|
||||
if (t != null) {
|
||||
this.completeExceptionally(t);
|
||||
} else {
|
||||
this.complete((Result) obj);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public <U> CompletableFuture<U> thenApply(Function<Result,? extends U> fn) {
|
||||
return this.responseFuture.thenApply(fn);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -231,18 +221,6 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
getAppResponse().setAttachment(key, value);
|
||||
}
|
||||
|
||||
public RpcContext getStoredContext() {
|
||||
return storedContext;
|
||||
}
|
||||
|
||||
public RpcContext getStoredServerContext() {
|
||||
return storedServerContext;
|
||||
}
|
||||
|
||||
public Invocation getInvocation() {
|
||||
return invocation;
|
||||
}
|
||||
|
||||
public Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
|
@ -257,25 +235,25 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
private RpcContext tmpContext;
|
||||
private RpcContext tmpServerContext;
|
||||
|
||||
private BiConsumer<Result, Throwable> beforeContext = (appResponse, t) -> {
|
||||
private Function<AppResponse, AppResponse> beforeContext = (appResponse) -> {
|
||||
tmpContext = RpcContext.getContext();
|
||||
tmpServerContext = RpcContext.getServerContext();
|
||||
RpcContext.restoreContext(storedContext);
|
||||
RpcContext.restoreServerContext(storedServerContext);
|
||||
return appResponse;
|
||||
};
|
||||
|
||||
private BiConsumer<Result, Throwable> afterContext = (appResponse, t) -> {
|
||||
private Function<AppResponse, AppResponse> afterContext = (appResponse) -> {
|
||||
RpcContext.restoreContext(tmpContext);
|
||||
RpcContext.restoreServerContext(tmpServerContext);
|
||||
return appResponse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Some utility methods used to quickly generate default AsyncRpcResult instance.
|
||||
*/
|
||||
public static AsyncRpcResult newDefaultAsyncResult(AppResponse appResponse, Invocation invocation) {
|
||||
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation);
|
||||
asyncRpcResult.complete(appResponse);
|
||||
return asyncRpcResult;
|
||||
return new AsyncRpcResult(CompletableFuture.completedFuture(appResponse), invocation);
|
||||
}
|
||||
|
||||
public static AsyncRpcResult newDefaultAsyncResult(Invocation invocation) {
|
||||
|
|
@ -291,15 +269,15 @@ public class AsyncRpcResult extends AbstractResult {
|
|||
}
|
||||
|
||||
public static AsyncRpcResult newDefaultAsyncResult(Object value, Throwable t, Invocation invocation) {
|
||||
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation);
|
||||
AppResponse appResponse = new AppResponse();
|
||||
CompletableFuture<AppResponse> future = new CompletableFuture<>();
|
||||
AppResponse result = new AppResponse();
|
||||
if (t != null) {
|
||||
appResponse.setException(t);
|
||||
result.setException(t);
|
||||
} else {
|
||||
appResponse.setValue(value);
|
||||
result.setValue(value);
|
||||
}
|
||||
asyncRpcResult.complete(appResponse);
|
||||
return asyncRpcResult;
|
||||
future.complete(result);
|
||||
return new AsyncRpcResult(future, invocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,8 +103,6 @@ public interface Constants {
|
|||
* To decide whether to make connection when the client is created
|
||||
*/
|
||||
String LAZY_CONNECT_KEY = "lazy";
|
||||
String $INVOKE = "$invoke";
|
||||
String $INVOKE_ASYNC = "$invokeAsync";
|
||||
|
||||
String INPUT_KEY = "input";
|
||||
String OUTPUT_KEY = "output";
|
||||
|
|
|
|||
|
|
@ -14,10 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.dubbo;
|
||||
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
package org.apache.dubbo.rpc;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
|
@ -53,6 +50,10 @@ public class FutureAdapter<V> extends CompletableFuture<V> {
|
|||
// TODO figure out the meaning of cancel in DefaultFuture.
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
// Invocation invocation = invocationSoftReference.get();
|
||||
// if (invocation != null) {
|
||||
// invocation.getInvoker().invoke(cancel);
|
||||
// }
|
||||
return appResponseFuture.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +91,4 @@ public class FutureAdapter<V> extends CompletableFuture<V> {
|
|||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<AppResponse> getAppResponseFuture() {
|
||||
return appResponseFuture;
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,13 @@ public interface Invocation {
|
|||
*/
|
||||
String getMethodName();
|
||||
|
||||
|
||||
/**
|
||||
* get the interface name
|
||||
* @return
|
||||
*/
|
||||
String getServiceName();
|
||||
|
||||
/**
|
||||
* get parameter types.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -20,8 +20,11 @@ import java.io.Serializable;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -38,7 +41,7 @@ import java.util.function.BiConsumer;
|
|||
* @see org.apache.dubbo.rpc.Invoker#invoke(Invocation)
|
||||
* @see AppResponse
|
||||
*/
|
||||
public interface Result extends CompletionStage<Result>, Future<Result>, Serializable {
|
||||
public interface Result extends Serializable {
|
||||
|
||||
/**
|
||||
* Get invoke result.
|
||||
|
|
@ -118,14 +121,6 @@ public interface Result extends CompletionStage<Result>, Future<Result>, Seriali
|
|||
|
||||
void setAttachment(String key, Object value);
|
||||
|
||||
/**
|
||||
* Returns the specified {@code valueIfAbsent} when not complete, or
|
||||
* returns the result value or throws an exception when complete.
|
||||
*
|
||||
* @see CompletableFuture#getNow(Object)
|
||||
*/
|
||||
Result getNow(Result valueIfAbsent);
|
||||
|
||||
/**
|
||||
* Add a callback which can be triggered when the RPC call finishes.
|
||||
* <p>
|
||||
|
|
@ -135,9 +130,11 @@ public interface Result extends CompletionStage<Result>, Future<Result>, Seriali
|
|||
* @param fn
|
||||
* @return
|
||||
*/
|
||||
Result whenCompleteWithContext(BiConsumer<Result, Throwable> fn);
|
||||
Result thenApplyWithContext(Function<AppResponse, AppResponse> fn);
|
||||
|
||||
default CompletableFuture<Result> completionFuture() {
|
||||
return toCompletableFuture();
|
||||
}
|
||||
<U> CompletableFuture<U> thenApply(Function<Result, ? extends U> fn);
|
||||
|
||||
Result get() throws InterruptedException, ExecutionException;
|
||||
|
||||
Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
|
||||
}
|
||||
|
|
@ -17,9 +17,12 @@
|
|||
package org.apache.dubbo.rpc;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -42,8 +45,10 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
private static final long serialVersionUID = -4355285085441097045L;
|
||||
|
||||
private String methodName;
|
||||
private String serviceName;
|
||||
|
||||
private Class<?>[] parameterTypes;
|
||||
private transient Class<?>[] parameterTypes;
|
||||
private String parameterTypesDesc;
|
||||
|
||||
private Object[] arguments;
|
||||
|
||||
|
|
@ -55,13 +60,15 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
|
||||
private transient Class<?> returnType;
|
||||
|
||||
private transient Type[] returnTypes;
|
||||
|
||||
private transient InvokeMode invokeMode;
|
||||
|
||||
public RpcInvocation() {
|
||||
}
|
||||
|
||||
public RpcInvocation(Invocation invocation, Invoker<?> invoker) {
|
||||
this(invocation.getMethodName(), invocation.getParameterTypes(),
|
||||
this(invocation.getMethodName(), invocation.getServiceName(), invocation.getParameterTypes(),
|
||||
invocation.getArguments(), new HashMap<>(invocation.getAttachments()),
|
||||
invocation.getInvoker());
|
||||
if (invoker != null) {
|
||||
|
|
@ -89,34 +96,43 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
}
|
||||
|
||||
public RpcInvocation(Invocation invocation) {
|
||||
this(invocation.getMethodName(), invocation.getParameterTypes(),
|
||||
this(invocation.getMethodName(), invocation.getServiceName(), invocation.getParameterTypes(),
|
||||
invocation.getArguments(), invocation.getAttachments(), invocation.getInvoker());
|
||||
}
|
||||
|
||||
public RpcInvocation(Method method, Object[] arguments) {
|
||||
this(method.getName(), method.getParameterTypes(), arguments, null, null);
|
||||
public RpcInvocation(Method method, String serviceName, Object[] arguments) {
|
||||
this(method, serviceName, arguments, null);
|
||||
}
|
||||
|
||||
public RpcInvocation(Method method, Object[] arguments, Map<String, Object> attachment, Map<Object, Object> attributes) {
|
||||
this(method.getName(), method.getParameterTypes(), arguments, attachment, null);
|
||||
public RpcInvocation(Method method, String serviceName, Object[] arguments, Map<String, Object> attachment, Map<Object, Object> attributes) {
|
||||
this(method.getName(), serviceName, method.getParameterTypes(), arguments, attachment, null);
|
||||
this.returnType = method.getReturnType();
|
||||
this.attributes = attributes == null ? new HashMap<>() : attributes;
|
||||
}
|
||||
|
||||
public RpcInvocation(String methodName, Class<?>[] parameterTypes, Object[] arguments) {
|
||||
this(methodName, parameterTypes, arguments, null, null);
|
||||
public RpcInvocation(String methodName, String serviceName, Class<?>[] parameterTypes, Object[] arguments) {
|
||||
this(methodName, serviceName, parameterTypes, arguments, null, null);
|
||||
}
|
||||
|
||||
public RpcInvocation(String methodName, Class<?>[] parameterTypes, Object[] arguments, Map<String, Object> attachments) {
|
||||
this(methodName, parameterTypes, arguments, attachments, null);
|
||||
public RpcInvocation(String methodName, String serviceName, Class<?>[] parameterTypes, Object[] arguments, Map<String, Object> attachments) {
|
||||
this(methodName, serviceName, parameterTypes, arguments, attachments, null);
|
||||
}
|
||||
|
||||
public RpcInvocation(String methodName, Class<?>[] parameterTypes, Object[] arguments, Map<String, Object> attachments, Invoker<?> invoker) {
|
||||
public RpcInvocation(String methodName, String serviceName, Class<?>[] parameterTypes, Object[] arguments, Map<String, Object> attachments, Invoker<?> invoker) {
|
||||
this.methodName = methodName;
|
||||
this.parameterTypes = parameterTypes == null ? new Class<?>[0] : parameterTypes;
|
||||
this.arguments = arguments == null ? new Object[0] : arguments;
|
||||
this.attachments = attachments == null ? new HashMap<String, Object>() : attachments;
|
||||
this.invoker = invoker;
|
||||
if (StringUtils.isNotEmpty(serviceName)) {
|
||||
ApplicationModel.getServiceModel(serviceName).ifPresent(serviceModel ->
|
||||
serviceModel.getMethod(methodName, parameterTypes)
|
||||
.ifPresent(methodModel -> {
|
||||
this.parameterTypesDesc = methodModel.getParamDesc();
|
||||
this.returnTypes = methodModel.getReturnTypes();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -146,6 +162,15 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
return methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
public void setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
|
@ -159,6 +184,14 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
this.parameterTypes = parameterTypes == null ? new Class<?>[0] : parameterTypes;
|
||||
}
|
||||
|
||||
public String getParameterTypesDesc() {
|
||||
return parameterTypesDesc;
|
||||
}
|
||||
|
||||
public void setParameterTypesDesc(String parameterTypesDesc) {
|
||||
this.parameterTypesDesc = parameterTypesDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getArguments() {
|
||||
return arguments;
|
||||
|
|
@ -242,6 +275,14 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
public Type[] getReturnTypes() {
|
||||
return returnTypes;
|
||||
}
|
||||
|
||||
public void setReturnTypes(Type[] returnTypes) {
|
||||
this.returnTypes = returnTypes;
|
||||
}
|
||||
|
||||
public InvokeMode getInvokeMode() {
|
||||
return invokeMode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class ConsumerContextFilter extends ListenableFilter {
|
|||
RpcContext.getContext()
|
||||
.setInvoker(invoker)
|
||||
.setInvocation(invocation)
|
||||
.setLocalAddress(NetUtils.getLocalHost(), 0)
|
||||
.setLocalAddress(NetUtils.getHostAddress(), 0)
|
||||
.setRemoteAddress(invoker.getUrl().getHost(),
|
||||
invoker.getUrl().getPort());
|
||||
if (invocation instanceof RpcInvocation) {
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ import org.apache.dubbo.rpc.support.ProtocolUtils;
|
|||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE_ASYNC;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_BEAN;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_NATIVE_JAVA;
|
||||
|
|
@ -138,7 +138,7 @@ public class GenericFilter extends ListenableFilter {
|
|||
args[0].getClass().getName());
|
||||
}
|
||||
}
|
||||
return invoker.invoke(new RpcInvocation(method, args, inv.getAttachments(), inv.getAttributes()));
|
||||
return invoker.invoke(new RpcInvocation(method, invoker.getInterface().getName(), args, inv.getAttachments(), inv.getAttributes()));
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RpcException(e.getMessage(), e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ import java.lang.reflect.Field;
|
|||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE_ASYNC;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
|
||||
/**
|
||||
|
|
@ -54,6 +54,8 @@ public class GenericImplFilter extends ListenableFilter {
|
|||
|
||||
private static final Class<?>[] GENERIC_PARAMETER_TYPES = new Class<?>[]{String.class, String[].class, Object[].class};
|
||||
|
||||
private static final String GENERIC_PARAMETER_DESC = "Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;";
|
||||
|
||||
public GenericImplFilter() {
|
||||
super.listener = new GenericImplListener();
|
||||
}
|
||||
|
|
@ -90,6 +92,7 @@ public class GenericImplFilter extends ListenableFilter {
|
|||
invocation2.setMethodName($INVOKE);
|
||||
}
|
||||
invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES);
|
||||
invocation2.setParameterTypesDesc(GENERIC_PARAMETER_DESC);
|
||||
invocation2.setArguments(new Object[]{methodName, types, args});
|
||||
return invoker.invoke(invocation2);
|
||||
} else if ((invocation.getMethodName().equals($INVOKE) || invocation.getMethodName().equals($INVOKE_ASYNC))
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.logger.Logger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
|
@ -36,18 +37,24 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
* adjust project structure in order to fully utilize the methods introduced here.
|
||||
*/
|
||||
public class ApplicationModel {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(ApplicationModel.class);
|
||||
|
||||
/**
|
||||
* full qualified class name -> provided service
|
||||
* serviceKey -> exported service
|
||||
* each service may has different group, version, path, instance and so on, but they point to the same {@link ServiceModel}
|
||||
*/
|
||||
private static final ConcurrentMap<String, ProviderModel> PROVIDED_SERVICES = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* full qualified class name -> subscribe service
|
||||
* serviceKey -> referred service
|
||||
* each service may has different group, version, path, instance and so on, but they point to the same {@link ServiceModel}
|
||||
*/
|
||||
private static final ConcurrentMap<String, ConsumerModel> CONSUMED_SERVICES = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* The description of a unique service (interface definition in Dubbo)
|
||||
*/
|
||||
private static final ConcurrentHashMap<String, ServiceModel> SERVICES = new ConcurrentHashMap<>();
|
||||
|
||||
private static String application;
|
||||
|
||||
private static AtomicBoolean INIT_FLAG = new AtomicBoolean(false);
|
||||
|
|
@ -60,12 +67,12 @@ public class ApplicationModel {
|
|||
return PROVIDED_SERVICES.values();
|
||||
}
|
||||
|
||||
public static ProviderModel getProviderModel(String serviceName) {
|
||||
return PROVIDED_SERVICES.get(serviceName);
|
||||
public static ProviderModel getProviderModel(String serviceKey) {
|
||||
return PROVIDED_SERVICES.get(serviceKey);
|
||||
}
|
||||
|
||||
public static ConsumerModel getConsumerModel(String serviceName) {
|
||||
return CONSUMED_SERVICES.get(serviceName);
|
||||
public static ConsumerModel getConsumerModel(String serviceKey) {
|
||||
return CONSUMED_SERVICES.get(serviceKey);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
|
@ -90,6 +97,38 @@ public class ApplicationModel {
|
|||
}
|
||||
}
|
||||
|
||||
public static ServiceModel registerServiceModel(Class<?> interfaceClass) {
|
||||
return SERVICES.computeIfAbsent(interfaceClass.getName(), (k) -> new ServiceModel(interfaceClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #registerServiceModel(Class)}
|
||||
*
|
||||
* we assume:
|
||||
* 1. services with different interface are not allowed to have the same path.
|
||||
* 2. services with the same interface but different group/version can share the same path.
|
||||
* 3. path's default value is the name of the interface.
|
||||
* @param path
|
||||
* @param interfaceClass
|
||||
* @return
|
||||
*/
|
||||
public static ServiceModel registerServiceModel(String path, Class<?> interfaceClass) {
|
||||
ServiceModel serviceModel = registerServiceModel(interfaceClass);
|
||||
// register path
|
||||
if (!interfaceClass.getName().equals(path)) {
|
||||
SERVICES.putIfAbsent(path, serviceModel);
|
||||
}
|
||||
return serviceModel;
|
||||
}
|
||||
|
||||
public static Optional<ServiceModel> getServiceModel (String interfaceName) {
|
||||
return Optional.ofNullable(SERVICES.get(interfaceName));
|
||||
}
|
||||
|
||||
public static Optional<ServiceModel> getServiceModel (Class<?> interfaceClass) {
|
||||
return Optional.ofNullable(SERVICES.get(interfaceClass.getName()));
|
||||
}
|
||||
|
||||
public static String getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
|
@ -105,4 +144,5 @@ public class ApplicationModel {
|
|||
PROVIDED_SERVICES.clear();
|
||||
CONSUMED_SERVICES.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,161 +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.rpc.model;
|
||||
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
|
||||
public class ConsumerMethodModel {
|
||||
private final Method method;
|
||||
// private final boolean isCallBack;
|
||||
// private final boolean isFuture;
|
||||
private final String[] parameterTypes;
|
||||
private final Class<?>[] parameterClasses;
|
||||
private final Class<?> returnClass;
|
||||
private final String methodName;
|
||||
private final boolean generic;
|
||||
|
||||
private final AsyncMethodInfo asyncInfo;
|
||||
|
||||
|
||||
public ConsumerMethodModel(Method method, Map<String, Object> attributes) {
|
||||
this.method = method;
|
||||
this.parameterClasses = method.getParameterTypes();
|
||||
this.returnClass = method.getReturnType();
|
||||
this.parameterTypes = this.createParamSignature(parameterClasses);
|
||||
this.methodName = method.getName();
|
||||
this.generic = methodName.equals($INVOKE) && parameterTypes != null && parameterTypes.length == 3;
|
||||
|
||||
if (attributes != null) {
|
||||
asyncInfo = (AsyncMethodInfo) attributes.get(methodName);
|
||||
} else {
|
||||
asyncInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public Class<?> getReturnClass() {
|
||||
return returnClass;
|
||||
}
|
||||
|
||||
public AsyncMethodInfo getAsyncInfo() {
|
||||
return asyncInfo;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public String[] getParameterTypes() {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
private String[] createParamSignature(Class<?>[] args) {
|
||||
if (args == null || args.length == 0) {
|
||||
return new String[]{};
|
||||
}
|
||||
String[] paramSig = new String[args.length];
|
||||
for (int x = 0; x < args.length; x++) {
|
||||
paramSig[x] = args[x].getName();
|
||||
}
|
||||
return paramSig;
|
||||
}
|
||||
|
||||
|
||||
public boolean isGeneric() {
|
||||
return generic;
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterClasses() {
|
||||
return parameterClasses;
|
||||
}
|
||||
|
||||
|
||||
public static class AsyncMethodInfo {
|
||||
// callback instance when async-call is invoked
|
||||
private Object oninvokeInstance;
|
||||
|
||||
// callback method when async-call is invoked
|
||||
private Method oninvokeMethod;
|
||||
|
||||
// callback instance when async-call is returned
|
||||
private Object onreturnInstance;
|
||||
|
||||
// callback method when async-call is returned
|
||||
private Method onreturnMethod;
|
||||
|
||||
// callback instance when async-call has exception thrown
|
||||
private Object onthrowInstance;
|
||||
|
||||
// callback method when async-call has exception thrown
|
||||
private Method onthrowMethod;
|
||||
|
||||
public Object getOninvokeInstance() {
|
||||
return oninvokeInstance;
|
||||
}
|
||||
|
||||
public void setOninvokeInstance(Object oninvokeInstance) {
|
||||
this.oninvokeInstance = oninvokeInstance;
|
||||
}
|
||||
|
||||
public Method getOninvokeMethod() {
|
||||
return oninvokeMethod;
|
||||
}
|
||||
|
||||
public void setOninvokeMethod(Method oninvokeMethod) {
|
||||
this.oninvokeMethod = oninvokeMethod;
|
||||
}
|
||||
|
||||
public Object getOnreturnInstance() {
|
||||
return onreturnInstance;
|
||||
}
|
||||
|
||||
public void setOnreturnInstance(Object onreturnInstance) {
|
||||
this.onreturnInstance = onreturnInstance;
|
||||
}
|
||||
|
||||
public Method getOnreturnMethod() {
|
||||
return onreturnMethod;
|
||||
}
|
||||
|
||||
public void setOnreturnMethod(Method onreturnMethod) {
|
||||
this.onreturnMethod = onreturnMethod;
|
||||
}
|
||||
|
||||
public Object getOnthrowInstance() {
|
||||
return onthrowInstance;
|
||||
}
|
||||
|
||||
public void setOnthrowInstance(Object onthrowInstance) {
|
||||
this.onthrowInstance = onthrowInstance;
|
||||
}
|
||||
|
||||
public Method getOnthrowMethod() {
|
||||
return onthrowMethod;
|
||||
}
|
||||
|
||||
public void setOnthrowMethod(Method onthrowMethod) {
|
||||
this.onthrowMethod = onthrowMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,83 +16,59 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Consumer Model which is about subscribed services.
|
||||
* This model is bind to your reference's configuration, for example, group, version or method level configuration.
|
||||
*/
|
||||
public class ConsumerModel {
|
||||
private final ServiceMetadata serviceMetadata;
|
||||
private final Map<Method, ConsumerMethodModel> methodModels = new IdentityHashMap<Method, ConsumerMethodModel>();
|
||||
private final String serviceKey;
|
||||
private final Object proxyObject;
|
||||
private final ServiceModel serviceModel;
|
||||
private final Map<String, AsyncMethodInfo> methodConfigs = new HashMap<>();
|
||||
|
||||
/**
|
||||
* This constructor create an instance of ConsumerModel and passed objects should not be null.
|
||||
* If service name, service instance, proxy object,methods should not be null. If these are null
|
||||
* then this constructor will throw {@link IllegalArgumentException}
|
||||
*
|
||||
* This constructor create an instance of ConsumerModel and passed objects should not be null.
|
||||
* If service name, service instance, proxy object,methods should not be null. If these are null
|
||||
* then this constructor will throw {@link IllegalArgumentException}
|
||||
* @param serviceKey Name of the service.
|
||||
* @param serviceInterfaceClass Service interface class.
|
||||
* @param proxyObject Proxy object.
|
||||
* @param attributes Attributes of methods.
|
||||
* @param metadata
|
||||
*/
|
||||
public ConsumerModel(Map<String, Object> attributes, ServiceMetadata metadata) {
|
||||
this.serviceMetadata = metadata;
|
||||
for (Method method : metadata.getServiceType().getMethods()) {
|
||||
methodModels.put(method, new ConsumerMethodModel(method, attributes));
|
||||
public ConsumerModel(String serviceKey
|
||||
, Class<?> serviceInterfaceClass
|
||||
, Object proxyObject
|
||||
, ServiceModel serviceModel
|
||||
, Map<String, Object> attributes) {
|
||||
|
||||
Assert.notEmptyString(serviceKey, "Service name can't be null or blank");
|
||||
Assert.notNull(serviceInterfaceClass, "Service interface class can't null");
|
||||
Assert.notNull(proxyObject, "Proxy object can't be null");
|
||||
|
||||
this.serviceKey = serviceKey;
|
||||
this.proxyObject = proxyObject;
|
||||
this.serviceModel = serviceModel;
|
||||
|
||||
if (CollectionUtils.isNotEmptyMap(attributes)) {
|
||||
attributes.forEach((method, object) -> {
|
||||
methodConfigs.put(method, (AsyncMethodInfo) object);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return serviceMetadata
|
||||
*/
|
||||
public ServiceMetadata getServiceMetadata() {
|
||||
return serviceMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return method model for the given method on consumer side
|
||||
*
|
||||
* @param method method object
|
||||
* @return method model
|
||||
*/
|
||||
public ConsumerMethodModel getMethodModel(Method method) {
|
||||
return methodModels.get(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return method model for the given method on consumer side
|
||||
*
|
||||
* @param method method object
|
||||
* @return method model
|
||||
*/
|
||||
public ConsumerMethodModel getMethodModel(String method) {
|
||||
Optional<Map.Entry<Method, ConsumerMethodModel>> consumerMethodModelEntry = methodModels.entrySet().stream().filter(entry -> entry.getKey().getName().equals(method)).findFirst();
|
||||
return consumerMethodModelEntry.map(Map.Entry::getValue).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param method metodName
|
||||
* @param argsType method arguments type
|
||||
* Return the proxy object used by called while creating instance of ConsumerModel
|
||||
* @return
|
||||
*/
|
||||
public ConsumerMethodModel getMethodModel(String method, String[] argsType) {
|
||||
Optional<ConsumerMethodModel> consumerMethodModel = methodModels.entrySet().stream()
|
||||
.filter(entry -> entry.getKey().getName().equals(method))
|
||||
.map(Map.Entry::getValue).filter(methodModel -> Arrays.equals(argsType, methodModel.getParameterTypes()))
|
||||
.findFirst();
|
||||
return consumerMethodModel.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return serviceMetadata.getServiceType();
|
||||
public Object getProxyObject() {
|
||||
return proxyObject;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,20 +76,91 @@ public class ConsumerModel {
|
|||
*
|
||||
* @return method model list
|
||||
*/
|
||||
public List<ConsumerMethodModel> getAllMethods() {
|
||||
return new ArrayList<ConsumerMethodModel>(methodModels.values());
|
||||
public Set<MethodModel> getAllMethods() {
|
||||
return serviceModel.getAllMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the proxy object used by called while creating instance of ConsumerModel
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Object getProxyObject() {
|
||||
return this.serviceMetadata.getTarget();
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return serviceModel.getServiceInterfaceClass();
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return this.serviceMetadata.getServiceKey();
|
||||
public String getServiceKey() {
|
||||
return serviceKey;
|
||||
}
|
||||
|
||||
public AsyncMethodInfo getMethodConfig(String methodName) {
|
||||
return methodConfigs.get(methodName);
|
||||
}
|
||||
|
||||
public ServiceModel getServiceModel() {
|
||||
return serviceModel;
|
||||
}
|
||||
|
||||
public static class AsyncMethodInfo {
|
||||
// callback instance when async-call is invoked
|
||||
private Object oninvokeInstance;
|
||||
|
||||
// callback method when async-call is invoked
|
||||
private Method oninvokeMethod;
|
||||
|
||||
// callback instance when async-call is returned
|
||||
private Object onreturnInstance;
|
||||
|
||||
// callback method when async-call is returned
|
||||
private Method onreturnMethod;
|
||||
|
||||
// callback instance when async-call has exception thrown
|
||||
private Object onthrowInstance;
|
||||
|
||||
// callback method when async-call has exception thrown
|
||||
private Method onthrowMethod;
|
||||
|
||||
public Object getOninvokeInstance() {
|
||||
return oninvokeInstance;
|
||||
}
|
||||
|
||||
public void setOninvokeInstance(Object oninvokeInstance) {
|
||||
this.oninvokeInstance = oninvokeInstance;
|
||||
}
|
||||
|
||||
public Method getOninvokeMethod() {
|
||||
return oninvokeMethod;
|
||||
}
|
||||
|
||||
public void setOninvokeMethod(Method oninvokeMethod) {
|
||||
this.oninvokeMethod = oninvokeMethod;
|
||||
}
|
||||
|
||||
public Object getOnreturnInstance() {
|
||||
return onreturnInstance;
|
||||
}
|
||||
|
||||
public void setOnreturnInstance(Object onreturnInstance) {
|
||||
this.onreturnInstance = onreturnInstance;
|
||||
}
|
||||
|
||||
public Method getOnreturnMethod() {
|
||||
return onreturnMethod;
|
||||
}
|
||||
|
||||
public void setOnreturnMethod(Method onreturnMethod) {
|
||||
this.onreturnMethod = onreturnMethod;
|
||||
}
|
||||
|
||||
public Object getOnthrowInstance() {
|
||||
return onthrowInstance;
|
||||
}
|
||||
|
||||
public void setOnthrowInstance(Object onthrowInstance) {
|
||||
this.onthrowInstance = onthrowInstance;
|
||||
}
|
||||
|
||||
public Method getOnthrowMethod() {
|
||||
return onthrowMethod;
|
||||
}
|
||||
|
||||
public void setOnthrowMethod(Method onthrowMethod) {
|
||||
this.onthrowMethod = onthrowMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,61 +16,68 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class ProviderMethodModel {
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MethodModel {
|
||||
private final Method method;
|
||||
private final String methodName;
|
||||
// private final boolean isCallBack;
|
||||
// private final boolean isFuture;
|
||||
private final String paramDesc;
|
||||
private final Class<?>[] parameterClasses;
|
||||
private final String[] methodArgTypes;
|
||||
private final Type[] genericParameterTypes;
|
||||
private final ConcurrentMap<String, Object> attributeMap = new ConcurrentHashMap<>();
|
||||
private final Class<?> returnClass;
|
||||
private final Type[] returnTypes;
|
||||
private final String methodName;
|
||||
private final boolean generic;
|
||||
|
||||
public ProviderMethodModel(Method method) {
|
||||
public MethodModel (Method method) {
|
||||
this.method = method;
|
||||
this.methodName = method.getName();
|
||||
this.parameterClasses = method.getParameterTypes();
|
||||
this.methodArgTypes = getArgTypes(method);
|
||||
this.genericParameterTypes = method.getGenericParameterTypes();
|
||||
this.returnClass = method.getReturnType();
|
||||
this.returnTypes = ReflectUtils.getReturnTypes(method);
|
||||
this.paramDesc = ReflectUtils.getDesc(method);
|
||||
this.methodName = method.getName();
|
||||
this.generic = (methodName.equals($INVOKE) || methodName.equals($INVOKE_ASYNC)) && parameterClasses.length == 3;
|
||||
}
|
||||
|
||||
public boolean matchParams (String params) {
|
||||
return paramDesc.equalsIgnoreCase(params);
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public String[] getMethodArgTypes() {
|
||||
return methodArgTypes;
|
||||
}
|
||||
|
||||
public ConcurrentMap<String, Object> getAttributeMap() {
|
||||
return attributeMap;
|
||||
}
|
||||
|
||||
private static String[] getArgTypes(Method method) {
|
||||
String[] methodArgTypes = new String[0];
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes.length > 0) {
|
||||
methodArgTypes = new String[parameterTypes.length];
|
||||
int index = 0;
|
||||
for (Class<?> paramType : parameterTypes) {
|
||||
methodArgTypes[index++] = paramType.getName();
|
||||
}
|
||||
}
|
||||
return methodArgTypes;
|
||||
public String getParamDesc() {
|
||||
return paramDesc;
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterClasses() {
|
||||
return parameterClasses;
|
||||
}
|
||||
|
||||
public Type[] getGenericParameterTypes() {
|
||||
return genericParameterTypes;
|
||||
public Class<?> getReturnClass() {
|
||||
return returnClass;
|
||||
}
|
||||
|
||||
public Type[] getReturnTypes() {
|
||||
return returnTypes;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public boolean isGeneric() {
|
||||
return generic;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,99 +16,43 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* ProviderModel which is about published services
|
||||
*/
|
||||
public class ProviderModel {
|
||||
private final String serviceKey;
|
||||
private final Object serviceInstance;
|
||||
private final ServiceMetadata serviceMetadata;
|
||||
private final String serivceKey;
|
||||
private final Map<String, List<ProviderMethodModel>> methods = new HashMap<String, List<ProviderMethodModel>>();
|
||||
private final ServiceModel serviceModel;
|
||||
|
||||
public ProviderModel(String serviceName, String group, String version, Object serviceInstance, Class<?> serviceInterfaceClass) {
|
||||
public ProviderModel(String serviceKey, Object serviceInstance, ServiceModel serviceModel) {
|
||||
if (null == serviceInstance) {
|
||||
throw new IllegalArgumentException("Service[" + serviceName + "]Target is NULL.");
|
||||
throw new IllegalArgumentException("Service[" + serviceKey + "]Target is NULL.");
|
||||
}
|
||||
|
||||
this.serviceKey = serviceKey;
|
||||
this.serviceInstance = serviceInstance;
|
||||
this.serviceMetadata = new ServiceMetadata(serviceName, group, version, serviceInterfaceClass);
|
||||
this.serivceKey = serviceMetadata.getServiceKey();
|
||||
initMethod(serviceInterfaceClass);
|
||||
this.serviceModel = serviceModel;
|
||||
}
|
||||
|
||||
public ProviderModel(Object serviceInstance, ServiceMetadata serviceMetadata) {
|
||||
this.serviceInstance = serviceInstance;
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
this.serivceKey = serviceMetadata.getServiceKey();
|
||||
initMethod(serviceMetadata.getServiceType());
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return this.serviceMetadata.getServiceKey();
|
||||
public String getServiceKey() {
|
||||
return serviceKey;
|
||||
}
|
||||
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return this.serviceMetadata.getServiceType();
|
||||
return serviceModel.getServiceInterfaceClass();
|
||||
}
|
||||
|
||||
public Object getServiceInstance() {
|
||||
return serviceInstance;
|
||||
}
|
||||
|
||||
public List<ProviderMethodModel> getAllMethods() {
|
||||
List<ProviderMethodModel> result = new ArrayList<ProviderMethodModel>();
|
||||
for (List<ProviderMethodModel> models : methods.values()) {
|
||||
result.addAll(models);
|
||||
}
|
||||
return result;
|
||||
public Set<MethodModel> getAllMethods() {
|
||||
return serviceModel.getAllMethods();
|
||||
}
|
||||
|
||||
public ProviderMethodModel getMethodModel(String methodName, String[] argTypes) {
|
||||
List<ProviderMethodModel> methodModels = methods.get(methodName);
|
||||
if (methodModels != null) {
|
||||
for (ProviderMethodModel methodModel : methodModels) {
|
||||
if (Arrays.equals(argTypes, methodModel.getMethodArgTypes())) {
|
||||
return methodModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ProviderMethodModel> getMethodModelList(String methodName) {
|
||||
List<ProviderMethodModel> resultList = methods.get(methodName);
|
||||
return resultList == null ? Collections.emptyList() : resultList;
|
||||
}
|
||||
|
||||
|
||||
private void initMethod(Class<?> serviceInterfaceClass) {
|
||||
Method[] methodsToExport;
|
||||
methodsToExport = serviceInterfaceClass.getMethods();
|
||||
|
||||
for (Method method : methodsToExport) {
|
||||
method.setAccessible(true);
|
||||
|
||||
List<ProviderMethodModel> methodModels = methods.get(method.getName());
|
||||
if (methodModels == null) {
|
||||
methodModels = new ArrayList<ProviderMethodModel>();
|
||||
methods.put(method.getName(), methodModels);
|
||||
}
|
||||
methodModels.add(new ProviderMethodModel(method));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return serviceMetadata
|
||||
*/
|
||||
public ServiceMetadata getServiceMetadata() {
|
||||
return serviceMetadata;
|
||||
public ServiceModel getServiceModel() {
|
||||
return serviceModel;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class ServiceModel {
|
||||
private final String serviceName;
|
||||
private final Class<?> serviceInterfaceClass;
|
||||
// to accelarate search
|
||||
private final Map<String, Set<MethodModel>> methods = new HashMap<>();
|
||||
private final Map<String, Map<String, MethodModel>> descToMethods = new HashMap<>();
|
||||
|
||||
public ServiceModel (Class<?> interfaceClass) {
|
||||
this.serviceInterfaceClass = interfaceClass;
|
||||
this.serviceName = interfaceClass.getName();
|
||||
initMethods();
|
||||
}
|
||||
|
||||
private void initMethods() {
|
||||
Method[] methodsToExport = null;
|
||||
methodsToExport = this.serviceInterfaceClass.getMethods();
|
||||
|
||||
for (Method method : methodsToExport) {
|
||||
method.setAccessible(true);
|
||||
|
||||
Set<MethodModel> methodModels = methods.computeIfAbsent(method.getName(), (k) ->new HashSet<>(1));
|
||||
methodModels.add(new MethodModel(method));
|
||||
}
|
||||
|
||||
methods.forEach((methodName, methodList) -> {
|
||||
Map<String, MethodModel> descMap = descToMethods.computeIfAbsent(methodName, k -> new HashMap<>());
|
||||
methodList.forEach(methodModel -> descMap.put(methodModel.getParamDesc(), methodModel));
|
||||
|
||||
// Map<Class<?>[], MethodModel> typesMap = typeToMethods.computeIfAbsent(methodName, k -> new HashMap<>());
|
||||
// methodList.forEach(methodModel -> typesMap.put(methodModel.getParameterClasses(), methodModel));
|
||||
});
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return serviceInterfaceClass;
|
||||
}
|
||||
|
||||
public Set<MethodModel> getAllMethods () {
|
||||
Set<MethodModel> methodModels = new HashSet<>();
|
||||
methods.forEach((k, v) -> methodModels.addAll(v));
|
||||
return methodModels;
|
||||
}
|
||||
|
||||
public Optional<MethodModel> getMethod (String methodName, String params) {
|
||||
Map<String, MethodModel> methods = descToMethods.get(methodName);
|
||||
if (CollectionUtils.isNotEmptyMap(methods)) {
|
||||
return Optional.ofNullable(methods.get(params));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<MethodModel> getMethod (String methodName, Class<?>[] paramTypes) {
|
||||
Set<MethodModel> methodModels = methods.get(methodName);
|
||||
if (CollectionUtils.isNotEmpty(methodModels)) {
|
||||
for (MethodModel methodModel : methodModels) {
|
||||
if (Arrays.equals(paramTypes, methodModel.getParameterClasses())) {
|
||||
return Optional.of(methodModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Set<MethodModel> getMethods (String methodName) {
|
||||
return methods.get(methodName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import org.apache.dubbo.common.utils.ArrayUtils;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.rpc.FutureAdapter;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.InvokeMode;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
|
@ -34,7 +35,6 @@ import org.apache.dubbo.rpc.Result;
|
|||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
|
@ -55,21 +55,21 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
|
|||
|
||||
private final URL url;
|
||||
|
||||
private final Map<String, Object> attachment;
|
||||
private final Map<String, String> attachment;
|
||||
|
||||
private volatile boolean available = true;
|
||||
|
||||
private AtomicBoolean destroyed = new AtomicBoolean(false);
|
||||
|
||||
public AbstractInvoker(Class<T> type, URL url) {
|
||||
this(type, url, (Map<String, Object>) null);
|
||||
this(type, url, (Map<String, String>) null);
|
||||
}
|
||||
|
||||
public AbstractInvoker(Class<T> type, URL url, String[] keys) {
|
||||
this(type, url, convertAttachment(url, keys));
|
||||
}
|
||||
|
||||
public AbstractInvoker(Class<T> type, URL url, Map<String, Object> attachment) {
|
||||
public AbstractInvoker(Class<T> type, URL url, Map<String, String> attachment) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("service type == null");
|
||||
}
|
||||
|
|
@ -81,11 +81,11 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
|
|||
this.attachment = attachment == null ? null : Collections.unmodifiableMap(attachment);
|
||||
}
|
||||
|
||||
private static Map<String, Object> convertAttachment(URL url, String[] keys) {
|
||||
private static Map<String, String> convertAttachment(URL url, String[] keys) {
|
||||
if (ArrayUtils.isEmpty(keys)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> attachment = new HashMap<String, Object>();
|
||||
Map<String, String> attachment = new HashMap<String, String>();
|
||||
for (String key : keys) {
|
||||
String value = url.getParameter(key);
|
||||
if (value != null && value.length() > 0) {
|
||||
|
|
@ -143,11 +143,11 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
|
|||
if (CollectionUtils.isNotEmptyMap(attachment)) {
|
||||
invocation.addAttachmentsIfAbsent(attachment);
|
||||
}
|
||||
Map<String, Object> contextAttachments = RpcContext.getContext().getAttachments();
|
||||
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
|
||||
if (CollectionUtils.isNotEmptyMap(contextAttachments)) {
|
||||
/**
|
||||
* invocation.addAttachmentsIfAbsent(context){@link RpcInvocation#addAttachmentsIfAbsent(Map)}should not be used here,
|
||||
* because the {@link RpcContext#setAttachment(String, Object)} is passed in the Filter when the call is triggered
|
||||
* because the {@link RpcContext#setAttachment(String, String)} is passed in the Filter when the call is triggered
|
||||
* by the built-in retry mechanism of the Dubbo. The attachment to update RpcContext will no longer work, which is
|
||||
* a mistake in most cases (for example, through Filter to RpcContext output traceId and spanId and other information).
|
||||
*/
|
||||
|
|
@ -179,12 +179,12 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
|
|||
} catch (Throwable e) {
|
||||
asyncResult = AsyncRpcResult.newDefaultAsyncResult(null, e, invocation);
|
||||
}
|
||||
RpcContext.getContext().setFuture(new FutureAdapter(asyncResult));
|
||||
RpcContext.getContext().setFuture(new FutureAdapter(asyncResult.getResponseFuture()));
|
||||
return asyncResult;
|
||||
}
|
||||
|
||||
protected ExecutorService getCallbackExecutor(URL url, Invocation inv) {
|
||||
ExecutorService sharedExecutor = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension().createExecutorIfAbsent(url);
|
||||
ExecutorService sharedExecutor = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension().getExecutor(url);
|
||||
if (InvokeMode.SYNC == RpcUtils.getInvokeMode(getUrl(), inv)) {
|
||||
return new ThreadlessExecutor(sharedExecutor);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -83,8 +83,7 @@ public abstract class AbstractProxyInvoker<T> implements Invoker<T> {
|
|||
try {
|
||||
Object value = doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
|
||||
CompletableFuture<Object> future = wrapWithFuture(value, invocation);
|
||||
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation);
|
||||
future.whenComplete((obj, t) -> {
|
||||
CompletableFuture<AppResponse> appResponseFuture = future.handle((obj, t) -> {
|
||||
AppResponse result = new AppResponse();
|
||||
if (t != null) {
|
||||
if (t instanceof CompletionException) {
|
||||
|
|
@ -95,9 +94,9 @@ public abstract class AbstractProxyInvoker<T> implements Invoker<T> {
|
|||
} else {
|
||||
result.setValue(obj);
|
||||
}
|
||||
asyncRpcResult.complete(result);
|
||||
return result;
|
||||
});
|
||||
return asyncRpcResult;
|
||||
return new AsyncRpcResult(appResponseFuture, invocation);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (RpcContext.getContext().isAsyncStarted() && !RpcContext.getContext().stopAsync()) {
|
||||
logger.error("Provider async started, but got an exception from the original method, cannot write the exception back to consumer because an async result may have returned the new thread.", e);
|
||||
|
|
|
|||
|
|
@ -38,20 +38,20 @@ public class InvokerInvocationHandler implements InvocationHandler {
|
|||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (method.getDeclaringClass() == Object.class) {
|
||||
return method.invoke(invoker, args);
|
||||
}
|
||||
if ("toString".equals(methodName) && parameterTypes.length == 0) {
|
||||
return invoker.toString();
|
||||
}
|
||||
if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
|
||||
return invoker.hashCode();
|
||||
}
|
||||
if ("equals".equals(methodName) && parameterTypes.length == 1) {
|
||||
return invoker.equals(args[0]);
|
||||
}
|
||||
// Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
// if (method.getDeclaringClass() == Object.class) {
|
||||
// return method.invoke(invoker, args);
|
||||
// }
|
||||
// if ("toString".equals(methodName) && parameterTypes.length == 0) {
|
||||
// return invoker.toString();
|
||||
// }
|
||||
// if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
|
||||
// return invoker.hashCode();
|
||||
// }
|
||||
// if ("equals".equals(methodName) && parameterTypes.length == 1) {
|
||||
// return invoker.equals(args[0]);
|
||||
// }
|
||||
|
||||
return invoker.invoke(new RpcInvocation(method, args)).recreate();
|
||||
return invoker.invoke(new RpcInvocation(method, invoker.getInterface().getName(), args)).recreate();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.FAIL_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.FORCE_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.RETURN_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
|
||||
|
||||
final public class MockInvoker<T> implements Invoker<T> {
|
||||
private final static ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
|
||||
|
|
@ -95,10 +95,13 @@ final public class MockInvoker<T> implements Invoker<T> {
|
|||
|
||||
@Override
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
String mock = getUrl().getParameter(invocation.getMethodName() + "." + MOCK_KEY);
|
||||
if (invocation instanceof RpcInvocation) {
|
||||
((RpcInvocation) invocation).setInvoker(this);
|
||||
}
|
||||
String mock = null;
|
||||
if (getUrl().hasMethodParameter(invocation.getMethodName())) {
|
||||
mock = getUrl().getParameter(invocation.getMethodName() + "." + MOCK_KEY);
|
||||
}
|
||||
if (StringUtils.isBlank(mock)) {
|
||||
mock = getUrl().getParameter(MOCK_KEY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ import java.lang.reflect.Type;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE_ASYNC;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
|
||||
import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.ID_KEY;
|
||||
|
|
@ -168,7 +168,12 @@ public class RpcUtils {
|
|||
}
|
||||
|
||||
public static boolean isReturnTypeFuture(Invocation inv) {
|
||||
Class<?> clazz = getReturnType(inv);
|
||||
Class<?> clazz;
|
||||
if (inv instanceof RpcInvocation) {
|
||||
clazz = ((RpcInvocation) inv).getReturnType();
|
||||
} else {
|
||||
clazz = getReturnType(inv);
|
||||
}
|
||||
return (clazz != null && CompletableFuture.class.isAssignableFrom(clazz)) || isGenericAsync(inv);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import org.apache.dubbo.rpc.support.DemoService;
|
|||
import org.apache.dubbo.rpc.support.LocalException;
|
||||
|
||||
import com.alibaba.com.caucho.hessian.HessianException;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
|
@ -52,7 +51,7 @@ public class ExceptionFilterTest {
|
|||
RpcException exception = new RpcException("TestRpcException");
|
||||
|
||||
ExceptionFilter exceptionFilter = new ExceptionFilter();
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
Invoker<DemoService> invoker = mock(Invoker.class);
|
||||
given(invoker.getInterface()).willReturn(DemoService.class);
|
||||
given(invoker.invoke(eq(invocation))).willThrow(exception);
|
||||
|
|
@ -76,7 +75,7 @@ public class ExceptionFilterTest {
|
|||
public void testJavaException() {
|
||||
|
||||
ExceptionFilter exceptionFilter = new ExceptionFilter();
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
|
||||
AppResponse appResponse = new AppResponse();
|
||||
appResponse.setException(new IllegalArgumentException("java"));
|
||||
|
|
@ -96,7 +95,7 @@ public class ExceptionFilterTest {
|
|||
public void testRuntimeException() {
|
||||
|
||||
ExceptionFilter exceptionFilter = new ExceptionFilter();
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
|
||||
AppResponse appResponse = new AppResponse();
|
||||
appResponse.setException(new LocalException("localException"));
|
||||
|
|
@ -116,7 +115,7 @@ public class ExceptionFilterTest {
|
|||
public void testConvertToRunTimeException() throws Exception {
|
||||
|
||||
ExceptionFilter exceptionFilter = new ExceptionFilter();
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
RpcInvocation invocation = new RpcInvocation("sayHello", DemoService.class.getName(), new Class<?>[]{String.class}, new Object[]{"world"});
|
||||
|
||||
AppResponse mockRpcResult = new AppResponse();
|
||||
mockRpcResult.setException(new HessianException("hessian"));
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ import java.lang.reflect.Method;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_NATIVE_JAVA;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_NATIVE_JAVA;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
|
||||
public class GenericFilterTest {
|
||||
GenericFilter genericFilter = new GenericFilter();
|
||||
|
|
@ -54,7 +54,7 @@ public class GenericFilterTest {
|
|||
person.put("name", "dubbo");
|
||||
person.put("age", 10);
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, genericInvoke.getParameterTypes(),
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, GenericService.class.getName(), genericInvoke.getParameterTypes(),
|
||||
new Object[]{"getPerson", new String[]{Person.class.getCanonicalName()}, new Object[]{person}});
|
||||
|
||||
URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
|
||||
|
|
@ -82,7 +82,7 @@ public class GenericFilterTest {
|
|||
person.put("name", "dubbo");
|
||||
person.put("age", 10);
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, genericInvoke.getParameterTypes(),
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, GenericService.class.getName(), genericInvoke.getParameterTypes(),
|
||||
new Object[]{"getPerson", new String[]{Person.class.getCanonicalName()}, new Object[]{person}});
|
||||
invocation.setAttachment(GENERIC_KEY, GENERIC_SERIALIZATION_NATIVE_JAVA);
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ public class GenericFilterTest {
|
|||
person.put("name", "dubbo");
|
||||
person.put("age", 10);
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation("sayHi", genericInvoke.getParameterTypes()
|
||||
RpcInvocation invocation = new RpcInvocation("sayHi", GenericService.class.getName(), genericInvoke.getParameterTypes()
|
||||
, new Object[]{"getPerson", new String[]{Person.class.getCanonicalName()}, new Object[]{person}});
|
||||
|
||||
URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
|
||||
|
|
@ -130,7 +130,7 @@ public class GenericFilterTest {
|
|||
person.put("name", "dubbo");
|
||||
person.put("age", 10);
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, genericInvoke.getParameterTypes()
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, GenericService.class.getName(), genericInvoke.getParameterTypes()
|
||||
, new Object[]{"getPerson", new String[]{Person.class.getCanonicalName()}});
|
||||
|
||||
URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
|
||||
|
|
|
|||
|
|
@ -36,12 +36,11 @@ import java.lang.reflect.Method;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
|
||||
|
||||
public class GenericImplFilterTest {
|
||||
|
||||
private GenericImplFilter genericImplFilter = new GenericImplFilter();
|
||||
|
|
@ -49,7 +48,7 @@ public class GenericImplFilterTest {
|
|||
@Test
|
||||
public void testInvoke() throws Exception {
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation("getPerson",
|
||||
RpcInvocation invocation = new RpcInvocation("getPerson", "org.apache.dubbo.rpc.support.DemoService",
|
||||
new Class[]{Person.class}, new Object[]{new Person("dubbo", 10)});
|
||||
|
||||
|
||||
|
|
@ -77,7 +76,7 @@ public class GenericImplFilterTest {
|
|||
@Test
|
||||
public void testInvokeWithException() throws Exception {
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation("getPerson",
|
||||
RpcInvocation invocation = new RpcInvocation("getPerson", "org.apache.dubbo.rpc.support.DemoService",
|
||||
new Class[]{Person.class}, new Object[]{new Person("dubbo", 10)});
|
||||
|
||||
URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
|
||||
|
|
@ -105,7 +104,7 @@ public class GenericImplFilterTest {
|
|||
person.put("name", "dubbo");
|
||||
person.put("age", 10);
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, genericInvoke.getParameterTypes(),
|
||||
RpcInvocation invocation = new RpcInvocation($INVOKE, GenericService.class.getName(), genericInvoke.getParameterTypes(),
|
||||
new Object[]{"getPerson", new String[]{Person.class.getCanonicalName()}, new Object[]{person}});
|
||||
|
||||
URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public abstract class AbstractProxyTest {
|
|||
//Assertions.assertEquals(proxy.toString(), invoker.toString());
|
||||
//Assertions.assertEquals(proxy.hashCode(), invoker.hashCode());
|
||||
|
||||
Assertions.assertEquals(invoker.invoke(new RpcInvocation("echo", new Class[]{String.class}, new Object[]{"aa"})).getValue()
|
||||
Assertions.assertEquals(invoker.invoke(new RpcInvocation("echo", DemoService.class.getName(), new Class[]{String.class}, new Object[]{"aa"})).getValue()
|
||||
, proxy.echo("aa"));
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ public abstract class AbstractProxyTest {
|
|||
|
||||
Assertions.assertEquals(invoker.getInterface(), DemoService.class);
|
||||
|
||||
Assertions.assertEquals(invoker.invoke(new RpcInvocation("echo", new Class[]{String.class}, new Object[]{"aa"})).getValue(),
|
||||
Assertions.assertEquals(invoker.invoke(new RpcInvocation("echo", DemoService.class.getName(), new Class[]{String.class}, new Object[]{"aa"})).getValue(),
|
||||
origin.echo("aa"));
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ public class MockInvocation implements Invocation {
|
|||
return "echo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
return "DemoService";
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return new Class[]{String.class};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import org.apache.dubbo.rpc.Invoker;
|
|||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* MockInvoker.java
|
||||
*/
|
||||
|
|
@ -67,7 +69,7 @@ public class MyInvoker<T> implements Invoker<T> {
|
|||
result.setException(new RuntimeException("mocked exception"));
|
||||
}
|
||||
|
||||
return AsyncRpcResult.newDefaultAsyncResult(result, invocation);
|
||||
return new AsyncRpcResult(CompletableFuture.completedFuture(result), invocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
|
@ -35,8 +37,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY;
|
||||
|
||||
public class RpcUtilsTest {
|
||||
|
||||
/**
|
||||
|
|
@ -48,7 +48,7 @@ public class RpcUtilsTest {
|
|||
URL url = URL.valueOf("dubbo://localhost/?test.async=true");
|
||||
Map<String, Object> attachments = new HashMap<String, Object>();
|
||||
attachments.put("aa", "bb");
|
||||
Invocation inv = new RpcInvocation("test", new Class[]{}, new String[]{}, attachments);
|
||||
Invocation inv = new RpcInvocation("test", "DemoService", new Class[]{}, new String[]{}, attachments);
|
||||
RpcUtils.attachInvocationIdIfAsync(url, inv);
|
||||
long id1 = RpcUtils.getInvocationId(inv);
|
||||
RpcUtils.attachInvocationIdIfAsync(url, inv);
|
||||
|
|
@ -65,7 +65,7 @@ public class RpcUtilsTest {
|
|||
@Test
|
||||
public void testAttachInvocationIdIfAsync_sync() {
|
||||
URL url = URL.valueOf("dubbo://localhost/");
|
||||
Invocation inv = new RpcInvocation("test", new Class[]{}, new String[]{});
|
||||
Invocation inv = new RpcInvocation("test", "DemoService", new Class[]{}, new String[]{});
|
||||
RpcUtils.attachInvocationIdIfAsync(url, inv);
|
||||
assertNull(RpcUtils.getInvocationId(inv));
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ public class RpcUtilsTest {
|
|||
@Test
|
||||
public void testAttachInvocationIdIfAsync_nullAttachments() {
|
||||
URL url = URL.valueOf("dubbo://localhost/?test.async=true");
|
||||
Invocation inv = new RpcInvocation("test", new Class[]{}, new String[]{});
|
||||
Invocation inv = new RpcInvocation("test", "DemoService", new Class[]{}, new String[]{});
|
||||
RpcUtils.attachInvocationIdIfAsync(url, inv);
|
||||
assertTrue(RpcUtils.getInvocationId(inv) >= 0L);
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ public class RpcUtilsTest {
|
|||
@Test
|
||||
public void testAttachInvocationIdIfAsync_forceNotAttache() {
|
||||
URL url = URL.valueOf("dubbo://localhost/?test.async=true&" + AUTO_ATTACH_INVOCATIONID_KEY + "=false");
|
||||
Invocation inv = new RpcInvocation("test", new Class[]{}, new String[]{});
|
||||
Invocation inv = new RpcInvocation("test", "DemoService", new Class[]{}, new String[]{});
|
||||
RpcUtils.attachInvocationIdIfAsync(url, inv);
|
||||
assertNull(RpcUtils.getInvocationId(inv));
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ public class RpcUtilsTest {
|
|||
@Test
|
||||
public void testAttachInvocationIdIfAsync_forceAttache() {
|
||||
URL url = URL.valueOf("dubbo://localhost/?" + AUTO_ATTACH_INVOCATIONID_KEY + "=true");
|
||||
Invocation inv = new RpcInvocation("test", new Class[]{}, new String[]{});
|
||||
Invocation inv = new RpcInvocation("test", "DemoService", new Class[]{}, new String[]{});
|
||||
RpcUtils.attachInvocationIdIfAsync(url, inv);
|
||||
assertNotNull(RpcUtils.getInvocationId(inv));
|
||||
}
|
||||
|
|
@ -109,40 +109,41 @@ public class RpcUtilsTest {
|
|||
@Test
|
||||
public void testGetReturnTypes() throws Exception {
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
String service = "org.apache.dubbo.rpc.support.DemoService";
|
||||
given(invoker.getUrl()).willReturn(URL.valueOf("test://127.0.0.1:1/org.apache.dubbo.rpc.support.DemoService?interface=org.apache.dubbo.rpc.support.DemoService"));
|
||||
Invocation inv = new RpcInvocation("testReturnType", new Class<?>[]{String.class}, null, null, invoker);
|
||||
Invocation inv = new RpcInvocation("testReturnType", service, new Class<?>[]{String.class}, null, null, invoker);
|
||||
|
||||
java.lang.reflect.Type[] types = RpcUtils.getReturnTypes(inv);
|
||||
Assertions.assertEquals(2, types.length);
|
||||
Assertions.assertEquals(String.class, types[0]);
|
||||
Assertions.assertEquals(String.class, types[1]);
|
||||
|
||||
Invocation inv1 = new RpcInvocation("testReturnType1", new Class<?>[]{String.class}, null, null, invoker);
|
||||
Invocation inv1 = new RpcInvocation("testReturnType1", service, new Class<?>[]{String.class}, null, null, invoker);
|
||||
java.lang.reflect.Type[] types1 = RpcUtils.getReturnTypes(inv1);
|
||||
Assertions.assertEquals(2, types1.length);
|
||||
Assertions.assertEquals(List.class, types1[0]);
|
||||
Assertions.assertEquals(DemoService.class.getMethod("testReturnType1", new Class<?>[]{String.class}).getGenericReturnType(), types1[1]);
|
||||
|
||||
Invocation inv2 = new RpcInvocation("testReturnType2", new Class<?>[]{String.class}, null, null, invoker);
|
||||
Invocation inv2 = new RpcInvocation("testReturnType2", service, new Class<?>[]{String.class}, null, null, invoker);
|
||||
java.lang.reflect.Type[] types2 = RpcUtils.getReturnTypes(inv2);
|
||||
Assertions.assertEquals(2, types2.length);
|
||||
Assertions.assertEquals(String.class, types2[0]);
|
||||
Assertions.assertEquals(String.class, types2[1]);
|
||||
|
||||
Invocation inv3 = new RpcInvocation("testReturnType3", new Class<?>[]{String.class}, null, null, invoker);
|
||||
Invocation inv3 = new RpcInvocation("testReturnType3", service, new Class<?>[]{String.class}, null, null, invoker);
|
||||
java.lang.reflect.Type[] types3 = RpcUtils.getReturnTypes(inv3);
|
||||
Assertions.assertEquals(2, types3.length);
|
||||
Assertions.assertEquals(List.class, types3[0]);
|
||||
java.lang.reflect.Type genericReturnType3 = DemoService.class.getMethod("testReturnType3", new Class<?>[]{String.class}).getGenericReturnType();
|
||||
Assertions.assertEquals(((ParameterizedType) genericReturnType3).getActualTypeArguments()[0], types3[1]);
|
||||
|
||||
Invocation inv4 = new RpcInvocation("testReturnType4", new Class<?>[]{String.class}, null, null, invoker);
|
||||
Invocation inv4 = new RpcInvocation("testReturnType4", service, new Class<?>[]{String.class}, null, null, invoker);
|
||||
java.lang.reflect.Type[] types4 = RpcUtils.getReturnTypes(inv4);
|
||||
Assertions.assertEquals(2, types4.length);
|
||||
Assertions.assertNull(types4[0]);
|
||||
Assertions.assertNull(types4[1]);
|
||||
|
||||
Invocation inv5 = new RpcInvocation("testReturnType5", new Class<?>[]{String.class}, null, null, invoker);
|
||||
Invocation inv5 = new RpcInvocation("testReturnType5", service, new Class<?>[]{String.class}, null, null, invoker);
|
||||
java.lang.reflect.Type[] types5 = RpcUtils.getReturnTypes(inv5);
|
||||
Assertions.assertEquals(2, types5.length);
|
||||
Assertions.assertEquals(Map.class, types5[0]);
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.CALLBACK_INSTANCES_LIMIT_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.DEFAULT_CALLBACK_INSTANCES;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_PROXY_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CHANNEL_CALLBACK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_PROXY_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CHANNEL_CALLBACK_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;
|
||||
|
||||
/**
|
||||
* callback service helper
|
||||
|
|
@ -65,7 +65,7 @@ class CallbackServiceCodec {
|
|||
private static byte isCallBack(URL url, String methodName, int argIndex) {
|
||||
// parameter callback rule: method-name.parameter-index(starting from 0).callback
|
||||
byte isCallback = CALLBACK_NONE;
|
||||
if (url != null) {
|
||||
if (url != null && url.hasMethodParameter(methodName)) {
|
||||
String callback = url.getParameter(methodName + "." + argIndex + ".callback");
|
||||
if (callback != null) {
|
||||
if ("true".equalsIgnoreCase(callback)) {
|
||||
|
|
|
|||
|
|
@ -72,16 +72,8 @@ class ChannelWrappedInvoker<T> extends AbstractInvoker<T> {
|
|||
currentClient.send(inv, getUrl().getMethodParameter(invocation.getMethodName(), SENT_KEY, false));
|
||||
return AsyncRpcResult.newDefaultAsyncResult(invocation);
|
||||
} else {
|
||||
CompletableFuture<Object> responseFuture = currentClient.request(inv);
|
||||
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(inv);
|
||||
responseFuture.whenComplete((appResponse, t) -> {
|
||||
if (t != null) {
|
||||
asyncRpcResult.completeExceptionally(t);
|
||||
} else {
|
||||
asyncRpcResult.complete((AppResponse) appResponse);
|
||||
}
|
||||
});
|
||||
return asyncRpcResult;
|
||||
CompletableFuture<AppResponse> appResponseFuture = currentClient.request(inv).thenApply(obj -> (AppResponse) obj);
|
||||
return new AsyncRpcResult(appResponseFuture, inv);
|
||||
}
|
||||
} catch (RpcException e) {
|
||||
throw e;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public interface Constants {
|
|||
|
||||
String DECODE_IN_IO_THREAD_KEY = "decode.in.io";
|
||||
|
||||
boolean DEFAULT_DECODE_IN_IO_THREAD = true;
|
||||
boolean DEFAULT_DECODE_IN_IO_THREAD = false;
|
||||
|
||||
/**
|
||||
* callback inst id
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import org.apache.dubbo.common.logger.LoggerFactory;
|
|||
import org.apache.dubbo.common.serialize.Cleanable;
|
||||
import org.apache.dubbo.common.serialize.ObjectInput;
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.remoting.Channel;
|
||||
import org.apache.dubbo.remoting.Codec;
|
||||
|
|
@ -30,17 +29,21 @@ import org.apache.dubbo.remoting.Decodeable;
|
|||
import org.apache.dubbo.remoting.exchange.Request;
|
||||
import org.apache.dubbo.remoting.transport.CodecSupport;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.MethodModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.decodeInvocationArgument;
|
||||
import static org.apache.dubbo.remoting.Constants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.decodeInvocationArgument;
|
||||
|
||||
public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Decodeable {
|
||||
|
||||
|
|
@ -97,27 +100,37 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec
|
|||
request.setVersion(dubboVersion);
|
||||
setAttachment(DUBBO_VERSION_KEY, dubboVersion);
|
||||
|
||||
setAttachment(PATH_KEY, in.readUTF());
|
||||
String path = in.readUTF();
|
||||
setAttachment(PATH_KEY, path);
|
||||
setAttachment(VERSION_KEY, in.readUTF());
|
||||
|
||||
setMethodName(in.readUTF());
|
||||
|
||||
String desc = in.readUTF();
|
||||
setParameterTypesDesc(desc);
|
||||
|
||||
try {
|
||||
Object[] args;
|
||||
Class<?>[] pts;
|
||||
String desc = in.readUTF();
|
||||
if (desc.length() == 0) {
|
||||
pts = DubboCodec.EMPTY_CLASS_ARRAY;
|
||||
args = DubboCodec.EMPTY_OBJECT_ARRAY;
|
||||
} else {
|
||||
pts = ReflectUtils.desc2classArray(desc);
|
||||
args = new Object[pts.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
try {
|
||||
args[i] = in.readObject(pts[i]);
|
||||
} catch (Exception e) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Decode argument failed: " + e.getMessage(), e);
|
||||
Object[] args = DubboCodec.EMPTY_OBJECT_ARRAY;
|
||||
Class<?>[] pts = DubboCodec.EMPTY_CLASS_ARRAY;
|
||||
if (desc.length() > 0) {
|
||||
// TODO, lambda function requires variables to be final.
|
||||
Optional<ServiceModel> serviceModel = ApplicationModel.getServiceModel(path);
|
||||
if (serviceModel.isPresent()) {
|
||||
Optional<MethodModel> methodOptional = serviceModel.get().getMethod(getMethodName(), desc);
|
||||
if (methodOptional.isPresent()) {
|
||||
pts = methodOptional.get().getParameterClasses();
|
||||
args = new Object[pts.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
try {
|
||||
args[i] = in.readObject(pts[i]);
|
||||
} catch (Exception e) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Decode argument failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setReturnTypes(methodOptional.get().getReturnTypes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,6 +145,7 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec
|
|||
attachment.putAll(map);
|
||||
setAttachments(attachment);
|
||||
}
|
||||
|
||||
//decode argument ,may be callback
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = decodeInvocationArgument(channel, this, pts, i, args[i]);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.apache.dubbo.remoting.exchange.Response;
|
|||
import org.apache.dubbo.remoting.transport.CodecSupport;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -38,6 +39,7 @@ import java.io.OutputStream;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class DecodeableRpcResult extends AppResponse implements Codec, Decodeable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DecodeableRpcResult.class);
|
||||
|
|
@ -125,7 +127,12 @@ public class DecodeableRpcResult extends AppResponse implements Codec, Decodeabl
|
|||
|
||||
private void handleValue(ObjectInput in) throws IOException {
|
||||
try {
|
||||
Type[] returnTypes = RpcUtils.getReturnTypes(invocation);
|
||||
Type[] returnTypes;
|
||||
if (invocation instanceof RpcInvocation) {
|
||||
returnTypes = ((RpcInvocation)invocation).getReturnTypes();
|
||||
} else {
|
||||
returnTypes = RpcUtils.getReturnTypes(invocation);
|
||||
}
|
||||
Object value = null;
|
||||
if (ArrayUtils.isEmpty(returnTypes)) {
|
||||
value = in.readObject();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.apache.dubbo.common.logger.Logger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.serialize.ObjectInput;
|
||||
import org.apache.dubbo.common.serialize.ObjectOutput;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.remoting.Channel;
|
||||
import org.apache.dubbo.remoting.exchange.Request;
|
||||
|
|
@ -179,7 +178,7 @@ public class DubboCodec extends ExchangeCodec {
|
|||
out.writeUTF((String) inv.getAttachment(VERSION_KEY));
|
||||
|
||||
out.writeUTF(inv.getMethodName());
|
||||
out.writeUTF(ReflectUtils.getDesc(inv.getParameterTypes()));
|
||||
out.writeUTF(inv.getParameterTypesDesc());
|
||||
Object[] args = inv.getArguments();
|
||||
if (args != null) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
|
|
|||
|
|
@ -93,12 +93,11 @@ public class DubboInvoker<T> extends AbstractInvoker<T> {
|
|||
currentClient.send(inv, isSent);
|
||||
return AsyncRpcResult.newDefaultAsyncResult(invocation);
|
||||
} else {
|
||||
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(inv);
|
||||
CompletableFuture<Object> responseFuture = currentClient.request(inv, timeout);
|
||||
asyncRpcResult.subscribeTo(responseFuture);
|
||||
CompletableFuture<AppResponse> appResponseFuture = currentClient.request(inv, timeout).thenApply(obj -> (AppResponse) obj);
|
||||
RpcContext.getContext().setFuture(new FutureAdapter(appResponseFuture));
|
||||
// save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter
|
||||
FutureContext.getContext().setCompatibleFuture(responseFuture);
|
||||
return asyncRpcResult;
|
||||
return new AsyncRpcResult(appResponseFuture, inv);
|
||||
}
|
||||
} catch (TimeoutException e) {
|
||||
throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -62,27 +62,27 @@ import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LAZY_CONNECT_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_CONNECT_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_DISCONNECT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.DEFAULT_HEARTBEAT;
|
||||
import static org.apache.dubbo.remoting.Constants.HEARTBEAT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CHANNEL_READONLYEVENT_SENT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.DEFAULT_HEARTBEAT;
|
||||
import static org.apache.dubbo.remoting.Constants.DEFAULT_REMOTING_CLIENT;
|
||||
import static org.apache.dubbo.remoting.Constants.HEARTBEAT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.DEFAULT_REMOTING_SERVER;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;
|
||||
import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.OPTIMIZER_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LAZY_CONNECT_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.STUB_EVENT_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.STUB_EVENT_METHODS_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.SHARE_CONNECTIONS_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_SHARE_CONNECTIONS;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_CONNECT_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_DISCONNECT_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.OPTIMIZER_KEY;
|
||||
import static org.apache.dubbo.rpc.protocol.dubbo.Constants.SHARE_CONNECTIONS_KEY;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -150,7 +150,7 @@ public class DubboProtocol extends AbstractProtocol {
|
|||
}
|
||||
RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());
|
||||
Result result = invoker.invoke(inv);
|
||||
return result.completionFuture().thenApply(Function.identity());
|
||||
return result.thenApply(Function.identity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -187,13 +187,22 @@ public class DubboProtocol extends AbstractProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME channel.getUrl() always binds to a fixed service, and this service is random.
|
||||
* we can choose to use a common service to carry onConnect event if there's no easy way to get the specific
|
||||
* service this connection is binding to.
|
||||
* @param channel
|
||||
* @param url
|
||||
* @param methodKey
|
||||
* @return
|
||||
*/
|
||||
private Invocation createInvocation(Channel channel, URL url, String methodKey) {
|
||||
String method = url.getParameter(methodKey);
|
||||
if (method == null || method.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation(method, new Class<?>[0], new Object[0]);
|
||||
RpcInvocation invocation = new RpcInvocation(method, url.getParameter(INTERFACE_KEY), new Class<?>[0], new Object[0]);
|
||||
invocation.setAttachment(PATH_KEY, url.getPath());
|
||||
invocation.setAttachment(GROUP_KEY, url.getParameter(GROUP_KEY));
|
||||
invocation.setAttachment(INTERFACE_KEY, url.getParameter(INTERFACE_KEY));
|
||||
|
|
|
|||
|
|
@ -26,13 +26,12 @@ import org.apache.dubbo.rpc.ListenableFilter;
|
|||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerMethodModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerModel;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.$INVOKE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
|
||||
/**
|
||||
* EventFilter
|
||||
|
|
@ -55,7 +54,7 @@ public class FutureFilter extends ListenableFilter {
|
|||
}
|
||||
|
||||
private void fireInvokeCallback(final Invoker<?> invoker, final Invocation invocation) {
|
||||
final ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
|
||||
final ConsumerModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
|
||||
if (asyncMethodInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -83,7 +82,7 @@ public class FutureFilter extends ListenableFilter {
|
|||
}
|
||||
|
||||
private void fireReturnCallback(final Invoker<?> invoker, final Invocation invocation, final Object result) {
|
||||
final ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
|
||||
final ConsumerModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
|
||||
if (asyncMethodInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -129,7 +128,7 @@ public class FutureFilter extends ListenableFilter {
|
|||
}
|
||||
|
||||
private void fireThrowCallback(final Invoker<?> invoker, final Invocation invocation, final Throwable exception) {
|
||||
final ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
|
||||
final ConsumerModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
|
||||
if (asyncMethodInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -175,7 +174,7 @@ public class FutureFilter extends ListenableFilter {
|
|||
}
|
||||
}
|
||||
|
||||
private ConsumerMethodModel.AsyncMethodInfo getAsyncMethodInfo(Invoker<?> invoker, Invocation invocation) {
|
||||
private ConsumerModel.AsyncMethodInfo getAsyncMethodInfo(Invoker<?> invoker, Invocation invocation) {
|
||||
final ConsumerModel consumerModel = ApplicationModel.getConsumerModel(invoker.getUrl().getServiceKey());
|
||||
if (consumerModel == null) {
|
||||
return null;
|
||||
|
|
@ -186,12 +185,7 @@ public class FutureFilter extends ListenableFilter {
|
|||
methodName = (String) invocation.getArguments()[0];
|
||||
}
|
||||
|
||||
ConsumerMethodModel methodModel = consumerModel.getMethodModel(methodName);
|
||||
if (methodModel == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = methodModel.getAsyncInfo();
|
||||
final ConsumerModel.AsyncMethodInfo asyncMethodInfo = consumerModel.getMethodConfig(methodName);
|
||||
if (asyncMethodInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.protocol.dubbo.status;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.status.Status;
|
||||
import org.apache.dubbo.common.status.StatusChecker;
|
||||
import org.apache.dubbo.common.store.DataStore;
|
||||
import org.apache.dubbo.remoting.Constants;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
|
@ -36,7 +36,7 @@ public class ThreadPoolStatusChecker implements StatusChecker {
|
|||
@Override
|
||||
public Status check() {
|
||||
DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
|
||||
Map<String, Object> executors = dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY);
|
||||
Map<String, Object> executors = dataStore.get(CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY);
|
||||
|
||||
StringBuilder msg = new StringBuilder();
|
||||
Status.Level level = Status.Level.OK;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.apache.dubbo.remoting.telnet.TelnetHandler;
|
|||
import org.apache.dubbo.remoting.telnet.support.Help;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderMethodModel;
|
||||
import org.apache.dubbo.rpc.model.MethodModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
|
@ -35,6 +35,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.utils.PojoUtils.realize;
|
||||
|
||||
|
|
@ -152,15 +153,15 @@ public class InvokeTelnetHandler implements TelnetHandler {
|
|||
|
||||
|
||||
private boolean isServiceMatch(String service, ProviderModel provider) {
|
||||
return provider.getServiceName().equalsIgnoreCase(service)
|
||||
return provider.getServiceKey().equalsIgnoreCase(service)
|
||||
|| provider.getServiceInterfaceClass().getSimpleName().equalsIgnoreCase(service)
|
||||
|| provider.getServiceInterfaceClass().getName().equalsIgnoreCase(service)
|
||||
|| StringUtils.isEmpty(service);
|
||||
}
|
||||
|
||||
private List<Method> findSameSignatureMethod(List<ProviderMethodModel> methods, String lookupMethodName, List<Object> args) {
|
||||
private List<Method> findSameSignatureMethod(Set<MethodModel> methods, String lookupMethodName, List<Object> args) {
|
||||
List<Method> sameSignatureMethods = new ArrayList<>();
|
||||
for (ProviderMethodModel model : methods) {
|
||||
for (MethodModel model : methods) {
|
||||
Method method = model.getMethod();
|
||||
if (method.getName().equals(lookupMethodName) && method.getParameterTypes().length == args.size()) {
|
||||
sameSignatureMethods.add(method);
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@ import org.apache.dubbo.remoting.Channel;
|
|||
import org.apache.dubbo.remoting.telnet.TelnetHandler;
|
||||
import org.apache.dubbo.remoting.telnet.support.Help;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerMethodModel;
|
||||
import org.apache.dubbo.rpc.model.ConsumerModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderMethodModel;
|
||||
import org.apache.dubbo.rpc.model.MethodModel;
|
||||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -87,11 +86,11 @@ public class ListTelnetHandler implements TelnetHandler {
|
|||
}
|
||||
|
||||
for (ProviderModel provider : ApplicationModel.allProviderModels()) {
|
||||
buf.append(provider.getServiceName());
|
||||
buf.append(provider.getServiceKey());
|
||||
if (detail) {
|
||||
buf.append(" -> ");
|
||||
buf.append(" published: ");
|
||||
buf.append(isRegistered(provider.getServiceName()) ? "Y" : "N");
|
||||
buf.append(isRegistered(provider.getServiceKey()) ? "Y" : "N");
|
||||
}
|
||||
buf.append("\r\n");
|
||||
}
|
||||
|
|
@ -103,11 +102,11 @@ public class ListTelnetHandler implements TelnetHandler {
|
|||
}
|
||||
|
||||
for (ConsumerModel consumer : ApplicationModel.allConsumerModels()) {
|
||||
buf.append(consumer.getServiceName());
|
||||
buf.append(consumer.getServiceKey());
|
||||
if (detail) {
|
||||
buf.append(" -> ");
|
||||
buf.append(" addresses: ");
|
||||
buf.append(getConsumerAddressNum(consumer.getServiceName()));
|
||||
buf.append(getConsumerAddressNum(consumer.getServiceKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -120,8 +119,8 @@ public class ListTelnetHandler implements TelnetHandler {
|
|||
private void printSpecifiedProvidedService(String service, StringBuilder buf, boolean detail) {
|
||||
for (ProviderModel provider : ApplicationModel.allProviderModels()) {
|
||||
if (isProviderMatched(service,provider)) {
|
||||
buf.append(provider.getServiceName()).append(" (as provider):\r\n");
|
||||
for (ProviderMethodModel method : provider.getAllMethods()) {
|
||||
buf.append(provider.getServiceKey()).append(" (as provider):\r\n");
|
||||
for (MethodModel method : provider.getAllMethods()) {
|
||||
printMethod(method.getMethod(), buf, detail);
|
||||
}
|
||||
}
|
||||
|
|
@ -131,8 +130,8 @@ public class ListTelnetHandler implements TelnetHandler {
|
|||
private void printSpecifiedReferredService(String service, StringBuilder buf, boolean detail) {
|
||||
for (ConsumerModel consumer : ApplicationModel.allConsumerModels()) {
|
||||
if (isConsumerMatcher(service,consumer)) {
|
||||
buf.append(consumer.getServiceName()).append(" (as consumer):\r\n");
|
||||
for (ConsumerMethodModel method : consumer.getAllMethods()) {
|
||||
buf.append(consumer.getServiceKey()).append(" (as consumer):\r\n");
|
||||
for (MethodModel method : consumer.getAllMethods()) {
|
||||
printMethod(method.getMethod(), buf, detail);
|
||||
}
|
||||
}
|
||||
|
|
@ -149,13 +148,13 @@ public class ListTelnetHandler implements TelnetHandler {
|
|||
}
|
||||
|
||||
private boolean isProviderMatched(String service, ProviderModel provider) {
|
||||
return service.equalsIgnoreCase(provider.getServiceName())
|
||||
return service.equalsIgnoreCase(provider.getServiceKey())
|
||||
|| service.equalsIgnoreCase(provider.getServiceInterfaceClass().getName())
|
||||
|| service.equalsIgnoreCase(provider.getServiceInterfaceClass().getSimpleName());
|
||||
}
|
||||
|
||||
private boolean isConsumerMatcher(String service,ConsumerModel consumer) {
|
||||
return service.equalsIgnoreCase(consumer.getServiceName())
|
||||
return service.equalsIgnoreCase(consumer.getServiceKey())
|
||||
|| service.equalsIgnoreCase(consumer.getServiceInterfaceClass().getName())
|
||||
|| service.equalsIgnoreCase(consumer.getServiceInterfaceClass().getSimpleName());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
|
||||
String result = invoke.telnet(mockChannel, "echo(\"ok\")");
|
||||
|
|
@ -84,8 +84,8 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
|
||||
String result = invoke.telnet(mockChannel, "DemoService.echo(\"ok\")");
|
||||
assertTrue(result.contains("result: \"ok\""));
|
||||
|
|
@ -99,9 +99,8 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
try {
|
||||
invoke.telnet(mockChannel, "sayHello(null)");
|
||||
} catch (Exception ex) {
|
||||
|
|
@ -116,8 +115,8 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
|
||||
String result = invoke.telnet(mockChannel, "getType(\"High\")");
|
||||
assertTrue(result.contains("result: \"High\""));
|
||||
|
|
@ -132,9 +131,8 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
String result = invoke.telnet(mockChannel, "getPerson({\"name\":\"zhangsan\",\"age\":12,\"class\":\"org.apache.dubbo.rpc.protocol.dubbo.support.Person\"})");
|
||||
assertTrue(result.contains("result: 12"));
|
||||
}
|
||||
|
|
@ -147,9 +145,8 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
String param = "{\"name\":\"Dubbo\",\"age\":8}";
|
||||
String result = invoke.telnet(mockChannel, "getPerson(" + param + ")");
|
||||
assertTrue(result.contains("Please use the select command to select the method you want to invoke. eg: select 1"));
|
||||
|
|
@ -165,9 +162,8 @@ public class InvokerTelnetHandlerTest {
|
|||
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
|
||||
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
ProviderModel providerModel = new ProviderModel(DemoService.class.getName(), new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel(DemoService.class.getName(), providerModel);
|
||||
String param = "{\"name\":\"Dubbo\",\"age\":8},{\"name\":\"Apache\",\"age\":20}";
|
||||
String result = invoke.telnet(mockChannel, "getPerson(" + param + ")");
|
||||
assertTrue(result.contains("result: 28"));
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import org.apache.dubbo.rpc.protocol.dubbo.support.DemoServiceImpl;
|
|||
import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -66,7 +66,7 @@ public class ListTelnetHandlerTest {
|
|||
mockChannel = mock(Channel.class);
|
||||
given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
String result = list.telnet(mockChannel, "-l DemoService");
|
||||
|
|
@ -80,7 +80,7 @@ public class ListTelnetHandlerTest {
|
|||
mockChannel = mock(Channel.class);
|
||||
given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
String result = list.telnet(mockChannel, "DemoService");
|
||||
|
|
@ -94,11 +94,11 @@ public class ListTelnetHandlerTest {
|
|||
mockChannel = mock(Channel.class);
|
||||
given(mockChannel.getAttribute("telnet.service")).willReturn(null);
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
String result = list.telnet(mockChannel, "");
|
||||
assertEquals("PROVIDER:\r\norg.apache.dubbo.rpc.protocol.dubbo.support.DemoService:1.0.0\r\n", result);
|
||||
assertEquals("PROVIDER:\r\norg.apache.dubbo.rpc.protocol.dubbo.support.DemoService\r\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -106,11 +106,11 @@ public class ListTelnetHandlerTest {
|
|||
mockChannel = mock(Channel.class);
|
||||
given(mockChannel.getAttribute("telnet.service")).willReturn(null);
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
String result = list.telnet(mockChannel, "-l");
|
||||
assertEquals("PROVIDER:\r\norg.apache.dubbo.rpc.protocol.dubbo.support.DemoService:1.0.0 -> published: N\r\n", result);
|
||||
assertEquals("PROVIDER:\r\norg.apache.dubbo.rpc.protocol.dubbo.support.DemoService -> published: N\r\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -118,12 +118,12 @@ public class ListTelnetHandlerTest {
|
|||
mockChannel = mock(Channel.class);
|
||||
given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
|
||||
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", "Dubbo", "1.0.0", new DemoServiceImpl(), DemoService.class);
|
||||
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), ApplicationModel.registerServiceModel(DemoService.class));
|
||||
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
|
||||
|
||||
String result = list.telnet(mockChannel, "");
|
||||
assertTrue(result.startsWith("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n" +
|
||||
"org.apache.dubbo.rpc.protocol.dubbo.support.DemoService:1.0.0 (as provider):\r\n"));
|
||||
"org.apache.dubbo.rpc.protocol.dubbo.support.DemoService (as provider):\r\n"));
|
||||
for (Method method : DemoService.class.getMethods()) {
|
||||
assertTrue(result.contains(method.getName()));
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue