diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java index c245f39b55..8d9e441ef7 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/AnnotationUtils.java @@ -132,6 +132,39 @@ public interface AnnotationUtils { return getAttribute(annotation, "value"); } + /** + * Get the attribute from the specified {@link Annotation annotation} + * + * @param annotation the specified {@link Annotation annotation} + * @param attributeNames the multiply attribute name arrays + * @param the type of attribute + * @return the attribute value + * @throws IllegalArgumentException If the attribute name can't be found + */ + static T getAttribute(Annotation annotation, String... attributeNames) throws IllegalArgumentException { + if (attributeNames == null || attributeNames.length == 0) { + return null; + } + + for (String attributeName : attributeNames) { + T attribute = getAttribute(annotation, attributeName); + + if (attribute == null) { + continue; + } + + // exclude string attribute default is empty + if ((attribute instanceof String) && ((String) attribute).length() == 0) { + continue; + } + + return attribute; + } + + return null; + + } + /** * Get the {@link Annotation} from the specified {@link AnnotatedElement the annotated element} and * {@link Annotation annotation} class name diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java index 845296e98a..2ef19ba8fd 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java @@ -212,6 +212,20 @@ public class ClassUtils { return forName(name, getClassLoader()); } + /** + * find class and don`t expect to throw exception + * @param name + * @return + */ + public static Class forNameAndTryCatch(String name) { + try { + return forName(name, getClassLoader()); + } catch (Throwable e) { + return null; + } + } + + /** * Replacement for Class.forName() that also returns Class * instances for primitives (like "int") and array class names (like diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java index 3018b6cec5..e1fe308981 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java @@ -34,6 +34,7 @@ import org.apache.dubbo.common.utils.UrlUtils; import org.apache.dubbo.config.annotation.Reference; import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.config.utils.ConfigValidationUtils; +import org.apache.dubbo.config.utils.FeignClientAnnotationUtil; import org.apache.dubbo.registry.client.metadata.MetadataUtils; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; @@ -418,6 +419,8 @@ public class ReferenceConfig extends ReferenceConfigBase { AbstractConfig.appendParameters(map, consumer); AbstractConfig.appendParameters(map, this); appendMetricsCompatible(map); + // after interface metadata set + FeignClientAnnotationUtil.appendParametersFromInterfaceClassMetadata(this.interfaceClass,map); String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY); if (StringUtils.isEmpty(hostToRegistry)) { diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/FeignClientAnnotationUtil.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/FeignClientAnnotationUtil.java new file mode 100644 index 0000000000..161cb5a9e5 --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/FeignClientAnnotationUtil.java @@ -0,0 +1,64 @@ +/* + * 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.utils; + +import org.apache.dubbo.common.utils.AnnotationUtils; +import org.apache.dubbo.common.utils.ClassUtils; +import org.apache.dubbo.common.utils.StringUtils; + +import java.lang.annotation.Annotation; +import java.util.Map; + +import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDED_BY; + +public class FeignClientAnnotationUtil { + /** + * append parameters from interface class metadata + * such as FeignClient service as dubbo providedBy + * + * @param paramtetersMap + */ + public static void appendParametersFromInterfaceClassMetadata(Class interfaceClass, Map paramtetersMap) { + + if (interfaceClass == null) { + return; + } + + Class feignClientAnno = (Class) ClassUtils.forNameAndTryCatch("org.springframework.cloud.openfeign.FeignClient"); + + + if (feignClientAnno == null || !AnnotationUtils.isAnnotationPresent(interfaceClass, feignClientAnno)) { + return; + } + + Annotation annotation = interfaceClass.getAnnotation(feignClientAnno); + + // get feign client service name + String serviceName = AnnotationUtils.getAttribute(annotation, "name", "value"); + + if (StringUtils.isEmpty(serviceName)) { + return; + } + + // append old value + serviceName = paramtetersMap.containsKey(PROVIDED_BY) ? paramtetersMap.get(PROVIDED_BY) + "," + serviceName : serviceName; + + // cover old value + paramtetersMap.put(PROVIDED_BY, serviceName); + + } +} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/deploy/ServiceDeployerManager.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/deploy/ServiceDeployerManager.java index 6b3e374611..ff93b26133 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/deploy/ServiceDeployerManager.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/deploy/ServiceDeployerManager.java @@ -34,7 +34,7 @@ public class ServiceDeployerManager { private static final ConcurrentMap serviceDeployers = new ConcurrentHashMap<>(); - public static URL deploy(final URL currentURL, ServiceRestMetadata serviceRestMetadata, Invoker invoker) { + public static URL deploy(URL currentURL, ServiceRestMetadata serviceRestMetadata, Invoker invoker) { AtomicBoolean isNewCreate = new AtomicBoolean(); @@ -52,6 +52,11 @@ public class ServiceDeployerManager { // register exception mapper newServiceDeployer.registerExtension(currentURL); + // passing ServiceDeployer to PortUnificationServer through URL + // add attribute for server build + + currentURL = currentURL.putAttribute(REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY, newServiceDeployer); + // not new URL if (!isNewCreate.get()) { return currentURL; @@ -64,11 +69,6 @@ public class ServiceDeployerManager { tmp = tmp.addParameter(SERVER_KEY, PORT_UNIFICATION_NETTY4_SERVER); } - // passing ServiceDeployer to PortUnificationServer through URL - // add attribute for server build - - tmp = tmp.putAttribute(REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY, newServiceDeployer); - return tmp; }