You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/12/13 07:24:54 UTC
[dubbo] 13/14: Merge branch 'merge-3.x' into master-hsf
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch master-hsf
in repository https://gitbox.apache.org/repos/asf/dubbo.git
commit bfa059cd2b054caaaca34843074acaad17149d2e
Merge: 48ef064 a619be6
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Dec 12 15:46:25 2019 +0800
Merge branch 'merge-3.x' into master-hsf
# Conflicts:
# dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
# dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerMethodModel.java
# dubbo-compatible/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
# dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
# dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
# dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/ConfigChangeEvent.java
# dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
# dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java
# dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ConsumerModel.java
# dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
.../org/apache/dubbo/common/ServiceDescriptor.java | 16 ++--
.../dubbo/common/extension/ExtensionLoader.java | 45 ++++++++---
.../dubbo/common/extension/LoadingStrategy.java | 29 ++++++++
.../org/apache/dubbo/config/AbstractConfig.java | 7 +-
.../dubbo/rpc/model/ConsumerMethodModel.java | 48 +-----------
.../org/apache/dubbo/config/MethodConfigTest.java | 4 +-
.../org/apache/dubbo/qos/command/impl/Offline.java | 2 +-
.../org/apache/dubbo/qos/command/impl/Online.java | 4 +-
.../remoting/exchange/support/DefaultFuture.java | 23 +++---
.../apache/dubbo/rpc/model/AsyncMethodInfo.java | 87 ++++++++++++++++++++++
.../rpc/protocol/dubbo/filter/FutureFilter.java | 16 ++--
11 files changed, 186 insertions(+), 95 deletions(-)
diff --cc dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index 0babf10,0000000..b0a9400
mode 100644,000000..100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@@ -1,611 -1,0 +1,610 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.CompositeConfiguration;
+import org.apache.dubbo.common.config.Configuration;
+import org.apache.dubbo.common.config.Environment;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.MethodUtils;
+import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.config.context.ConfigConfigurationAdapter;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.support.Parameter;
- import org.apache.dubbo.rpc.model.ApplicationModel;
- import org.apache.dubbo.rpc.model.ConsumerModel;
++import org.apache.dubbo.rpc.model.AsyncMethodInfo;
+
+import javax.annotation.PostConstruct;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+import static org.apache.dubbo.common.utils.ReflectUtils.findMethodByMethodSignature;
+
+/**
+ * Utility methods and public methods for parsing configuration
+ *
+ * @export
+ */
+public abstract class AbstractConfig implements Serializable {
+
+ protected static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
+ private static final long serialVersionUID = 4267533505537413570L;
+
+ /**
+ * The legacy properties container
+ */
+ private static final Map<String, String> LEGACY_PROPERTIES = new HashMap<String, String>();
+
+ /**
+ * The suffix container
+ */
+ private static final String[] SUFFIXES = new String[]{"Config", "Bean", "ConfigBase"};
+
+ static {
+ LEGACY_PROPERTIES.put("dubbo.protocol.name", "dubbo.service.protocol");
+ LEGACY_PROPERTIES.put("dubbo.protocol.host", "dubbo.service.server.host");
+ LEGACY_PROPERTIES.put("dubbo.protocol.port", "dubbo.service.server.port");
+ LEGACY_PROPERTIES.put("dubbo.protocol.threads", "dubbo.service.max.thread.pool.size");
+ LEGACY_PROPERTIES.put("dubbo.consumer.timeout", "dubbo.service.invoke.timeout");
+ LEGACY_PROPERTIES.put("dubbo.consumer.retries", "dubbo.service.max.retry.providers");
+ LEGACY_PROPERTIES.put("dubbo.consumer.check", "dubbo.service.allow.no.provider");
+ LEGACY_PROPERTIES.put("dubbo.service.url", "dubbo.service.address");
+ }
+
+ /**
+ * The config id
+ */
+ protected String id;
+ protected String prefix;
+
+ protected final AtomicBoolean refreshed = new AtomicBoolean(false);
+
+ private static String convertLegacyValue(String key, String value) {
+ if (value != null && value.length() > 0) {
+ if ("dubbo.service.max.retry.providers".equals(key)) {
+ return String.valueOf(Integer.parseInt(value) - 1);
+ } else if ("dubbo.service.allow.no.provider".equals(key)) {
+ return String.valueOf(!Boolean.parseBoolean(value));
+ }
+ }
+ return value;
+ }
+
+ public static String getTagName(Class<?> cls) {
+ String tag = cls.getSimpleName();
+ for (String suffix : SUFFIXES) {
+ if (tag.endsWith(suffix)) {
+ tag = tag.substring(0, tag.length() - suffix.length());
+ break;
+ }
+ }
+ return StringUtils.camelToSplitName(tag, "-");
+ }
+
+ public static void appendParameters(Map<String, String> parameters, Object config) {
+ appendParameters(parameters, config, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void appendParameters(Map<String, String> parameters, Object config, String prefix) {
+ if (config == null) {
+ return;
+ }
+ Method[] methods = config.getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ String name = method.getName();
+ if (MethodUtils.isGetter(method)) {
+ Parameter parameter = method.getAnnotation(Parameter.class);
+ if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
+ continue;
+ }
+ String key;
+ if (parameter != null && parameter.key().length() > 0) {
+ key = parameter.key();
+ } else {
+ key = calculatePropertyFromGetter(name);
+ }
+ Object value = method.invoke(config);
+ String str = String.valueOf(value).trim();
+ if (value != null && str.length() > 0) {
+ if (parameter != null && parameter.escaped()) {
+ str = URL.encode(str);
+ }
+ if (parameter != null && parameter.append()) {
+ String pre = parameters.get(key);
+ if (pre != null && pre.length() > 0) {
+ str = pre + "," + str;
+ }
+ }
+ if (prefix != null && prefix.length() > 0) {
+ key = prefix + "." + key;
+ }
+ parameters.put(key, str);
+ } else if (parameter != null && parameter.required()) {
+ throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
+ }
+ } else if (isParametersGetter(method)) {
+ Map<String, String> map = (Map<String, String>) method.invoke(config, new Object[0]);
+ parameters.putAll(convert(map, prefix));
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ }
+
+ @Deprecated
+ protected static void appendAttributes(Map<String, Object> parameters, Object config) {
+ appendAttributes(parameters, config, null);
+ }
+
+ @Deprecated
+ protected static void appendAttributes(Map<String, Object> parameters, Object config, String prefix) {
+ if (config == null) {
+ return;
+ }
+ Method[] methods = config.getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ Parameter parameter = method.getAnnotation(Parameter.class);
+ if (parameter == null || !parameter.attribute()) {
+ continue;
+ }
+ String name = method.getName();
+ if (MethodUtils.isGetter(method)) {
+ String key;
+ if (parameter.key().length() > 0) {
+ key = parameter.key();
+ } else {
+ key = calculateAttributeFromGetter(name);
+ }
+ Object value = method.invoke(config);
+ if (value != null) {
+ if (prefix != null && prefix.length() > 0) {
+ key = prefix + "." + key;
+ }
+ parameters.put(key, value);
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ }
+
- public static ConsumerModel.AsyncMethodInfo convertMethodConfig2AsyncInfo(MethodConfig methodConfig) {
++ protected static AsyncMethodInfo convertMethodConfig2AsyncInfo(MethodConfig methodConfig) {
+ if (methodConfig == null || (methodConfig.getOninvoke() == null && methodConfig.getOnreturn() == null && methodConfig.getOnthrow() == null)) {
+ return null;
+ }
+
+ //check config conflict
+ if (Boolean.FALSE.equals(methodConfig.isReturn()) && (methodConfig.getOnreturn() != null || methodConfig.getOnthrow() != null)) {
+ throw new IllegalStateException("method config error : return attribute must be set true when onreturn or onthrow has been set.");
+ }
+
- ConsumerModel.AsyncMethodInfo asyncMethodInfo = new ConsumerModel.AsyncMethodInfo();
++ AsyncMethodInfo asyncMethodInfo = new AsyncMethodInfo();
+
+ asyncMethodInfo.setOninvokeInstance(methodConfig.getOninvoke());
+ asyncMethodInfo.setOnreturnInstance(methodConfig.getOnreturn());
+ asyncMethodInfo.setOnthrowInstance(methodConfig.getOnthrow());
+
+ try {
+ String oninvokeMethod = methodConfig.getOninvokeMethod();
+ if (StringUtils.isNotEmpty(oninvokeMethod)) {
+ asyncMethodInfo.setOninvokeMethod(getMethodByName(methodConfig.getOninvoke().getClass(), oninvokeMethod));
+ }
+
+ String onreturnMethod = methodConfig.getOnreturnMethod();
+ if (StringUtils.isNotEmpty(onreturnMethod)) {
+ asyncMethodInfo.setOnreturnMethod(getMethodByName(methodConfig.getOnreturn().getClass(), onreturnMethod));
+ }
+
+ String onthrowMethod = methodConfig.getOnthrowMethod();
+ if (StringUtils.isNotEmpty(onthrowMethod)) {
+ asyncMethodInfo.setOnthrowMethod(getMethodByName(methodConfig.getOnthrow().getClass(), onthrowMethod));
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+
+ return asyncMethodInfo;
+ }
+
+ private static Method getMethodByName(Class<?> clazz, String methodName) {
+ try {
+ return ReflectUtils.findMethodByMethodName(clazz, methodName);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ protected static Set<String> getSubProperties(Map<String, String> properties, String prefix) {
+ return properties.keySet().stream().filter(k -> k.contains(prefix)).map(k -> {
+ k = k.substring(prefix.length());
+ return k.substring(0, k.indexOf("."));
+ }).collect(Collectors.toSet());
+ }
+
+ private static String extractPropertyName(Class<?> clazz, Method setter) throws Exception {
+ String propertyName = setter.getName().substring("set".length());
+ Method getter = null;
+ try {
+ getter = clazz.getMethod("get" + propertyName);
+ } catch (NoSuchMethodException e) {
+ getter = clazz.getMethod("is" + propertyName);
+ }
+ Parameter parameter = getter.getAnnotation(Parameter.class);
+ if (parameter != null && StringUtils.isNotEmpty(parameter.key()) && parameter.useKeyAsProperty()) {
+ propertyName = parameter.key();
+ } else {
+ propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
+ }
+ return propertyName;
+ }
+
+ private static String calculatePropertyFromGetter(String name) {
+ int i = name.startsWith("get") ? 3 : 2;
+ return StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + name.substring(i + 1), ".");
+ }
+
+ private static String calculateAttributeFromGetter(String getter) {
+ int i = getter.startsWith("get") ? 3 : 2;
+ return getter.substring(i, i + 1).toLowerCase() + getter.substring(i + 1);
+ }
+
+ private static void invokeSetParameters(Class c, Object o, Map map) {
+ try {
+ Method method = findMethodByMethodSignature(c, "setParameters", new String[]{Map.class.getName()});
+ if (method != null && isParametersSetter(method)) {
+ method.invoke(o, map);
+ }
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+
+ private static Map<String, String> invokeGetParameters(Class c, Object o) {
+ try {
+ Method method = findMethodByMethodSignature(c, "getParameters", null);
+ if (method != null && isParametersGetter(method)) {
+ return (Map<String, String>) method.invoke(o);
+ }
+ } catch (Throwable t) {
+ // ignore
+ }
+ return null;
+ }
+
+ private static boolean isParametersGetter(Method method) {
+ String name = method.getName();
+ return ("getParameters".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && method.getReturnType() == Map.class);
+ }
+
+ private static boolean isParametersSetter(Method method) {
+ return ("setParameters".equals(method.getName())
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterCount() == 1
+ && Map.class == method.getParameterTypes()[0]
+ && method.getReturnType() == void.class);
+ }
+
+ private static Map<String, String> convert(Map<String, String> parameters, String prefix) {
+ if (parameters == null || parameters.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, String> result = new HashMap<>();
+ String pre = (prefix != null && prefix.length() > 0 ? prefix + "." : "");
+ for (Map.Entry<String, String> entry : parameters.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ result.put(pre + key, value);
+ // For compatibility, key like "registry-type" will has a duplicate key "registry.type"
+ if (key.contains("-")) {
+ result.put(pre + key.replace('-', '.'), value);
+ }
+ }
+ return result;
+ }
+
+ @Parameter(excluded = true)
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void updateIdIfAbsent(String value) {
+ if (StringUtils.isNotEmpty(value) && StringUtils.isEmpty(id)) {
+ this.id = value;
+ }
+ }
+
+ protected void appendAnnotation(Class<?> annotationClass, Object annotation) {
+ Method[] methods = annotationClass.getMethods();
+ for (Method method : methods) {
+ if (method.getDeclaringClass() != Object.class
+ && method.getReturnType() != void.class
+ && method.getParameterTypes().length == 0
+ && Modifier.isPublic(method.getModifiers())
+ && !Modifier.isStatic(method.getModifiers())) {
+ try {
+ String property = method.getName();
+ if ("interfaceClass".equals(property) || "interfaceName".equals(property)) {
+ property = "interface";
+ }
+ String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
+ Object value = method.invoke(annotation);
+ if (value != null && !value.equals(method.getDefaultValue())) {
+ Class<?> parameterType = ReflectUtils.getBoxedClass(method.getReturnType());
+ if ("filter".equals(property) || "listener".equals(property)) {
+ parameterType = String.class;
+ value = StringUtils.join((String[]) value, ",");
+ } else if ("parameters".equals(property)) {
+ parameterType = Map.class;
+ value = CollectionUtils.toStringMap((String[]) value);
+ }
+ try {
+ Method setterMethod = getClass().getMethod(setter, parameterType);
+ setterMethod.invoke(this, value);
+ } catch (NoSuchMethodException e) {
+ // ignore
+ }
+ }
+ } catch (Throwable e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Should be called after Config was fully initialized.
+ * // FIXME: this method should be completely replaced by appendParameters
+ *
+ * @return
+ * @see AbstractConfig#appendParameters(Map, Object, String)
+ * <p>
+ * Notice! This method should include all properties in the returning map, treat @Parameter differently compared to appendParameters.
+ */
+ public Map<String, String> getMetaData() {
+ Map<String, String> metaData = new HashMap<>();
+ Method[] methods = this.getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ String name = method.getName();
+ if (MethodUtils.isMetaMethod(method)) {
+ String key;
+ Parameter parameter = method.getAnnotation(Parameter.class);
+ if (parameter != null && parameter.key().length() > 0 && parameter.useKeyAsProperty()) {
+ key = parameter.key();
+ } else {
+ key = calculateAttributeFromGetter(name);
+ }
+ // treat url and configuration differently, the value should always present in configuration though it may not need to present in url.
+ //if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
+ if (method.getReturnType() == Object.class) {
+ metaData.put(key, null);
+ continue;
+ }
+
+ /**
+ * Attributes annotated as deprecated should not override newly added replacement.
+ */
+ if (MethodUtils.isDeprecated(method) && metaData.get(key) != null) {
+ continue;
+ }
+
+ Object value = method.invoke(this);
+ String str = String.valueOf(value).trim();
+ if (value != null && str.length() > 0) {
+ metaData.put(key, str);
+ } else {
+ metaData.put(key, null);
+ }
+ } else if (isParametersGetter(method)) {
+ Map<String, String> map = (Map<String, String>) method.invoke(this, new Object[0]);
+ metaData.putAll(convert(map, ""));
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ return metaData;
+ }
+
+ @Parameter(excluded = true)
+ public String getPrefix() {
+ return StringUtils.isNotEmpty(prefix) ? prefix : (CommonConstants.DUBBO + "." + getTagName(this.getClass()));
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public void refresh() {
+ Environment env = ApplicationModel.getEnvironment();
+ try {
+ CompositeConfiguration compositeConfiguration = env.getConfiguration(getPrefix(), getId());
+ Configuration config = new ConfigConfigurationAdapter(this);
+ if (env.isConfigCenterFirst()) {
+ // The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
+ compositeConfiguration.addConfiguration(4, config);
+ } else {
+ // The sequence would be: SystemConfiguration -> AbstractConfig -> AppExternalConfiguration -> ExternalConfiguration -> PropertiesConfiguration
+ compositeConfiguration.addConfiguration(2, config);
+ }
+
+ // loop methods, get override value and set the new value back to method
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods) {
+ if (MethodUtils.isSetter(method)) {
+ try {
+ String value = StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method)));
+ // isTypeMatch() is called to avoid duplicate and incorrect update, for example, we have two 'setGeneric' methods in ReferenceConfig.
+ if (StringUtils.isNotEmpty(value) && ClassUtils.isTypeMatch(method.getParameterTypes()[0], value)) {
+ method.invoke(this, ClassUtils.convertPrimitive(method.getParameterTypes()[0], value));
+ }
+ } catch (NoSuchMethodException e) {
+ logger.info("Failed to override the property " + method.getName() + " in " +
+ this.getClass().getSimpleName() +
+ ", please make sure every property has getter/setter method provided.");
+ }
+ } else if (isParametersSetter(method)) {
+ String value = StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method)));
+ if (StringUtils.isNotEmpty(value)) {
+ Map<String, String> map = invokeGetParameters(getClass(), this);
+ map = map == null ? new HashMap<>() : map;
+ map.putAll(convert(StringUtils.parseParameters(value), ""));
+ invokeSetParameters(getClass(), this, map);
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("Failed to override ", e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ try {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<dubbo:");
+ buf.append(getTagName(getClass()));
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ if (MethodUtils.isGetter(method)) {
+ String name = method.getName();
+ String key = calculateAttributeFromGetter(name);
+ Object value = method.invoke(this);
+ if (value != null) {
+ buf.append(" ");
+ buf.append(key);
+ buf.append("=\"");
+ buf.append(value);
+ buf.append("\"");
+ }
+ }
+ } catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+ buf.append(" />");
+ return buf.toString();
+ } catch (Throwable t) {
+ logger.warn(t.getMessage(), t);
+ return super.toString();
+ }
+ }
+
+ /**
+ * FIXME check @Parameter(required=true) and any conditions that need to match.
+ */
+ @Parameter(excluded = true)
+ public boolean isValid() {
+ return true;
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj.getClass().getName().equals(this.getClass().getName()))) {
+ return false;
+ }
+
+ Method[] methods = this.getClass().getMethods();
+ for (Method method1 : methods) {
+ if (MethodUtils.isGetter(method1)) {
+ Parameter parameter = method1.getAnnotation(Parameter.class);
+ if (parameter != null && parameter.excluded()) {
+ continue;
+ }
+ try {
+ Method method2 = obj.getClass().getMethod(method1.getName(), method1.getParameterTypes());
+ Object value1 = method1.invoke(this, new Object[]{});
+ Object value2 = method2.invoke(obj, new Object[]{});
+ if (!Objects.equals(value1, value2)) {
+ return false;
+ }
+ } catch (Exception e) {
+ return true;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Add {@link AbstractConfig instance} into {@link ConfigManager}
+ * <p>
+ * Current method will invoked by Spring or Java EE container automatically, or should be triggered manually.
+ *
+ * @see ConfigManager#addConfig(AbstractConfig)
+ * @since 2.7.5
+ */
+ @PostConstruct
+ public void addIntoConfigManager() {
+ ApplicationModel.getConfigManager().addConfig(this);
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ Method[] methods = this.getClass().getMethods();
+ for (Method method : methods) {
+ if (MethodUtils.isGetter(method)) {
+ Parameter parameter = method.getAnnotation(Parameter.class);
+ if (parameter != null && parameter.excluded()) {
+ continue;
+ }
+ try {
+ Object value = method.invoke(this, new Object[]{});
+ hashCode = 31 * hashCode + value.hashCode();
+ } catch (Exception ignored) {
+ //ignored
+ }
+ }
+ }
+
+ if (hashCode == 0) {
+ hashCode = 1;
+ }
+
+ return hashCode;
+ }
+}
diff --cc dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerMethodModel.java
index b164856,0000000..7a4427f
mode 100644,000000..100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerMethodModel.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ConsumerMethodModel.java
@@@ -1,147 -1,0 +1,101 @@@
+/*
+ * 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 java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
+
+/**
+ * Replaced with {@link MethodDescriptor}
+ */
+@Deprecated
+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;
+ private final ConcurrentMap<String, Object> attributeMap = new ConcurrentHashMap<>();
+
+
- public ConsumerMethodModel(Method method, Map<String, Object> attributes) {
++ public ConsumerMethodModel(Method method) {
+ 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) {
- ConsumerModel.AsyncMethodInfo consumerAsyncInfo = (ConsumerModel.AsyncMethodInfo) attributes.get(methodName);
- this.asyncInfo = new AsyncMethodInfo(consumerAsyncInfo);
- } else {
- asyncInfo = null;
- }
-
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+// public ConcurrentMap<String, Object> getAttributeMap() {
+// return attributeMap;
+// }
+
+ public void addAttribute(String key, Object value) {
+ this.attributeMap.put(key, value);
+ }
+
+ public Object getAttribute(String key) {
+ return this.attributeMap.get(key);
+ }
+
+
+ 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 {
- private ConsumerModel.AsyncMethodInfo delegate;
-
- public AsyncMethodInfo(ConsumerModel.AsyncMethodInfo methodInfo) {
- this.delegate = methodInfo;
- }
-
- public Object getOninvokeInstance() {
- return delegate.getOninvokeInstance();
- }
-
-
- public Method getOninvokeMethod() {
- return delegate.getOninvokeMethod();
- }
-
- public Object getOnreturnInstance() {
- return delegate.getOnreturnInstance();
- }
-
- public Method getOnreturnMethod() {
- return delegate.getOnreturnMethod();
- }
-
- public Object getOnthrowInstance() {
- return delegate.getOnthrowInstance();
- }
-
- public Method getOnthrowMethod() {
- return delegate.getOnthrowMethod();
- }
- }
+}
diff --cc dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
index eae4aca,8e1c63b..4fd15e1
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Offline.java
@@@ -59,18 -58,19 +59,18 @@@ public class Offline implements BaseCom
public static boolean offline(String servicePattern) {
boolean hasService = false;
- Collection<ProviderModel> providerModelList = ApplicationModel.allProviderModels();
+
+ Collection<ProviderModel> providerModelList = serviceRepository.getExportedServices();
for (ProviderModel providerModel : providerModelList) {
- if (providerModel.getServiceKey().matches(servicePattern)) {
+ if (providerModel.getServiceMetadata().getDisplayServiceKey().matches(servicePattern)) {
hasService = true;
- Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable
- .getProviderInvoker(providerModel.getServiceMetadata().getServiceKey());
- for (ProviderInvokerWrapper providerInvokerWrapper : providerInvokerWrapperSet) {
- if (!providerInvokerWrapper.isReg()) {
- continue;
+ List<ProviderModel.RegisterStatedURL> statedUrls = providerModel.getStatedUrl();
+ for (ProviderModel.RegisterStatedURL statedURL : statedUrls) {
+ if (statedURL.isRegistered()) {
+ Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl());
+ registry.unregister(statedURL.getProviderUrl());
+ statedURL.setRegistered(false);
}
- Registry registry = registryFactory.getRegistry(providerInvokerWrapper.getRegistryUrl());
- registry.unregister(providerInvokerWrapper.getProviderUrl());
- providerInvokerWrapper.setReg(false);
}
}
}
diff --cc dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
index 1f99dd5,cb62647..c04f184
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/Online.java
@@@ -55,22 -56,23 +55,22 @@@ public class Online implements BaseComm
} else {
return "service not found";
}
-
}
- public static boolean online(String servicePattern){
+ public static boolean online(String servicePattern) {
boolean hasService = false;
- Collection<ProviderModel> providerModelList = ApplicationModel.allProviderModels();
+
+ Collection<ProviderModel> providerModelList = serviceRepository.getExportedServices();
for (ProviderModel providerModel : providerModelList) {
- if (providerModel.getServiceName().matches(servicePattern)) {
+ if (providerModel.getServiceMetadata().getDisplayServiceKey().matches(servicePattern)) {
hasService = true;
- Set<ProviderInvokerWrapper> providerInvokerWrapperSet = ProviderConsumerRegTable.getProviderInvoker(providerModel.getServiceMetadata().getServiceKey());
- for (ProviderInvokerWrapper providerInvokerWrapper : providerInvokerWrapperSet) {
- if (providerInvokerWrapper.isReg()) {
- continue;
+ List<ProviderModel.RegisterStatedURL> statedUrls = providerModel.getStatedUrl();
+ for (ProviderModel.RegisterStatedURL statedURL : statedUrls) {
+ if (!statedURL.isRegistered()) {
+ Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl());
+ registry.register(statedURL.getProviderUrl());
+ statedURL.setRegistered(true);
}
- Registry registry = registryFactory.getRegistry(providerInvokerWrapper.getRegistryUrl());
- registry.register(providerInvokerWrapper.getProviderUrl());
- providerInvokerWrapper.setReg(true);
}
}
}
diff --cc dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
index bcbe962,ffbdcec..1f182a0
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
@@@ -49,22 -54,8 +50,22 @@@ public class FutureFilter implements Fi
return invoker.invoke(invocation);
}
+ @Override
+ public void onMessage(Result result, Invoker<?> invoker, Invocation invocation) {
+ if (result.hasException()) {
+ fireThrowCallback(invoker, invocation, result.getException());
+ } else {
+ fireReturnCallback(invoker, invocation, result.getValue());
+ }
+ }
+
+ @Override
+ public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
+
+ }
+
private void fireInvokeCallback(final Invoker<?> invoker, final Invocation invocation) {
- final ConsumerModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
+ final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
if (asyncMethodInfo == null) {
return;
}
@@@ -195,12 -186,22 +196,7 @@@
methodName = (String) invocation.getArguments()[0];
}
- final ConsumerModel.AsyncMethodInfo asyncMethodInfo = consumerModel.getMethodConfig(methodName);
- if (asyncMethodInfo == null) {
- return null;
- }
-
- return asyncMethodInfo;
+ return consumerModel.getAsyncInfo(methodName);
}
- class FutureListener implements Listener {
- @Override
- public void onResponse(Result result, Invoker<?> invoker, Invocation invocation) {
- if (result.hasException()) {
- fireThrowCallback(invoker, invocation, result.getException());
- } else {
- fireReturnCallback(invoker, invocation, result.getValue());
- }
- }
-
- @Override
- public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
-
- }
- }
}