From 1744f6b4cfbc943d88ac40f6756f901b82fc0892 Mon Sep 17 00:00:00 2001 From: mercyblitz <mercyblitz@gmail.com> Date: Tue, 26 Mar 2019 00:19:58 +0800 Subject: [PATCH] Polish : spring-cloud-incubator/spring-cloud-alibaba#477 : @DubboTransported adds more attributes to customize settings --- .../dubbo/annotation/DubboTransported.java | 83 +++++++++++++++++++ ...BalancedRestTemplateAutoConfiguration.java | 30 +++---- .../DubboTransporterInterceptor.java | 10 +-- .../metadata/DubboTransportedMetadata.java | 61 -------------- .../DubboTransportedMethodMetadata.java | 39 +++------ .../DubboTransportedAttributesResolver.java | 56 +++++++++++++ ...ubboTransportedMethodMetadataResolver.java | 12 +-- .../openfeign/TargeterInvocationHandler.java | 8 +- .../service/DubboGenericServiceFactory.java | 63 ++++++++++---- 9 files changed, 222 insertions(+), 140 deletions(-) delete mode 100644 spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMetadata.java create mode 100644 spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedAttributesResolver.java diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/annotation/DubboTransported.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/annotation/DubboTransported.java index 2714923d0..f5cfe6444 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/annotation/DubboTransported.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/annotation/DubboTransported.java @@ -16,6 +16,11 @@ */ package org.springframework.cloud.alibaba.dubbo.annotation; +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.config.annotation.Reference; +import org.apache.dubbo.rpc.ExporterListener; +import org.apache.dubbo.rpc.Filter; + import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.client.RestTemplate; @@ -26,6 +31,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import static org.apache.dubbo.common.Constants.DEFAULT_RETRIES; + /** * {@link DubboTransported @DubboTransported} annotation indicates that the traditional Spring Cloud Service-to-Service call is transported * by Dubbo under the hood, there are two main scenarios: @@ -64,4 +71,80 @@ public @interface DubboTransported { * @return the default cluster is "failover" */ String cluster() default "${dubbo.transport.cluster:failover}"; + + /** + * Whether to reconnect if connection is lost, if not specify, reconnect is enabled by default, and the interval + * for retry connecting is 2000 ms + * + * @see Constants#DEFAULT_RECONNECT_PERIOD + * @see Reference#reconnect() + */ + String reconnect() default "${dubbo.transport.reconnect:2000}"; + + /** + * Maximum connections service provider can accept, default value is 0 - connection is shared + * + * @see Reference#connections() + */ + int connections() default 0; + + /** + * Service invocation retry times + * + * @see Constants#DEFAULT_RETRIES + * @see Reference#retries() + */ + int retries() default DEFAULT_RETRIES; + + /** + * Load balance strategy, legal values include: random, roundrobin, leastactive + * + * @see Constants#DEFAULT_LOADBALANCE + * @see Reference#loadbalance() + */ + String loadbalance() default "${dubbo.transport.loadbalance:}"; + + /** + * Maximum active requests allowed, default value is 0 + * + * @see Reference#actives() + */ + int actives() default 0; + + /** + * Timeout value for service invocation, default value is 0 + * + * @see Reference#timeout() + */ + int timeout() default 0; + + /** + * Specify cache implementation for service invocation, legal values include: lru, threadlocal, jcache + * + * @see Reference#cache() + */ + String cache() default "${dubbo.transport.cache:}"; + + /** + * Filters for service invocation + * + * @see Filter + * @see Reference#filter() + */ + String[] filter() default {}; + + /** + * Listeners for service exporting and unexporting + * + * @see ExporterListener + * @see Reference#listener() + */ + String[] listener() default {}; + + /** + * Customized parameter key-value pair, for example: {key1, value1, key2, value2} + * + * @see Reference#parameters() + */ + String[] parameters() default {}; } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java index e97acfca3..a6afc5a98 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java @@ -28,8 +28,8 @@ import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported; import org.springframework.cloud.alibaba.dubbo.client.loadbalancer.DubboMetadataInitializerInterceptor; import org.springframework.cloud.alibaba.dubbo.client.loadbalancer.DubboTransporterInterceptor; -import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; +import org.springframework.cloud.alibaba.dubbo.metadata.resolver.DubboTransportedAttributesResolver; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; import org.springframework.cloud.client.loadbalancer.LoadBalanced; @@ -86,6 +86,7 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass private ClassLoader classLoader; + /** * Adapt the {@link RestTemplate} beans that are annotated {@link LoadBalanced @LoadBalanced} and * {@link LoadBalanced @LoadBalanced} when Spring Boot application started @@ -94,9 +95,12 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass */ @EventListener(ApplicationStartedEvent.class) public void adaptRestTemplates() { + + DubboTransportedAttributesResolver attributesResolver = new DubboTransportedAttributesResolver(environment); + for (Map.Entry<String, RestTemplate> entry : restTemplates.entrySet()) { String beanName = entry.getKey(); - Map<String, Object> dubboTranslatedAttributes = getDubboTranslatedAttributes(beanName); + Map<String, Object> dubboTranslatedAttributes = getDubboTranslatedAttributes(beanName, attributesResolver); if (!CollectionUtils.isEmpty(dubboTranslatedAttributes)) { adaptRestTemplate(entry.getValue(), dubboTranslatedAttributes); } @@ -107,10 +111,12 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass * Gets the annotation attributes {@link RestTemplate} bean being annotated * {@link DubboTransported @DubboTransported} * - * @param beanName the bean name of {@link LoadBalanced @LoadBalanced} {@link RestTemplate} + * @param beanName the bean name of {@link LoadBalanced @LoadBalanced} {@link RestTemplate} + * @param attributesResolver {@link DubboTransportedAttributesResolver} * @return non-null {@link Map} */ - private Map<String, Object> getDubboTranslatedAttributes(String beanName) { + private Map<String, Object> getDubboTranslatedAttributes(String beanName, + DubboTransportedAttributesResolver attributesResolver) { Map<String, Object> attributes = Collections.emptyMap(); BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); if (beanDefinition instanceof AnnotatedBeanDefinition) { @@ -119,7 +125,7 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass attributes = factoryMethodMetadata != null ? factoryMethodMetadata.getAnnotationAttributes(DUBBO_TRANSPORTED_CLASS_NAME) : Collections.emptyMap(); } - return attributes; + return attributesResolver.resolve(attributes); } @@ -132,8 +138,6 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass */ private void adaptRestTemplate(RestTemplate restTemplate, Map<String, Object> dubboTranslatedAttributes) { - DubboTransportedMetadata dubboTransportedMetadata = buildDubboTransportedMetadata(dubboTranslatedAttributes); - List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(restTemplate.getInterceptors()); int index = interceptors.indexOf(loadBalancerInterceptor); @@ -144,21 +148,11 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass interceptors.add(index++, new DubboMetadataInitializerInterceptor(repository)); interceptors.add(index++, new DubboTransporterInterceptor(repository, restTemplate.getMessageConverters(), - classLoader, dubboTransportedMetadata, serviceFactory, contextFactory)); + classLoader, dubboTranslatedAttributes, serviceFactory, contextFactory)); restTemplate.setInterceptors(interceptors); } - private DubboTransportedMetadata buildDubboTransportedMetadata(Map<String, Object> dubboTranslatedAttributes) { - DubboTransportedMetadata dubboTransportedMetadata = new DubboTransportedMetadata(); - String protocol = (String) dubboTranslatedAttributes.get("protocol"); - String cluster = (String) dubboTranslatedAttributes.get("cluster"); - // resolve placeholders - dubboTransportedMetadata.setProtocol(environment.resolvePlaceholders(protocol)); - dubboTransportedMetadata.setCluster(environment.resolvePlaceholders(cluster)); - return dubboTransportedMetadata; - } - @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/client/loadbalancer/DubboTransporterInterceptor.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/client/loadbalancer/DubboTransporterInterceptor.java index 0d2864fc6..9920e8c50 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/client/loadbalancer/DubboTransporterInterceptor.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/client/loadbalancer/DubboTransporterInterceptor.java @@ -18,9 +18,9 @@ package org.springframework.cloud.alibaba.dubbo.client.loadbalancer; import org.apache.dubbo.rpc.service.GenericException; import org.apache.dubbo.rpc.service.GenericService; + import org.springframework.cloud.alibaba.dubbo.http.MutableHttpServerRequest; import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata; -import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; @@ -57,7 +57,7 @@ public class DubboTransporterInterceptor implements ClientHttpRequestInterceptor private final DubboClientHttpResponseFactory clientHttpResponseFactory; - private final DubboTransportedMetadata dubboTransportedMetadata; + private final Map<String, Object> dubboTranslatedAttributes; private final DubboGenericServiceFactory serviceFactory; @@ -68,11 +68,11 @@ public class DubboTransporterInterceptor implements ClientHttpRequestInterceptor public DubboTransporterInterceptor(DubboServiceMetadataRepository dubboServiceMetadataRepository, List<HttpMessageConverter<?>> messageConverters, ClassLoader classLoader, - DubboTransportedMetadata dubboTransportedMetadata, + Map<String, Object> dubboTranslatedAttributes, DubboGenericServiceFactory serviceFactory, DubboGenericServiceExecutionContextFactory contextFactory) { this.repository = dubboServiceMetadataRepository; - this.dubboTransportedMetadata = dubboTransportedMetadata; + this.dubboTranslatedAttributes = dubboTranslatedAttributes; this.clientHttpResponseFactory = new DubboClientHttpResponseFactory(messageConverters, classLoader); this.serviceFactory = serviceFactory; this.contextFactory = contextFactory; @@ -96,7 +96,7 @@ public class DubboTransporterInterceptor implements ClientHttpRequestInterceptor RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata(); - GenericService genericService = serviceFactory.create(dubboServiceMetadata, dubboTransportedMetadata); + GenericService genericService = serviceFactory.create(dubboServiceMetadata, dubboTranslatedAttributes); MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(request, body); diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMetadata.java deleted file mode 100644 index 2811bdaf4..000000000 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMetadata.java +++ /dev/null @@ -1,61 +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.springframework.cloud.alibaba.dubbo.metadata; - -import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported; - -import java.util.Objects; - -/** - * {@link DubboTransported @DubboTransported} Metadata - */ -public class DubboTransportedMetadata { - - private String protocol; - - private String cluster; - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getCluster() { - return cluster; - } - - public void setCluster(String cluster) { - this.cluster = cluster; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof DubboTransportedMetadata)) return false; - DubboTransportedMetadata that = (DubboTransportedMetadata) o; - return Objects.equals(protocol, that.protocol) && - Objects.equals(cluster, that.cluster); - } - - @Override - public int hashCode() { - return Objects.hash(protocol, cluster); - } -} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMethodMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMethodMetadata.java index ade65aa99..6e7ab9ac3 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMethodMetadata.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/DubboTransportedMethodMetadata.java @@ -20,6 +20,7 @@ import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported; import java.lang.reflect.Method; import java.util.List; +import java.util.Map; import java.util.Objects; /** @@ -29,29 +30,13 @@ import java.util.Objects; */ public class DubboTransportedMethodMetadata { - private final DubboTransportedMetadata dubboTransportedMetadata; - private final MethodMetadata methodMetadata; - public DubboTransportedMethodMetadata(Method method) { - this.methodMetadata = new MethodMetadata(method); - this.dubboTransportedMetadata = new DubboTransportedMetadata(); - } - - public String getProtocol() { - return dubboTransportedMetadata.getProtocol(); - } - - public void setProtocol(String protocol) { - dubboTransportedMetadata.setProtocol(protocol); - } - - public String getCluster() { - return dubboTransportedMetadata.getCluster(); - } + private final Map<String, Object> attributes; - public void setCluster(String cluster) { - dubboTransportedMetadata.setCluster(cluster); + public DubboTransportedMethodMetadata(Method method, Map<String, Object> attributes) { + this.methodMetadata = new MethodMetadata(method); + this.attributes = attributes; } public String getName() { @@ -82,25 +67,25 @@ public class DubboTransportedMethodMetadata { return methodMetadata.getMethod(); } - public DubboTransportedMetadata getDubboTransportedMetadata() { - return dubboTransportedMetadata; - } - public MethodMetadata getMethodMetadata() { return methodMetadata; } + public Map<String, Object> getAttributes() { + return attributes; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof DubboTransportedMethodMetadata)) return false; DubboTransportedMethodMetadata that = (DubboTransportedMethodMetadata) o; - return Objects.equals(dubboTransportedMetadata, that.dubboTransportedMetadata) && - Objects.equals(methodMetadata, that.methodMetadata); + return Objects.equals(methodMetadata, that.methodMetadata) && + Objects.equals(attributes, that.attributes); } @Override public int hashCode() { - return Objects.hash(dubboTransportedMetadata, methodMetadata); + return Objects.hash(methodMetadata, attributes); } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedAttributesResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedAttributesResolver.java new file mode 100644 index 000000000..e403139e5 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedAttributesResolver.java @@ -0,0 +1,56 @@ +/* + * 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.springframework.cloud.alibaba.dubbo.metadata.resolver; + +import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported; +import org.springframework.core.env.PropertyResolver; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes; + +/** + * {@link DubboTransported} annotation attributes resolver + * + * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> + */ +public class DubboTransportedAttributesResolver { + + private final PropertyResolver propertyResolver; + + public DubboTransportedAttributesResolver(PropertyResolver propertyResolver) { + this.propertyResolver = propertyResolver; + } + + public Map<String, Object> resolve(DubboTransported dubboTransported) { + Map<String, Object> attributes = getAnnotationAttributes(dubboTransported); + return resolve(attributes); + } + + public Map<String, Object> resolve(Map<String, Object> attributes) { + Map<String, Object> resolvedAttributes = new LinkedHashMap<>(); + for (Map.Entry<String, Object> entry : attributes.entrySet()) { + Object value = entry.getValue(); + if (value instanceof String) { + value = propertyResolver.resolvePlaceholders(value.toString()); + } + resolvedAttributes.put(entry.getKey(), value); + } + return resolvedAttributes; + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedMethodMetadataResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedMethodMetadataResolver.java index d1aa6389f..3e2324409 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedMethodMetadataResolver.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/DubboTransportedMethodMetadataResolver.java @@ -42,12 +42,12 @@ public class DubboTransportedMethodMetadataResolver { private static final Class<DubboTransported> DUBBO_TRANSPORTED_CLASS = DubboTransported.class; - private final PropertyResolver propertyResolver; + private final DubboTransportedAttributesResolver attributesResolver; private final Contract contract; public DubboTransportedMethodMetadataResolver(PropertyResolver propertyResolver, Contract contract) { - this.propertyResolver = propertyResolver; + this.attributesResolver = new DubboTransportedAttributesResolver(propertyResolver); this.contract = contract; } @@ -93,12 +93,8 @@ public class DubboTransportedMethodMetadataResolver { private DubboTransportedMethodMetadata createDubboTransportedMethodMetadata(Method method, DubboTransported dubboTransported) { - DubboTransportedMethodMetadata methodMetadata = new DubboTransportedMethodMetadata(method); - String protocol = propertyResolver.resolvePlaceholders(dubboTransported.protocol()); - String cluster = propertyResolver.resolvePlaceholders(dubboTransported.cluster()); - methodMetadata.setProtocol(protocol); - methodMetadata.setCluster(cluster); - return methodMetadata; + Map<String, Object> attributes = attributesResolver.resolve(dubboTransported); + return new DubboTransportedMethodMetadata(method, attributes); } private DubboTransported resolveDubboTransported(Method method) { diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java index e606367a0..9ef731dd6 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterInvocationHandler.java @@ -17,14 +17,14 @@ package org.springframework.cloud.alibaba.dubbo.openfeign; +import org.apache.dubbo.rpc.service.GenericService; + import feign.Contract; import feign.Target; -import org.apache.dubbo.rpc.service.GenericService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported; import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata; -import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMethodMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata; @@ -150,9 +150,9 @@ class TargeterInvocationHandler implements InvocationHandler { DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, feignRequestMetadata); if (dubboServiceMetadata != null) { DubboTransportedMethodMetadata dubboTransportedMethodMetadata = entry.getKey(); - DubboTransportedMetadata dubboTransportedMetadata = dubboTransportedMethodMetadata.getDubboTransportedMetadata(); + Map<String, Object> dubboTranslatedAttributes = dubboTransportedMethodMetadata.getAttributes(); Method method = dubboTransportedMethodMetadata.getMethod(); - GenericService dubboGenericService = dubboGenericServiceFactory.create(dubboServiceMetadata, dubboTransportedMetadata); + GenericService dubboGenericService = dubboGenericServiceFactory.create(dubboServiceMetadata, dubboTranslatedAttributes); RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata(); MethodMetadata methodMetadata = dubboTransportedMethodMetadata.getMethodMetadata(); FeignMethodMetadata feignMethodMetadata = new FeignMethodMetadata(dubboGenericService, diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java index e15bbb692..10cd08c9f 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java @@ -17,24 +17,31 @@ package org.springframework.cloud.alibaba.dubbo.service; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.rpc.service.GenericService; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata; -import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata; import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; +import org.springframework.util.StringUtils; +import org.springframework.validation.DataBinder; import javax.annotation.PreDestroy; +import java.beans.PropertyEditorSupport; import java.util.Collection; +import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import static org.apache.dubbo.common.Constants.DEFAULT_CLUSTER; -import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL; +import static java.util.Collections.emptyMap; import static org.apache.dubbo.common.Constants.GROUP_KEY; import static org.apache.dubbo.common.Constants.VERSION_KEY; +import static org.springframework.util.StringUtils.commaDelimitedListToStringArray; /** * Dubbo {@link GenericService} Factory @@ -48,38 +55,35 @@ public class DubboGenericServiceFactory { private final ConcurrentMap<Integer, ReferenceBean<GenericService>> cache = new ConcurrentHashMap<>(); public GenericService create(DubboServiceMetadata dubboServiceMetadata, - DubboTransportedMetadata dubboTransportedMetadata) { + Map<String, Object> dubboTranslatedAttributes) { - ReferenceBean<GenericService> referenceBean = build(dubboServiceMetadata.getServiceRestMetadata(), dubboTransportedMetadata); + ReferenceBean<GenericService> referenceBean = build(dubboServiceMetadata.getServiceRestMetadata(), dubboTranslatedAttributes); return referenceBean == null ? null : referenceBean.get(); } public GenericService create(String serviceName, Class<?> serviceClass) { String interfaceName = serviceClass.getName(); - ReferenceBean<GenericService> referenceBean = build(interfaceName, serviceName, null, - DEFAULT_PROTOCOL, DEFAULT_CLUSTER); + ReferenceBean<GenericService> referenceBean = build(interfaceName, serviceName, null, emptyMap()); return referenceBean.get(); } private ReferenceBean<GenericService> build(ServiceRestMetadata serviceRestMetadata, - DubboTransportedMetadata dubboTransportedMetadata) { + Map<String, Object> dubboTranslatedAttributes) { String urlValue = serviceRestMetadata.getUrl(); URL url = URL.valueOf(urlValue); String interfaceName = url.getServiceInterface(); String version = url.getParameter(VERSION_KEY); - String group = url.getParameter(GROUP_KEY); - String protocol = dubboTransportedMetadata.getProtocol(); - String cluster = dubboTransportedMetadata.getCluster(); + String group = url.getParameter(GROUP_KEY); - return build(interfaceName, version, group, protocol, cluster); + return build(interfaceName, version, group, dubboTranslatedAttributes); } - private ReferenceBean<GenericService> build(String interfaceName, String version, String group, String protocol, - String cluster) { + private ReferenceBean<GenericService> build(String interfaceName, String version, String group, + Map<String, Object> dubboTranslatedAttributes) { - Integer key = Objects.hash(interfaceName, version, group, protocol, cluster); + Integer key = Objects.hash(interfaceName, version, group, dubboTranslatedAttributes); ReferenceBean<GenericService> referenceBean = cache.get(key); @@ -89,13 +93,38 @@ public class DubboGenericServiceFactory { referenceBean.setInterface(interfaceName); referenceBean.setVersion(version); referenceBean.setGroup(group); - referenceBean.setProtocol(protocol); - referenceBean.setCluster(cluster); + bindReferenceBean(referenceBean, dubboTranslatedAttributes); } return referenceBean; } + private void bindReferenceBean(ReferenceBean<GenericService> referenceBean, Map<String, Object> dubboTranslatedAttributes) { + DataBinder dataBinder = new DataBinder(referenceBean); + // Register CustomEditors for special fields + dataBinder.registerCustomEditor(String.class, "filter", new StringTrimmerEditor(true)); + dataBinder.registerCustomEditor(String.class, "listener", new StringTrimmerEditor(true)); + dataBinder.registerCustomEditor(Map.class, "parameters", new PropertyEditorSupport() { + + public void setAsText(String text) throws java.lang.IllegalArgumentException { + // Trim all whitespace + String content = StringUtils.trimAllWhitespace(text); + if (!StringUtils.hasText(content)) { // No content , ignore directly + return; + } + // replace "=" to "," + content = StringUtils.replace(content, "=", ","); + // replace ":" to "," + content = StringUtils.replace(content, ":", ","); + // String[] to Map + Map<String, String> parameters = CollectionUtils.toStringMap(commaDelimitedListToStringArray(content)); + setValue(parameters); + } + }); + + dataBinder.bind(new MutablePropertyValues(dubboTranslatedAttributes)); + } + @PreDestroy public void destroy() { destroyReferenceBeans();