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 <[email protected]> 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) { - - } - } }
