mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d6da5e4885
12
pom.xml
12
pom.xml
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
@ -70,11 +70,11 @@
|
||||
|
||||
<properties>
|
||||
<!-- Dependency Versions -->
|
||||
<spring-cloud-commons.version>2.1.0.RELEASE</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.1.0.RELEASE</spring-cloud-netflix.version>
|
||||
<spring-cloud-openfeign.version>2.1.0.RELEASE</spring-cloud-openfeign.version>
|
||||
<spring-cloud-bus.version>2.1.0.RELEASE</spring-cloud-bus.version>
|
||||
<spring-cloud-gateway.version>2.1.0.RELEASE</spring-cloud-gateway.version>
|
||||
<spring-cloud-commons.version>2.1.1.RELEASE</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.1.1.RELEASE</spring-cloud-netflix.version>
|
||||
<spring-cloud-openfeign.version>2.1.1.RELEASE</spring-cloud-openfeign.version>
|
||||
<spring-cloud-bus.version>2.1.1.RELEASE</spring-cloud-bus.version>
|
||||
<spring-cloud-gateway.version>2.1.1.RELEASE</spring-cloud-gateway.version>
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
<javax-servlet-api>3.0</javax-servlet-api>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-dependencies-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
|
@ -15,9 +15,8 @@
|
||||
|
||||
<properties>
|
||||
<dubbo.version>2.7.1</dubbo.version>
|
||||
<dubbo-spring-boot.version>2.7.0</dubbo-spring-boot.version>
|
||||
<spring-cloud-zookeeper.version>2.1.0.RELEASE</spring-cloud-zookeeper.version>
|
||||
<spring-cloud-consul.version>2.1.0.RELEASE</spring-cloud-consul.version>
|
||||
<spring-cloud-zookeeper.version>2.1.1.RELEASE</spring-cloud-zookeeper.version>
|
||||
<spring-cloud-consul.version>2.1.1.RELEASE</spring-cloud-consul.version>
|
||||
<curator.version>4.0.1</curator.version>
|
||||
</properties>
|
||||
|
||||
@ -179,7 +178,14 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
<version>${dubbo-spring-boot.version}</version>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Dubbo Spring Boot Actuator -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-actuator</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Netty -->
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.actuate;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.alibaba.dubbo.actuate.endpoint.DubboRestMetadataEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
/**
|
||||
* Dubbo Metadata Endpoints Auto-{@link Configuration}
|
||||
*/
|
||||
@ConditionalOnClass(name = "org.springframework.boot.actuate.endpoint.annotation.Endpoint")
|
||||
@PropertySource(value = "classpath:/META-INF/dubbo/default/actuator-endpoints.properties")
|
||||
@ManagementContextConfiguration
|
||||
public class DubboMetadataEndpointAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
public DubboRestMetadataEndpoint dubboRestMetadataEndpoint() {
|
||||
return new DubboRestMetadataEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.actuate.endpoint;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataService;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
|
||||
|
||||
/**
|
||||
* Dubbo Rest Metadata {@link Endpoint}
|
||||
*/
|
||||
@Endpoint(id = "dubborestmetadata")
|
||||
public class DubboRestMetadataEndpoint {
|
||||
|
||||
@Autowired
|
||||
private DubboMetadataService dubboMetadataService;
|
||||
|
||||
@ReadOperation(produces = APPLICATION_JSON_UTF8_VALUE)
|
||||
public String get() {
|
||||
return dubboMetadataService.getServiceRestMetadata();
|
||||
}
|
||||
}
|
@ -35,6 +35,7 @@ import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactor
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
|
||||
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
|
||||
import org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.core.env.Environment;
|
||||
@ -56,7 +57,7 @@ import java.util.Map;
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = {"org.springframework.web.client.RestTemplate"})
|
||||
@AutoConfigureAfter(name = {"org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration"})
|
||||
public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClassLoaderAware {
|
||||
public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClassLoaderAware, SmartInitializingSingleton {
|
||||
|
||||
private static final Class<DubboTransported> DUBBO_TRANSPORTED_CLASS = DubboTransported.class;
|
||||
|
||||
@ -65,9 +66,12 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
|
||||
@Autowired
|
||||
private DubboServiceMetadataRepository repository;
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private LoadBalancerInterceptor loadBalancerInterceptor;
|
||||
|
||||
@Autowired(required = false)
|
||||
private RetryLoadBalancerInterceptor retryLoadBalancerInterceptor;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@ -86,6 +90,17 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
/**
|
||||
* The {@link ClientHttpRequestInterceptor} bean that may be {@link LoadBalancerInterceptor} or {@link RetryLoadBalancerInterceptor}
|
||||
*/
|
||||
private ClientHttpRequestInterceptor loadBalancerInterceptorBean;
|
||||
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
loadBalancerInterceptorBean = retryLoadBalancerInterceptor != null ?
|
||||
retryLoadBalancerInterceptor :
|
||||
loadBalancerInterceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the {@link RestTemplate} beans that are annotated {@link LoadBalanced @LoadBalanced} and
|
||||
@ -140,7 +155,7 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
|
||||
|
||||
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(restTemplate.getInterceptors());
|
||||
|
||||
int index = interceptors.indexOf(loadBalancerInterceptor);
|
||||
int index = loadBalancerInterceptorBean == null ? -1 : interceptors.indexOf(loadBalancerInterceptorBean);
|
||||
|
||||
index = index < 0 ? 0 : index;
|
||||
|
||||
@ -157,4 +172,5 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,9 +30,9 @@ import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceM
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.resolver.DubboServiceBeanMetadataResolver;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceExporter;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceProxy;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.PublishingDubboMetadataConfigService;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataServiceExporter;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataServiceProxy;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.PublishingDubboMetadataService;
|
||||
import org.springframework.cloud.alibaba.dubbo.util.JSONUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -50,19 +50,19 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
@Configuration
|
||||
@Import({DubboServiceMetadataRepository.class,
|
||||
PublishingDubboMetadataConfigService.class,
|
||||
DubboMetadataConfigServiceExporter.class,
|
||||
PublishingDubboMetadataService.class,
|
||||
DubboMetadataServiceExporter.class,
|
||||
JSONUtils.class})
|
||||
public class DubboMetadataAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private PublishingDubboMetadataConfigService dubboMetadataConfigService;
|
||||
private PublishingDubboMetadataService dubboMetadataService;
|
||||
|
||||
@Autowired
|
||||
private MetadataResolver metadataResolver;
|
||||
|
||||
@Autowired
|
||||
private DubboMetadataConfigServiceExporter dubboMetadataConfigServiceExporter;
|
||||
private DubboMetadataServiceExporter dubboMetadataConfigServiceExporter;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ -77,8 +77,8 @@ public class DubboMetadataAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public DubboMetadataConfigServiceProxy dubboMetadataConfigServiceProxy(DubboGenericServiceFactory factory) {
|
||||
return new DubboMetadataConfigServiceProxy(factory);
|
||||
public DubboMetadataServiceProxy dubboMetadataConfigServiceProxy(DubboGenericServiceFactory factory) {
|
||||
return new DubboMetadataServiceProxy(factory);
|
||||
}
|
||||
|
||||
// Event-Handling
|
||||
@ -101,7 +101,7 @@ public class DubboMetadataAutoConfiguration {
|
||||
}
|
||||
|
||||
private void publishServiceRestMetadata(ServiceBean serviceBean) {
|
||||
dubboMetadataConfigService.publishServiceRestMetadata(metadataResolver.resolveServiceRestMetadata(serviceBean));
|
||||
dubboMetadataService.publishServiceRestMetadata(metadataResolver.resolveServiceRestMetadata(serviceBean));
|
||||
}
|
||||
|
||||
private void exportDubboMetadataConfigService() {
|
||||
|
@ -16,12 +16,9 @@
|
||||
*/
|
||||
package org.springframework.cloud.alibaba.dubbo.autoconfigure;
|
||||
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.config.spring.util.PropertySourcesUtils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.cloud.alibaba.dubbo.env.DubboCloudProperties;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
||||
@ -33,17 +30,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.spring.boot.util.DubboUtils.BASE_PACKAGES_PROPERTY_RESOLVER_BEAN_NAME;
|
||||
import static org.apache.dubbo.spring.boot.util.DubboUtils.DUBBO_SCAN_PREFIX;
|
||||
|
||||
/**
|
||||
* Spring Boot Auto-Configuration class for Dubbo Service
|
||||
@ -72,80 +60,14 @@ public class DubboServiceAutoConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459
|
||||
* Build a primary {@link PropertyResolver} bean to {@link Autowired @Autowired}
|
||||
*
|
||||
* @param environment {@link ConfigurableEnvironment}
|
||||
* @return a Bean of {@link PropertyResolver}
|
||||
* @param environment {@link Environment}
|
||||
* @return alias bean for {@link Environment}
|
||||
*/
|
||||
@Bean
|
||||
@Primary
|
||||
@Bean(name = BASE_PACKAGES_PROPERTY_RESOLVER_BEAN_NAME)
|
||||
public PropertyResolver dubboScanBasePackagesPropertyResolver(ConfigurableEnvironment environment) {
|
||||
ConfigurableEnvironment propertyResolver = new AbstractEnvironment() {
|
||||
@Override
|
||||
protected void customizePropertySources(MutablePropertySources propertySources) {
|
||||
Map<String, Object> dubboScanProperties = PropertySourcesUtils.getSubProperties(environment, DUBBO_SCAN_PREFIX);
|
||||
propertySources.addLast(new MapPropertySource("dubboScanProperties", dubboScanProperties));
|
||||
}
|
||||
};
|
||||
ConfigurationPropertySources.attach(propertyResolver);
|
||||
return new DelegatingPropertyResolver(propertyResolver);
|
||||
}
|
||||
|
||||
|
||||
private static class DelegatingPropertyResolver implements PropertyResolver {
|
||||
|
||||
private final PropertyResolver delegate;
|
||||
|
||||
DelegatingPropertyResolver(PropertyResolver delegate) {
|
||||
Assert.notNull(delegate, "The delegate of PropertyResolver must not be null");
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsProperty(String key) {
|
||||
return delegate.containsProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getProperty(String key) {
|
||||
return delegate.getProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String key, String defaultValue) {
|
||||
return delegate.getProperty(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T getProperty(String key, Class<T> targetType) {
|
||||
return delegate.getProperty(key, targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
|
||||
return delegate.getProperty(key, targetType, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequiredProperty(String key) throws IllegalStateException {
|
||||
return delegate.getRequiredProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException {
|
||||
return delegate.getRequiredProperty(key, targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolvePlaceholders(String text) {
|
||||
return delegate.resolvePlaceholders(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
|
||||
return delegate.resolveRequiredPlaceholders(text);
|
||||
}
|
||||
public PropertyResolver primaryPropertyResolver(Environment environment) {
|
||||
return environment;
|
||||
}
|
||||
}
|
@ -29,8 +29,8 @@ import org.springframework.cloud.alibaba.dubbo.http.matcher.RequestMetadataMatch
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.DubboRestServiceMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigService;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceProxy;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataService;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataServiceProxy;
|
||||
import org.springframework.cloud.alibaba.dubbo.util.JSONUtils;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
@ -88,7 +88,7 @@ public class DubboServiceMetadataRepository {
|
||||
private DubboCloudProperties dubboCloudProperties;
|
||||
|
||||
@Autowired
|
||||
private DubboMetadataConfigServiceProxy dubboMetadataConfigServiceProxy;
|
||||
private DubboMetadataServiceProxy dubboMetadataConfigServiceProxy;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
@ -255,11 +255,11 @@ public class DubboServiceMetadataRepository {
|
||||
}
|
||||
|
||||
private Set<ServiceRestMetadata> getServiceRestMetadataSet(String serviceName) {
|
||||
DubboMetadataConfigService dubboMetadataConfigService = dubboMetadataConfigServiceProxy.newProxy(serviceName);
|
||||
DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy.newProxy(serviceName);
|
||||
|
||||
Set<ServiceRestMetadata> metadata = Collections.emptySet();
|
||||
try {
|
||||
String serviceRestMetadataJsonConfig = dubboMetadataConfigService.getServiceRestMetadata();
|
||||
String serviceRestMetadataJsonConfig = dubboMetadataService.getServiceRestMetadata();
|
||||
metadata = objectMapper.readValue(serviceRestMetadataJsonConfig,
|
||||
TypeFactory.defaultInstance().constructCollectionType(LinkedHashSet.class, ServiceRestMetadata.class));
|
||||
} catch (Exception e) {
|
||||
|
@ -18,7 +18,6 @@ package org.springframework.cloud.alibaba.dubbo.registry;
|
||||
|
||||
import org.apache.dubbo.common.Constants;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.registry.NotifyListener;
|
||||
import org.apache.dubbo.registry.RegistryFactory;
|
||||
import org.apache.dubbo.registry.support.FailbackRegistry;
|
||||
@ -29,20 +28,21 @@ import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singleton;
|
||||
import static org.apache.dubbo.common.Constants.PROVIDER_SIDE;
|
||||
import static org.apache.dubbo.common.Constants.SIDE_KEY;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
/**
|
||||
* Abstract Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
|
||||
@ -144,13 +144,8 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private void filterServiceNames(Collection<String> serviceNames) {
|
||||
filter(serviceNames, new Filter<String>() {
|
||||
@Override
|
||||
public boolean accept(String serviceName) {
|
||||
return supports(serviceName);
|
||||
}
|
||||
});
|
||||
private Set<String> filterServiceNames(Collection<String> serviceNames) {
|
||||
return new LinkedHashSet<>(filter(serviceNames, this::supports));
|
||||
}
|
||||
|
||||
protected abstract boolean supports(String serviceName);
|
||||
@ -185,8 +180,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
||||
*/
|
||||
protected Set<String> getServiceNamesForOps(URL url) {
|
||||
Set<String> serviceNames = getAllServiceNames();
|
||||
filterServiceNames(serviceNames);
|
||||
return serviceNames;
|
||||
return filterServiceNames(serviceNames);
|
||||
}
|
||||
|
||||
protected abstract String getServiceName(URL url);
|
||||
@ -206,7 +200,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
||||
}
|
||||
|
||||
protected List<ServiceInstance> getServiceInstances(String serviceName) {
|
||||
return discoveryClient.getInstances(serviceName);
|
||||
return hasText(serviceName) ? discoveryClient.getInstances(serviceName) : emptyList();
|
||||
}
|
||||
|
||||
private void subscribe(final URL url, final NotifyListener listener, final Collection<String> serviceNames) {
|
||||
@ -227,67 +221,9 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
||||
*/
|
||||
protected abstract void notifySubscriber(URL url, NotifyListener listener, List<ServiceInstance> serviceInstances);
|
||||
|
||||
protected void filterHealthyInstances(Collection<ServiceInstance> instances) {
|
||||
filter(instances, new Filter<ServiceInstance>() {
|
||||
@Override
|
||||
public boolean accept(ServiceInstance data) {
|
||||
// TODO check the details of status
|
||||
// return serviceRegistry.getStatus(new DubboRegistration(data)) != null;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
protected <T> Collection<T> filter(Collection<T> collection, Predicate<T> filter) {
|
||||
return collection.stream()
|
||||
.filter(filter)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected List<URL> buildURLs(URL consumerURL, Collection<ServiceInstance> serviceInstances) {
|
||||
if (serviceInstances.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<URL> urls = new LinkedList<URL>();
|
||||
for (ServiceInstance serviceInstance : serviceInstances) {
|
||||
URL url = buildURL(serviceInstance);
|
||||
if (UrlUtils.isMatch(consumerURL, url)) {
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
private URL buildURL(ServiceInstance serviceInstance) {
|
||||
URL url = new URL(serviceInstance.getMetadata().get(Constants.PROTOCOL_KEY),
|
||||
serviceInstance.getHost(),
|
||||
serviceInstance.getPort(),
|
||||
serviceInstance.getMetadata());
|
||||
return url;
|
||||
}
|
||||
|
||||
private <T> void filter(Collection<T> collection, Filter<T> filter) {
|
||||
Iterator<T> iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
T data = iterator.next();
|
||||
if (!filter.accept(data)) { // remove if not accept
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T[] of(T... values) {
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter
|
||||
*/
|
||||
public interface Filter<T> {
|
||||
|
||||
/**
|
||||
* Tests whether or not the specified data should be accepted.
|
||||
*
|
||||
* @param data The data to be tested
|
||||
* @return <code>true</code> if and only if <code>data</code>
|
||||
* should be accepted
|
||||
*/
|
||||
boolean accept(T data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,16 +21,16 @@ import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Dubbo Metadata Configuration Service
|
||||
* Dubbo Metadata Service
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public interface DubboMetadataConfigService {
|
||||
public interface DubboMetadataService {
|
||||
|
||||
/**
|
||||
* Get The json content of {@link ServiceRestMetadata} {@link Set}
|
||||
*
|
||||
* @return the non-null String
|
||||
* @return <code>null</code> if present
|
||||
*/
|
||||
String getServiceRestMetadata();
|
||||
}
|
@ -25,17 +25,16 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* {@link DubboMetadataConfigService} exporter
|
||||
* {@link DubboMetadataService} exporter
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
@Component
|
||||
public class DubboMetadataConfigServiceExporter {
|
||||
public class DubboMetadataServiceExporter {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@ -43,7 +42,7 @@ public class DubboMetadataConfigServiceExporter {
|
||||
private ApplicationConfig applicationConfig;
|
||||
|
||||
@Autowired
|
||||
private PublishingDubboMetadataConfigService dubboMetadataConfigService;
|
||||
private DubboMetadataService dubboMetadataService;
|
||||
|
||||
@Autowired
|
||||
private Supplier<ProtocolConfig> protocolConfigSupplier;
|
||||
@ -54,10 +53,10 @@ public class DubboMetadataConfigServiceExporter {
|
||||
/**
|
||||
* The ServiceConfig of DubboMetadataConfigService to be exported, can be nullable.
|
||||
*/
|
||||
private ServiceConfig<DubboMetadataConfigService> serviceConfig;
|
||||
private ServiceConfig<DubboMetadataService> serviceConfig;
|
||||
|
||||
/**
|
||||
* export {@link DubboMetadataConfigService} as Dubbo service
|
||||
* export {@link DubboMetadataService} as Dubbo service
|
||||
*/
|
||||
public void export() {
|
||||
|
||||
@ -65,21 +64,12 @@ public class DubboMetadataConfigServiceExporter {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(dubboMetadataConfigService.getServiceRestMetadata())) {
|
||||
// If there is no REST metadata, DubboMetadataConfigService will not be exported.
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("There is no REST metadata, the Dubbo service[{}] will not be exported.",
|
||||
dubboMetadataConfigService.getClass().getName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
serviceConfig = new ServiceConfig<>();
|
||||
|
||||
serviceConfig.setInterface(DubboMetadataConfigService.class);
|
||||
serviceConfig.setInterface(DubboMetadataService.class);
|
||||
// Use current Spring application name as the Dubbo Service version
|
||||
serviceConfig.setVersion(currentApplicationName);
|
||||
serviceConfig.setRef(dubboMetadataConfigService);
|
||||
serviceConfig.setRef(dubboMetadataService);
|
||||
serviceConfig.setApplication(applicationConfig);
|
||||
serviceConfig.setProtocol(protocolConfigSupplier.get());
|
||||
|
||||
@ -92,7 +82,7 @@ public class DubboMetadataConfigServiceExporter {
|
||||
|
||||
|
||||
/**
|
||||
* unexport {@link DubboMetadataConfigService}
|
||||
* unexport {@link DubboMetadataService}
|
||||
*/
|
||||
public void unexport() {
|
||||
|
@ -22,14 +22,14 @@ import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* {@link DubboMetadataConfigService} {@link InvocationHandler}
|
||||
* {@link DubboMetadataService} {@link InvocationHandler}
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
class DubboMetadataConfigServiceInvocationHandler implements InvocationHandler {
|
||||
class DubboMetadataServiceInvocationHandler implements InvocationHandler {
|
||||
|
||||
/**
|
||||
* The method name of {@link DubboMetadataConfigService#getServiceRestMetadata()}
|
||||
* The method name of {@link DubboMetadataService#getServiceRestMetadata()}
|
||||
*/
|
||||
private static final String METHOD_NAME = "getServiceRestMetadata";
|
||||
|
||||
@ -39,8 +39,8 @@ class DubboMetadataConfigServiceInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final GenericService genericService;
|
||||
|
||||
public DubboMetadataConfigServiceInvocationHandler(String serviceName, DubboGenericServiceFactory dubboGenericServiceFactory) {
|
||||
this.genericService = dubboGenericServiceFactory.create(serviceName, DubboMetadataConfigService.class);
|
||||
public DubboMetadataServiceInvocationHandler(String serviceName, DubboGenericServiceFactory dubboGenericServiceFactory) {
|
||||
this.genericService = dubboGenericServiceFactory.create(serviceName, DubboMetadataService.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -21,27 +21,27 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import static java.lang.reflect.Proxy.newProxyInstance;
|
||||
|
||||
/**
|
||||
* The proxy of {@link DubboMetadataConfigService}
|
||||
* The proxy of {@link DubboMetadataService}
|
||||
*/
|
||||
public class DubboMetadataConfigServiceProxy implements BeanClassLoaderAware {
|
||||
public class DubboMetadataServiceProxy implements BeanClassLoaderAware {
|
||||
|
||||
private final DubboGenericServiceFactory dubboGenericServiceFactory;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public DubboMetadataConfigServiceProxy(DubboGenericServiceFactory dubboGenericServiceFactory) {
|
||||
public DubboMetadataServiceProxy(DubboGenericServiceFactory dubboGenericServiceFactory) {
|
||||
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* New proxy instance of {@link DubboMetadataConfigService} via the specified service name
|
||||
* New proxy instance of {@link DubboMetadataService} via the specified service name
|
||||
*
|
||||
* @param serviceName the service name
|
||||
* @return a {@link DubboMetadataConfigService} proxy
|
||||
* @return a {@link DubboMetadataService} proxy
|
||||
*/
|
||||
public DubboMetadataConfigService newProxy(String serviceName) {
|
||||
return (DubboMetadataConfigService) newProxyInstance(classLoader, new Class[]{DubboMetadataConfigService.class},
|
||||
new DubboMetadataConfigServiceInvocationHandler(serviceName, dubboGenericServiceFactory));
|
||||
public DubboMetadataService newProxy(String serviceName) {
|
||||
return (DubboMetadataService) newProxyInstance(classLoader, new Class[]{DubboMetadataService.class},
|
||||
new DubboMetadataServiceInvocationHandler(serviceName, dubboGenericServiceFactory));
|
||||
}
|
||||
|
||||
@Override
|
@ -27,11 +27,11 @@ import java.util.Set;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
/**
|
||||
* Publishing {@link DubboMetadataConfigService} implementation
|
||||
* Publishing {@link DubboMetadataService} implementation
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class PublishingDubboMetadataConfigService implements DubboMetadataConfigService {
|
||||
public class PublishingDubboMetadataService implements DubboMetadataService {
|
||||
|
||||
/**
|
||||
* A Map to store REST metadata temporary, its' key is the special service name for a Dubbo service,
|
@ -0,0 +1,7 @@
|
||||
# Dubbo Endpoints Default Properties is loaded by @PropertySource with low order,
|
||||
# Set enabled for Dubbo Endpoints
|
||||
management.endpoint.dubborestmetadata.enabled = true
|
||||
|
||||
# "management.endpoints.web.base-path" should not be configured in this file
|
||||
# Re-defines path-mapping of Dubbo Web Endpoints
|
||||
management.endpoints.web.path-mapping.dubborestmetadata = dubbo/rest/metadata
|
@ -6,10 +6,11 @@ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationNo
|
||||
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\
|
||||
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration
|
||||
|
||||
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\
|
||||
org.springframework.cloud.alibaba.dubbo.actuate.DubboMetadataEndpointAutoConfiguration
|
||||
|
||||
org.springframework.context.ApplicationContextInitializer=\
|
||||
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
|
||||
|
||||
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=\
|
||||
org.springframework.cloud.alibaba.dubbo.env.DubboNonWebApplicationEnvironmentPostProcessor
|
@ -29,4 +29,12 @@
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -25,4 +25,12 @@
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,6 +1,10 @@
|
||||
package org.springframework.cloud.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
@ -13,9 +17,7 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
|
||||
/**
|
||||
* @author xiaojing, Jianwei Mao
|
||||
@ -37,45 +39,44 @@ class SampleRunner implements ApplicationRunner {
|
||||
@Value("${user.age:25}")
|
||||
int userAge;
|
||||
|
||||
|
||||
@Autowired
|
||||
private NacosConfigProperties nacosConfigProperties;
|
||||
@Autowired
|
||||
private NacosConfigProperties nacosConfigProperties;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
System.out.println(String.format("Initial username=%s, userAge=%d", userName, userAge));
|
||||
System.out.println(
|
||||
String.format("Initial username=%s, userAge=%d", userName, userAge));
|
||||
|
||||
nacosConfigProperties.configServiceInstance()
|
||||
.addListener("nacos-config-example.properties", "DEFAULT_GROUP", new Listener() {
|
||||
nacosConfigProperties.configServiceInstance().addListener(
|
||||
"nacos-config-example.properties", "DEFAULT_GROUP", new Listener() {
|
||||
|
||||
/**
|
||||
* Callback with latest config data.
|
||||
*
|
||||
* For example, config data in Nacos is:
|
||||
*
|
||||
* user.name=Nacos
|
||||
* user.age=25
|
||||
*
|
||||
* @param configInfo latest config data for specific dataId in Nacos server
|
||||
*/
|
||||
@Override
|
||||
public void receiveConfigInfo(String configInfo) {
|
||||
String [] configLines = configInfo.split("\r\n");
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
for (String c : configLines) {
|
||||
String [] configPair = c.split("=");
|
||||
configs.put(configPair[0], configPair[1]);
|
||||
}
|
||||
/**
|
||||
* Callback with latest config data.
|
||||
*
|
||||
* For example, config data in Nacos is:
|
||||
*
|
||||
* user.name=Nacos user.age=25
|
||||
*
|
||||
* @param configInfo latest config data for specific dataId in Nacos
|
||||
* server
|
||||
*/
|
||||
@Override
|
||||
public void receiveConfigInfo(String configInfo) {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(new StringReader(configInfo));
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("config changed: " + properties);
|
||||
}
|
||||
|
||||
System.out.println(String.format("Latest username=%s, userAge=%s",
|
||||
configs.get("user.name"), configs.get("user.age")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getExecutor() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public Executor getExecutor() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,6 +87,7 @@ class SampleController {
|
||||
@Value("${user.name}")
|
||||
String userName;
|
||||
|
||||
|
||||
@Value("${user.age:25}")
|
||||
int age;
|
||||
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
<properties>
|
||||
<dubbo.version>2.7.0</dubbo.version>
|
||||
<spring-cloud-zookeeper.version>2.1.0.RELEASE</spring-cloud-zookeeper.version>
|
||||
<spring-cloud-consul.version>2.1.0.RELEASE</spring-cloud-consul.version>
|
||||
<spring-cloud-zookeeper.version>2.1.1.RELEASE</spring-cloud-zookeeper.version>
|
||||
<spring-cloud-consul.version>2.1.1.RELEASE</spring-cloud-consul.version>
|
||||
<curator.version>4.0.1</curator.version>
|
||||
</properties>
|
||||
|
||||
@ -96,87 +96,69 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<!-- Spring Cloud Nacos Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<profiles>
|
||||
<!-- Spring Cloud Eureka Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Nacos -->
|
||||
<profile>
|
||||
<id>nacos</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<!-- Nacos Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>eureka</id>
|
||||
<dependencies>
|
||||
<!-- Eureka Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<!-- Zookeeper -->
|
||||
<profile>
|
||||
<id>zookeeper</id>
|
||||
<dependencies>
|
||||
<!-- Zookeeper Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
|
||||
<version>${spring-cloud-zookeeper.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!-- Spring Cloud Zookeeper Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
|
||||
<version>${spring-cloud-zookeeper.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<version>3.4.12</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
<version>${curator.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<dependency>
|
||||
<groupId>org.apache.zookeeper</groupId>
|
||||
<artifactId>zookeeper</artifactId>
|
||||
<version>3.4.12</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<profile>
|
||||
<id>consul</id>
|
||||
<dependencies>
|
||||
<!-- Spring Cloud Consul -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
|
||||
<version>${spring-cloud-consul.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<dependency>
|
||||
<groupId>org.apache.curator</groupId>
|
||||
<artifactId>curator-framework</artifactId>
|
||||
<version>${curator.version}</version>
|
||||
</dependency>
|
||||
|
||||
</profiles>
|
||||
<!-- Spring Cloud Consul Service Discovery -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
|
||||
<version>${spring-cloud-consul.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
@ -21,6 +21,18 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Cloud Open Feign -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Retry -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.retry</groupId>
|
||||
<artifactId>spring-retry</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sample API -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
@ -28,11 +40,14 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Cloud Open Feign -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -80,4 +80,13 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -16,6 +16,12 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Production Ready features -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@ -30,4 +36,13 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -16,4 +16,10 @@ feign:
|
||||
enabled: true
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
port: 8080
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: dubborestmetadata
|
@ -36,4 +36,12 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,188 +1,181 @@
|
||||
//package org.springframework.cloud.alibaba.dubbo.gateway;
|
||||
//
|
||||
//import org.apache.commons.lang.StringUtils;
|
||||
//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;
|
||||
//import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContext;
|
||||
//import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||
//import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
||||
//import org.springframework.http.HttpHeaders;
|
||||
//import org.springframework.http.HttpRequest;
|
||||
//import org.springframework.util.AntPathMatcher;
|
||||
//import org.springframework.util.CollectionUtils;
|
||||
//import org.springframework.util.PathMatcher;
|
||||
//import org.springframework.util.StreamUtils;
|
||||
//import org.springframework.web.util.UriComponents;
|
||||
//
|
||||
//import javax.servlet.ServletException;
|
||||
//import javax.servlet.ServletInputStream;
|
||||
//import javax.servlet.annotation.WebServlet;
|
||||
//import javax.servlet.http.HttpServlet;
|
||||
//import javax.servlet.http.HttpServletRequest;
|
||||
//import javax.servlet.http.HttpServletResponse;
|
||||
//import java.io.IOException;
|
||||
//import java.net.URI;
|
||||
//import java.net.URISyntaxException;
|
||||
//import java.util.*;
|
||||
//
|
||||
//import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
|
||||
//
|
||||
//@WebServlet(urlPatterns = "/dsc/*")
|
||||
//public class DubboGatewayServlet extends HttpServlet {
|
||||
//
|
||||
// private final DubboServiceMetadataRepository repository;
|
||||
//
|
||||
// private final DubboTransportedMetadata dubboTransportedMetadata;
|
||||
//
|
||||
// private final DubboGenericServiceFactory serviceFactory;
|
||||
//
|
||||
// private final DubboGenericServiceExecutionContextFactory contextFactory;
|
||||
//
|
||||
// private final PathMatcher pathMatcher = new AntPathMatcher();
|
||||
//
|
||||
// public DubboGatewayServlet(DubboServiceMetadataRepository repository,
|
||||
// DubboGenericServiceFactory serviceFactory,
|
||||
// DubboGenericServiceExecutionContextFactory contextFactory) {
|
||||
// this.repository = repository;
|
||||
// this.dubboTransportedMetadata = new DubboTransportedMetadata();
|
||||
// dubboTransportedMetadata.setProtocol("dubbo");
|
||||
// dubboTransportedMetadata.setCluster("failover");
|
||||
// this.serviceFactory = serviceFactory;
|
||||
// this.contextFactory = contextFactory;
|
||||
// }
|
||||
//
|
||||
// public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
//
|
||||
// // /g/{app-name}/{rest-path}
|
||||
// String requestURI = request.getRequestURI();
|
||||
// // /g/
|
||||
// String servletPath = request.getServletPath();
|
||||
//
|
||||
// String part = StringUtils.substringAfter(requestURI, servletPath);
|
||||
//
|
||||
// String serviceName = StringUtils.substringBetween(part, "/", "/");
|
||||
//
|
||||
// // App name= spring-cloud-alibaba-dubbo-web-provider (127.0.0.1:8080)
|
||||
//
|
||||
// String restPath = StringUtils.substringAfter(part, serviceName);
|
||||
//
|
||||
// // 初始化 serviceName 的 REST 请求元数据
|
||||
// repository.initialize(serviceName);
|
||||
// // 将 HttpServletRequest 转化为 RequestMetadata
|
||||
// RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);
|
||||
//
|
||||
// DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, clientMetadata);
|
||||
//
|
||||
// if (dubboServiceMetadata == null) {
|
||||
// // if DubboServiceMetadata is not found, executes next
|
||||
// throw new ServletException("DubboServiceMetadata can't be found!");
|
||||
// }
|
||||
//
|
||||
// RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
|
||||
//
|
||||
// GenericService genericService = serviceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
|
||||
//
|
||||
// // TODO: Get the Request Body from HttpServletRequest
|
||||
// byte[] body = getRequestBody(request);
|
||||
//
|
||||
// MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(new HttpRequestAdapter(request), body);
|
||||
//
|
||||
//// customizeRequest(httpServerRequest, dubboRestMethodMetadata, clientMetadata);
|
||||
//
|
||||
// DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata, httpServerRequest);
|
||||
//
|
||||
// Object result = null;
|
||||
// GenericException exception = null;
|
||||
//
|
||||
// try {
|
||||
// result = genericService.$invoke(context.getMethodName(), context.getParameterTypes(), context.getParameters());
|
||||
// } catch (GenericException e) {
|
||||
// exception = e;
|
||||
// }
|
||||
// response.getWriter().println(result);
|
||||
// }
|
||||
//
|
||||
// private byte[] getRequestBody(HttpServletRequest request) throws IOException {
|
||||
// ServletInputStream inputStream = request.getInputStream();
|
||||
// return StreamUtils.copyToByteArray(inputStream);
|
||||
// }
|
||||
//
|
||||
// private static class HttpRequestAdapter implements HttpRequest {
|
||||
//
|
||||
// private final HttpServletRequest request;
|
||||
//
|
||||
// private HttpRequestAdapter(HttpServletRequest request) {
|
||||
// this.request = request;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getMethodValue() {
|
||||
// return request.getMethod();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public URI getURI() {
|
||||
// try {
|
||||
// return new URI(request.getRequestURL().toString() + "?" + request.getQueryString());
|
||||
// } catch (URISyntaxException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// throw new RuntimeException();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public HttpHeaders getHeaders() {
|
||||
// return new HttpHeaders();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//// protected void customizeRequest(MutableHttpServerRequest httpServerRequest,
|
||||
//// RestMethodMetadata dubboRestMethodMetadata, RequestMetadata clientMetadata) {
|
||||
////
|
||||
//// RequestMetadata dubboRequestMetadata = dubboRestMethodMetadata.getRequest();
|
||||
//// String pathPattern = dubboRequestMetadata.getPath();
|
||||
////
|
||||
//// Map<String, String> pathVariables = pathMatcher.extractUriTemplateVariables(pathPattern, httpServerRequest.getPath());
|
||||
////
|
||||
//// if (!CollectionUtils.isEmpty(pathVariables)) {
|
||||
//// // Put path variables Map into query parameters Map
|
||||
//// httpServerRequest.params(pathVariables);
|
||||
//// }
|
||||
////
|
||||
//// }
|
||||
//
|
||||
// private RequestMetadata buildRequestMetadata(HttpServletRequest request, String restPath) {
|
||||
// UriComponents uriComponents = fromUriString(request.getRequestURI()).build(true);
|
||||
// RequestMetadata requestMetadata = new RequestMetadata();
|
||||
// requestMetadata.setPath(restPath);
|
||||
// requestMetadata.setMethod(request.getMethod());
|
||||
// requestMetadata.setParams(getParams(request));
|
||||
// requestMetadata.setHeaders(getHeaders(request));
|
||||
// return requestMetadata;
|
||||
// }
|
||||
//
|
||||
// private Map<String, List<String>> getHeaders(HttpServletRequest request) {
|
||||
// Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
// Enumeration<String> headerNames = request.getHeaderNames();
|
||||
// while (headerNames.hasMoreElements()) {
|
||||
// String headerName = headerNames.nextElement();
|
||||
// Enumeration<String> headerValues = request.getHeaders(headerName);
|
||||
// map.put(headerName, Collections.list(headerValues));
|
||||
// }
|
||||
// return map;
|
||||
// }
|
||||
//
|
||||
// private Map<String, List<String>> getParams(HttpServletRequest request) {
|
||||
// Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
// for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
// map.put(entry.getKey(), Arrays.asList(entry.getValue()));
|
||||
// }
|
||||
// return map;
|
||||
// }
|
||||
//}
|
||||
package org.springframework.cloud.alibaba.dubbo.gateway;
|
||||
|
||||
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.DubboRestServiceMetadata;
|
||||
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;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContext;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.servlet.HttpServletBean;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.substringAfter;
|
||||
import static org.apache.commons.lang3.StringUtils.substringBetween;
|
||||
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
|
||||
|
||||
@WebServlet(urlPatterns = "/dsc/*")
|
||||
public class DubboGatewayServlet extends HttpServletBean {
|
||||
|
||||
private final DubboServiceMetadataRepository repository;
|
||||
|
||||
private final DubboGenericServiceFactory serviceFactory;
|
||||
|
||||
private final DubboGenericServiceExecutionContextFactory contextFactory;
|
||||
|
||||
private final PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
private final Map<String, Object> dubboTranslatedAttributes = new HashMap<>();
|
||||
|
||||
public DubboGatewayServlet(DubboServiceMetadataRepository repository,
|
||||
DubboGenericServiceFactory serviceFactory,
|
||||
DubboGenericServiceExecutionContextFactory contextFactory) {
|
||||
this.repository = repository;
|
||||
this.serviceFactory = serviceFactory;
|
||||
this.contextFactory = contextFactory;
|
||||
dubboTranslatedAttributes.put("protocol", "dubbo");
|
||||
dubboTranslatedAttributes.put("cluster", "failover");
|
||||
}
|
||||
|
||||
private String resolveServiceName(HttpServletRequest request) {
|
||||
|
||||
// /g/{app-name}/{rest-path}
|
||||
String requestURI = request.getRequestURI();
|
||||
// /g/
|
||||
String servletPath = request.getServletPath();
|
||||
|
||||
String part = substringAfter(requestURI, servletPath);
|
||||
|
||||
String serviceName = substringBetween(part, "/", "/");
|
||||
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
|
||||
String serviceName = resolveServiceName(request);
|
||||
|
||||
String restPath = substringAfter(request.getRequestURI(), serviceName);
|
||||
|
||||
// 初始化 serviceName 的 REST 请求元数据
|
||||
repository.initialize(serviceName);
|
||||
// 将 HttpServletRequest 转化为 RequestMetadata
|
||||
RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);
|
||||
|
||||
DubboRestServiceMetadata dubboRestServiceMetadata = repository.get(serviceName, clientMetadata);
|
||||
|
||||
if (dubboRestServiceMetadata == null) {
|
||||
// if DubboServiceMetadata is not found, executes next
|
||||
throw new ServletException("DubboServiceMetadata can't be found!");
|
||||
}
|
||||
|
||||
RestMethodMetadata dubboRestMethodMetadata = dubboRestServiceMetadata.getRestMethodMetadata();
|
||||
|
||||
GenericService genericService = serviceFactory.create(dubboRestServiceMetadata, dubboTranslatedAttributes);
|
||||
|
||||
// TODO: Get the Request Body from HttpServletRequest
|
||||
byte[] body = getRequestBody(request);
|
||||
|
||||
MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(new HttpRequestAdapter(request), body);
|
||||
|
||||
DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata, httpServerRequest);
|
||||
|
||||
Object result = null;
|
||||
GenericException exception = null;
|
||||
|
||||
try {
|
||||
result = genericService.$invoke(context.getMethodName(), context.getParameterTypes(), context.getParameters());
|
||||
} catch (GenericException e) {
|
||||
exception = e;
|
||||
}
|
||||
response.getWriter().println(result);
|
||||
}
|
||||
|
||||
private byte[] getRequestBody(HttpServletRequest request) throws IOException {
|
||||
ServletInputStream inputStream = request.getInputStream();
|
||||
return StreamUtils.copyToByteArray(inputStream);
|
||||
}
|
||||
|
||||
private static class HttpRequestAdapter implements HttpRequest {
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private HttpRequestAdapter(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodValue() {
|
||||
return request.getMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
try {
|
||||
return new URI(request.getRequestURL().toString() + "?" + request.getQueryString());
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return new HttpHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
private RequestMetadata buildRequestMetadata(HttpServletRequest request, String restPath) {
|
||||
UriComponents uriComponents = fromUriString(request.getRequestURI()).build(true);
|
||||
RequestMetadata requestMetadata = new RequestMetadata();
|
||||
requestMetadata.setPath(restPath);
|
||||
requestMetadata.setMethod(request.getMethod());
|
||||
requestMetadata.setParams(getParams(request));
|
||||
requestMetadata.setHeaders(getHeaders(request));
|
||||
return requestMetadata;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getHeaders(HttpServletRequest request) {
|
||||
Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String headerName = headerNames.nextElement();
|
||||
Enumeration<String> headerValues = request.getHeaders(headerName);
|
||||
map.put(headerName, Collections.list(headerValues));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getParams(HttpServletRequest request) {
|
||||
Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
map.put(entry.getKey(), Arrays.asList(entry.getValue()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public class NacosDiscoveryProperties {
|
||||
/**
|
||||
* watch delay,duration to pull new service from nacos server.
|
||||
*/
|
||||
private long watchDelay = 5000;
|
||||
private long watchDelay = 30000;
|
||||
|
||||
/**
|
||||
* nacos naming log file name
|
||||
|
Loading…
x
Reference in New Issue
Block a user