1
0
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' into binder-dev

This commit is contained in:
fangjian0423 2019-02-28 15:23:39 +08:00
commit 509d4819b3
57 changed files with 1848 additions and 304 deletions

View File

@ -34,7 +34,6 @@
<dubbo-registry-nacos.version>0.0.2</dubbo-registry-nacos.version>
<aliyun.java.sdk.dysmsapi>1.1.0</aliyun.java.sdk.dysmsapi>
<aliyun.sdk.mns>1.1.8</aliyun.sdk.mns>
<aliyun.java.sdk.dysmsapi>1.1.0</aliyun.java.sdk.dysmsapi>
<aliyun.java.sdk.dyvmsapi>1.1.1</aliyun.java.sdk.dyvmsapi>
</properties>

View File

@ -17,6 +17,9 @@
<dubbo.version>2.6.5</dubbo.version>
<dubbo-spring-boot.version>0.2.1.RELEASE</dubbo-spring-boot.version>
<dubbo-registry-nacos.version>0.0.2</dubbo-registry-nacos.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>
<curator.version>4.0.1</curator.version>
</properties>
<dependencyManagement>
@ -90,11 +93,64 @@
<optional>true</optional>
</dependency>
<!-- Eureka Service Discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-config</artifactId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<optional>true</optional>
</dependency>
<!-- Zookeeper Service Discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<version>${spring-cloud-zookeeper.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<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>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
<optional>true</optional>
</dependency>
<!-- Spring Cloud Consul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>${spring-cloud-consul.version}</version>
<optional>true</optional>
</dependency>
<!-- Nacos Service Discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Cloud Open Feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
@ -118,37 +174,6 @@
<artifactId>netty-all</artifactId>
</dependency>
<!-- REST support dependencies -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty4</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
@ -162,11 +187,6 @@
<version>9.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
@ -192,19 +212,6 @@
<scope>test</scope>
</dependency>
<!-- Nacos Service Discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<scope>test</scope>
</dependency>
<!-- Eureka Service Discovery -->
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
</dependencies>

View File

@ -33,7 +33,6 @@ import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceM
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
import org.springframework.context.annotation.Configuration;
@ -55,8 +54,8 @@ import java.util.Map;
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
@Configuration
@ConditionalOnClass(RestTemplate.class)
@AutoConfigureAfter(LoadBalancerAutoConfiguration.class)
@ConditionalOnClass(name = {"org.springframework.web.client.RestTemplate"})
@AutoConfigureAfter(name = {"org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration"})
public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClassLoaderAware {
private static final Class<DubboTransported> DUBBO_TRANSPORTED_CLASS = DubboTransported.class;

View File

@ -66,6 +66,12 @@ public class DubboMetadataAutoConfiguration {
protocolConfig = iterator.hasNext() ? iterator.next() : null;
}
if (protocolConfig == null) {
protocolConfig = new ProtocolConfig();
protocolConfig.setName(DEFAULT_PROTOCOL);
protocolConfig.setPort(20880);
}
return protocolConfig;
}

View File

@ -17,7 +17,6 @@
package org.springframework.cloud.alibaba.dubbo.autoconfigure;
import feign.Contract;
import feign.Feign;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -28,7 +27,6 @@ import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolve
import org.springframework.cloud.alibaba.dubbo.openfeign.TargeterBeanPostProcessor;
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@ -39,8 +37,8 @@ import org.springframework.core.env.Environment;
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
@ConditionalOnClass(value = Feign.class)
@AutoConfigureAfter(FeignAutoConfiguration.class)
@ConditionalOnClass(name = {"feign.Feign"})
@AutoConfigureAfter(name = {"org.springframework.cloud.openfeign.FeignAutoConfiguration"})
@Configuration
public class DubboOpenFeignAutoConfiguration {

View File

@ -84,7 +84,7 @@ public class DubboServiceBeanMetadataResolver implements BeanClassLoaderAware, S
Stream.of(CONTRACT_CLASS_NAMES)
.filter(this::isClassPresent) // filter the existed classes
.map(this::loadContractClass) // load Contract Class
.map(this::createContract) // create instance by the specified class
.map(this::createContract) // createServiceInstance instance by the specified class
.forEach(contracts::add); // add the Contract instance into contracts
this.contracts = Collections.unmodifiableCollection(contracts);

View File

@ -26,6 +26,7 @@ import org.springframework.core.env.Environment;
import static java.lang.reflect.Proxy.newProxyInstance;
import static org.springframework.util.ClassUtils.getUserClass;
import static org.springframework.util.ClassUtils.isPresent;
import static org.springframework.util.ClassUtils.resolveClassName;
/**
@ -64,12 +65,14 @@ public class TargeterBeanPostProcessor implements BeanPostProcessor, BeanClassLo
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
Class<?> beanClass = getUserClass(bean.getClass());
Class<?> targetClass = resolveClassName(TARGETER_CLASS_NAME, classLoader);
if (targetClass.isAssignableFrom(beanClass)) {
return newProxyInstance(classLoader, new Class[]{targetClass},
new TargeterInvocationHandler(bean, environment, dubboServiceMetadataRepository,
dubboGenericServiceFactory,contextFactory));
if (isPresent(TARGETER_CLASS_NAME, classLoader)) {
Class<?> beanClass = getUserClass(bean.getClass());
Class<?> targetClass = resolveClassName(TARGETER_CLASS_NAME, classLoader);
if (targetClass.isAssignableFrom(beanClass)) {
return newProxyInstance(classLoader, new Class[]{targetClass},
new TargeterInvocationHandler(bean, environment, dubboServiceMetadataRepository,
dubboGenericServiceFactory, contextFactory));
}
}
return bean;
}

View File

@ -0,0 +1,49 @@
/*
* 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.registry;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.NetUtils;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
import java.util.LinkedHashMap;
/**
* Abstract {@link RegistrationFactory} implementation
* <p>
*
* @param <T> The subclass of {@link Registration}
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public abstract class AbstractRegistrationFactory<T extends Registration> implements RegistrationFactory<T> {
protected ServiceInstance createServiceInstance(String serviceName, URL url) {
// Append default category if absent
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
String ip = NetUtils.getLocalHost();
int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceName, ip, port, false);
serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
return serviceInstance;
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.registry;
import com.alibaba.dubbo.common.URL;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.ApplicationContext;
/**
* Default {@link RegistrationFactory}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class DefaultRegistrationFactory extends AbstractRegistrationFactory<Registration> {
@Override
public Registration create(String serviceName, URL url, ApplicationContext applicationContext) {
return new DelegatingRegistration(createServiceInstance(serviceName, url));
}
}

View File

@ -27,11 +27,11 @@ import java.util.Map;
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
class DubboRegistration implements Registration {
class DelegatingRegistration implements Registration {
private final ServiceInstance delegate;
public DubboRegistration(ServiceInstance delegate) {
public DelegatingRegistration(ServiceInstance delegate) {
this.delegate = delegate;
}

View File

@ -0,0 +1,42 @@
/*
* 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.registry;
import com.alibaba.dubbo.common.URL;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.ApplicationContext;
/**
* {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
*
* @param <T> The subclass of {@link Registration}
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public interface RegistrationFactory<T extends Registration> {
/**
* Create a instance of {@link T}
*
* @param serviceName The service name of Dubbo service interface
* @param url The Dubbo's URL
* @param applicationContext {@link ApplicationContext}
* @return a instance of {@link T}
*/
T create(String serviceName, URL url, ApplicationContext applicationContext);
}

View File

@ -18,7 +18,7 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.common.utils.NamedThreadFactory;
import com.alibaba.dubbo.common.utils.UrlUtils;
import com.alibaba.dubbo.registry.NotifyListener;
import com.alibaba.dubbo.registry.RegistryFactory;
@ -26,11 +26,12 @@ import com.alibaba.dubbo.registry.support.FailbackRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.core.ResolvableType;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
@ -38,11 +39,9 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -50,6 +49,14 @@ import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY;
import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY;
import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY;
import static java.lang.Long.getLong;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.springframework.beans.BeanUtils.instantiateClass;
import static org.springframework.core.ResolvableType.forInstance;
import static org.springframework.core.ResolvableType.forType;
import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames;
import static org.springframework.util.ClassUtils.isPresent;
import static org.springframework.util.ClassUtils.resolveClassName;
/**
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
@ -70,10 +77,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
private static final int CATEGORY_INDEX = 0;
// private static final int PROTOCOL_INDEX = CATEGORY_INDEX + 1;
// private static final int SERVICE_INTERFACE_INDEX = PROTOCOL_INDEX + 1;
private static final int SERVICE_INTERFACE_INDEX = CATEGORY_INDEX + 1;
private static final int SERVICE_VERSION_INDEX = SERVICE_INTERFACE_INDEX + 1;
@ -82,34 +85,125 @@ public class SpringCloudRegistry extends FailbackRegistry {
private static final String WILDCARD = "*";
/**
* The interval in second of lookup service names(only for Dubbo-OPS)
*/
private static final long ALL_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.all.services.lookup.interval", 30);
/**
* The interval in second of lookup regigered service instances
*/
private static final long REGISTERED_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.registered.services.lookup.interval", 300);
/**
* The {@link ScheduledExecutorService Scheduler} to lookup the registered services
*/
private static final ScheduledExecutorService registeredServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-registered-services-lookup-"));
/**
* The {@link ScheduledExecutorService Scheduler} to lookup all services (only for Dubbo-OPS)
*/
private static volatile ScheduledExecutorService allServicesLookupScheduler;
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* The separator for service name
*/
private static final String SERVICE_NAME_SEPARATOR = ":";
private final ApplicationContext applicationContext;
private final ServiceRegistry<Registration> serviceRegistry;
private final DiscoveryClient discoveryClient;
private final Logger logger = LoggerFactory.getLogger(getClass());
private final RegistrationFactory registrationFactory;
/**
* {@link ScheduledExecutorService} lookup service names(only for Dubbo-OPS)
*/
private volatile ScheduledExecutorService scheduledExecutorService;
/**
* The interval in second of lookup service names(only for Dubbo-OPS)
*/
private static final long LOOKUP_INTERVAL = Long.getLong("dubbo.service.names.lookup.interval", 30);
public SpringCloudRegistry(URL url, ServiceRegistry<Registration> serviceRegistry,
DiscoveryClient discoveryClient) {
public SpringCloudRegistry(URL url, ApplicationContext applicationContext) {
super(url);
this.serviceRegistry = serviceRegistry;
this.discoveryClient = discoveryClient;
this.applicationContext = applicationContext;
this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader());
this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
applicationContext.getClassLoader();
}
private RegistrationFactory buildRegistrationFactory(ServiceRegistry<Registration> serviceRegistry,
ClassLoader classLoader) {
RegistrationFactory registrationFactory = null;
List<String> factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader);
ResolvableType serviceRegistryType = forInstance(serviceRegistry);
// Get first generic Class
Class<?> registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0);
for (String factoryClassName : factoryClassNames) {
if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue
Class<?> factoryClass = resolveClassName(factoryClassName, classLoader);
ResolvableType registrationFactoryType = forType(factoryClass);
Class<?> actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0);
if (registrationClass.equals(actualRegistrationClass)) {
registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass());
break;
}
}
}
if (registrationFactory == null) {
if (logger.isWarnEnabled()) {
logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]",
registrationClass.getSimpleName(), serviceRegistry.getClass().getName());
}
registrationFactory = new DefaultRegistrationFactory();
} else {
if (logger.isInfoEnabled()) {
logger.info("{} has been resolved by ServiceRegistry[{}]",
registrationFactory.getClass().getName(), serviceRegistry.getClass().getName());
}
}
return registrationFactory;
}
private Class<?> resolveGenericClass(ResolvableType implementedType, Class<?> interfaceClass, int index) {
ResolvableType resolvableType = implementedType;
try {
OUTER:
while (true) {
ResolvableType[] interfaceTypes = resolvableType.getInterfaces();
for (ResolvableType interfaceType : interfaceTypes) {
if (interfaceType.resolve().equals(interfaceClass)) {
resolvableType = interfaceType;
break OUTER;
}
}
ResolvableType superType = resolvableType.getSuperType();
Class<?> superClass = superType.resolve();
if (Object.class.equals(superClass)) {
break;
}
resolvableType = superType;
}
} catch (Throwable e) {
resolvableType = ResolvableType.forType(void.class);
}
return resolvableType.resolveGeneric(index);
}
@Override
protected void doRegister(URL url) {
final String serviceName = getServiceName(url);
@ -128,6 +222,12 @@ public class SpringCloudRegistry extends FailbackRegistry {
protected void doSubscribe(URL url, NotifyListener listener) {
List<String> serviceNames = getServiceNames(url, listener);
doSubscribe(url, listener, serviceNames);
this.registeredServicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
doSubscribe(url, listener, serviceNames);
}
}, REGISTERED_SERVICES_LOOKUP_INTERVAL, REGISTERED_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS);
}
@Override
@ -135,6 +235,10 @@ public class SpringCloudRegistry extends FailbackRegistry {
if (isAdminProtocol(url)) {
shutdownServiceNamesLookup();
}
// if (registeredServicesLookupScheduler != null) {
// registeredServicesLookupScheduler.shutdown();
// }
}
@Override
@ -143,25 +247,13 @@ public class SpringCloudRegistry extends FailbackRegistry {
}
private void shutdownServiceNamesLookup() {
if (scheduledExecutorService != null) {
scheduledExecutorService.shutdown();
if (allServicesLookupScheduler != null) {
allServicesLookupScheduler.shutdown();
}
}
private Registration createRegistration(String serviceName, URL url) {
return new DubboRegistration(createServiceInstance(serviceName, url));
}
private ServiceInstance createServiceInstance(String serviceName, URL url) {
// Append default category if absent
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
String ip = NetUtils.getLocalHost();
int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(serviceName, ip, port, false);
serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
return serviceInstance;
return registrationFactory.create(serviceName, url, applicationContext);
}
public static String getServiceName(URL url) {
@ -248,10 +340,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
return segments[CATEGORY_INDEX];
}
// public static String getProtocol(String[] segments) {
// return segments[PROTOCOL_INDEX];
// }
public static String getServiceInterface(String[] segments) {
return segments[SERVICE_INTERFACE_INDEX];
}
@ -288,7 +376,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
*/
private List<String> getServiceNames(URL url, NotifyListener listener) {
if (isAdminProtocol(url)) {
scheduleServiceNamesLookup(url, listener);
initAllServicesLookupScheduler(url, listener);
return getServiceNamesForOps(url);
} else {
return doGetServiceNames(url);
@ -300,10 +388,10 @@ public class SpringCloudRegistry extends FailbackRegistry {
return Constants.ADMIN_PROTOCOL.equals(url.getProtocol());
}
private void scheduleServiceNamesLookup(final URL url, final NotifyListener listener) {
if (scheduledExecutorService == null) {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) {
if (allServicesLookupScheduler == null) {
allServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-all-services-lookup-"));
allServicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
List<String> serviceNames = getAllServiceNames();
@ -323,7 +411,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
});
doSubscribe(url, listener, serviceNames);
}
}, LOOKUP_INTERVAL, LOOKUP_INTERVAL, TimeUnit.SECONDS);
}, ALL_SERVICES_LOOKUP_INTERVAL, ALL_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS);
}
}
@ -331,7 +419,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
for (String serviceName : serviceNames) {
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
notifySubscriber(url, listener, serviceInstances);
// TODO Support Update notification event
}
}

View File

@ -20,9 +20,6 @@ import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.registry.Registry;
import com.alibaba.dubbo.registry.RegistryFactory;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.context.ApplicationContext;
/**
@ -38,9 +35,7 @@ public class SpringCloudRegistryFactory implements RegistryFactory {
@Override
public Registry getRegistry(URL url) {
ServiceRegistry<Registration> serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
DiscoveryClient discoveryClient = applicationContext.getBean(DiscoveryClient.class);
return new SpringCloudRegistry(url, serviceRegistry, discoveryClient);
return new SpringCloudRegistry(url, applicationContext);
}
public static void setApplicationContext(ApplicationContext applicationContext) {

View File

@ -0,0 +1,54 @@
/*
* 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.registry.apache.zookeeper;
import com.alibaba.dubbo.common.URL;
import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
import org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance;
import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration;
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
import org.springframework.context.ApplicationContext;
/**
* Zookeeper {@link RegistrationFactory}
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory<ZookeeperRegistration> {
@Override
public ZookeeperRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
serviceInstance.getServiceId(), serviceInstance.getMetadata());
ZookeeperRegistration registration = ServiceInstanceRegistration
.builder()
.address(serviceInstance.getHost())
.name(serviceInstance.getServiceId())
.payload(zookeeperInstance)
.port(serviceInstance.getPort())
.build();
return registration;
}
}

View File

@ -0,0 +1,92 @@
/*
* 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.registry.hashicorp.consul;
import com.alibaba.dubbo.common.URL;
import com.ecwid.consul.v1.agent.model.NewService;
import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
import org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
import org.springframework.cloud.consul.serviceregistry.ConsulRegistration;
import org.springframework.context.ApplicationContext;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* {@link ConsulRegistration} {@link RegistrationFactory} implementation
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class ConsulRegistrationFactory extends AbstractRegistrationFactory<ConsulRegistration> {
@Override
public ConsulRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
Map<String, String> metadata = getMetadata(serviceInstance);
List<String> tags = createTags(metadata);
NewService service = new NewService();
service.setId(serviceInstance.getInstanceId());
service.setName(serviceInstance.getServiceId());
service.setAddress(serviceInstance.getHost());
service.setPort(serviceInstance.getPort());
service.setMeta(metadata);
service.setTags(tags);
ConsulDiscoveryProperties properties = applicationContext.getBean(ConsulDiscoveryProperties.class);
ConsulRegistration registration = new ConsulRegistration(service, properties);
return registration;
}
/**
* @param metadata
* @return
* @see ConsulServerUtils#getMetadata(java.util.List)
*/
private List<String> createTags(Map<String, String> metadata) {
List<String> tags = new LinkedList<>();
for (Map.Entry<String, String> entry : metadata.entrySet()) {
String tag = entry.getKey() + "=" + entry.getValue();
tags.add(tag);
}
return tags;
}
private Map<String, String> getMetadata(ServiceInstance serviceInstance) {
Map<String, String> metadata = serviceInstance.getMetadata();
Set<String> removedKeys = new LinkedHashSet<>();
for (String key : metadata.keySet()) {
if (key.contains(".")) {
removedKeys.add(key);
}
}
for (String removedKey : removedKeys) {
metadata.remove(removedKey);
}
return metadata;
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.registry.netflix.eureka;
import com.alibaba.dubbo.common.URL;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.discovery.EurekaClientConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
import org.springframework.context.ApplicationContext;
/**
* {@link EurekaRegistration} Factory
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class EurekaRegistrationFactory extends AbstractRegistrationFactory<EurekaRegistration> {
@Override
public EurekaRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
ObjectProvider<HealthCheckHandler> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
InetUtils inetUtils = applicationContext.getBean(InetUtils.class);
EurekaInstanceConfigBean eurekaInstanceConfigBean = new EurekaInstanceConfigBean(inetUtils);
BeanUtils.copyProperties(cloudEurekaInstanceConfig, eurekaInstanceConfigBean);
String serviceId = serviceInstance.getServiceId();
eurekaInstanceConfigBean.setInstanceId(serviceInstance.getInstanceId());
eurekaInstanceConfigBean.setVirtualHostName(serviceId);
eurekaInstanceConfigBean.setSecureVirtualHostName(serviceId);
eurekaInstanceConfigBean.setAppname(serviceId);
eurekaInstanceConfigBean.setHostname(serviceInstance.getHost());
eurekaInstanceConfigBean.setMetadataMap(serviceInstance.getMetadata());
return EurekaRegistration.builder(eurekaInstanceConfigBean)
.with(healthCheckHandler)
.with(eurekaClientConfig, applicationContext)
.build();
}
}

View File

@ -7,3 +7,9 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.context.ApplicationContextInitializer=\
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\
org.springframework.cloud.alibaba.dubbo.registry.DefaultRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.netflix.eureka.EurekaRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory

View File

@ -7,7 +7,7 @@ dubbo:
port: 12345
rest:
name: rest
port: 9090
port: 8081
server: netty
registry:
address: spring-cloud://nacos

View File

@ -7,6 +7,9 @@ spring:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
zookeeper:
enabled: false
main:
allow-bean-definition-overriding: true
@ -27,4 +30,18 @@ eureka:
client:
enabled: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
defaultZone: http://localhost:9090/eureka/
---
spring:
profiles: zookeeper
cloud:
nacos:
discovery:
enabled: false
register-enabled: false
zookeeper:
enabled: true
connect-string: localhost:2181

View File

@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RestController;
/**
* @author xiaojing
*/
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {

View File

@ -35,8 +35,10 @@
<module>fescar-example/account-service</module>
<module>acm-example/acm-local-example</module>
<module>rocketmq-example</module>
<module>sms-example</module>
<module>spring-cloud-bus-rocketmq-example</module>
<module>schedulerx-example/schedulerx-simple-task-example</module>
<module>spring-cloud-alibaba-dubbo-examples</module>
</modules>
<build>

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.cloud.examples;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xiaolongzuo
*/
@RestController
public class HelloController {
@RequestMapping("/")
@ResponseBody
public String hello() {
return "OK";
}
}

View File

@ -16,25 +16,25 @@
package org.springframework.cloud.alibaba.cloud.examples;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.edas.schedulerx.ProcessResult;
import com.alibaba.edas.schedulerx.ScxSimpleJobContext;
import com.alibaba.edas.schedulerx.ScxSimpleJobProcessor;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author xiaolongzuo
*/
public class SimpleTask implements ScxSimpleJobProcessor {
@Autowired
private TestService testService;
@Autowired
private TestService testService;
@Override
public ProcessResult process(ScxSimpleJobContext context) {
System.out.println("-----------Hello world---------------");
testService.test();
ProcessResult processResult = new ProcessResult(true);
return processResult;
}
@Override
public ProcessResult process(ScxSimpleJobContext context) {
testService.test();
ProcessResult processResult = new ProcessResult(true);
return processResult;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.cloud.examples;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xiaolongzuo
*/
@RestController
public class TestController {
static AtomicInteger atomicInteger = new AtomicInteger(0);
@RequestMapping("/test")
@ResponseBody
public String test() {
return String.valueOf(atomicInteger.get());
}
}

View File

@ -24,7 +24,7 @@ import org.springframework.stereotype.Service;
@Service
public class TestService {
public void test() {
System.out.println("---------IOC Success--------");
}
public void test() {
TestController.atomicInteger.incrementAndGet();
}
}

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba-examples</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>0.2.2.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dubbo-examples</artifactId>
<name>Spring Cloud Alibaba Dubbo Examples</name>
<packaging>pom</packaging>
<modules>
<module>spring-cloud-dubbo-sample-api</module>
<module>spring-cloud-dubbo-provider-sample</module>
<module>spring-cloud-dubbo-consumer-sample</module>
</modules>
<properties>
<dubbo.version>2.6.5</dubbo.version>
<dubbo-spring-boot.version>0.2.1.RELEASE</dubbo-spring-boot.version>
<dubbo-registry-nacos.version>0.0.2</dubbo-registry-nacos.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>
<curator.version>4.0.1</curator.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Apache Dubbo dependencies-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Cloud dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<!-- Dubbo Spring Cloud Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<profiles>
<!-- 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>
<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>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
</dependencies>
</profile>
<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>
</profiles>
</project>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba-dubbo-examples</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>0.2.2.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dubbo-consumer-sample</artifactId>
<name>Spring Cloud Dubbo Consumer Sample</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sample API -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dubbo-sample-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring Cloud Open Feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -19,6 +19,7 @@ package org.springframework.cloud.alibaba.dubbo.bootstrap;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@ -37,24 +38,20 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import java.util.HashMap;
import java.util.Map;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
/**
* Dubbo Spring Cloud Bootstrap
* Dubbo Spring Cloud Consumer Bootstrap
*/
@EnableDiscoveryClient
@EnableAutoConfiguration
@EnableFeignClients
@RestController
public class DubboSpringCloudBootstrap {
public class DubboSpringCloudConsumerBootstrap {
@Reference(version = "1.0.0")
private RestService restService;
@ -67,11 +64,14 @@ public class DubboSpringCloudBootstrap {
@Lazy
private DubboFeignRestService dubboFeignRestService;
@Value("${provider.application.name}")
private String providerApplicationName;
@Autowired
@LoadBalanced
private RestTemplate restTemplate;
@FeignClient("spring-cloud-alibaba-dubbo")
@FeignClient("${provider.application.name}")
public interface FeignRestService {
@GetMapping(value = "/param")
@ -84,8 +84,6 @@ public class DubboSpringCloudBootstrap {
User requestBody(@RequestParam("param") String param, @RequestBody Map<String, Object> data);
@GetMapping("/headers")
@Path("/headers")
@GET
public String headers(@RequestHeader("h2") String header2,
@RequestHeader("h") String header,
@RequestParam("v") Integer value);
@ -96,7 +94,7 @@ public class DubboSpringCloudBootstrap {
@RequestParam("v") String param);
}
@FeignClient("spring-cloud-alibaba-dubbo")
@FeignClient("${provider.application.name}")
@DubboTransported
public interface DubboFeignRestService {
@ -110,8 +108,6 @@ public class DubboSpringCloudBootstrap {
User requestBody(@RequestParam("param") String param, @RequestBody Map<String, Object> data);
@GetMapping("/headers")
@Path("/headers")
@GET
public String headers(@RequestHeader("h2") String header2,
@RequestParam("v") Integer value,
@RequestHeader("h") String header);
@ -122,7 +118,6 @@ public class DubboSpringCloudBootstrap {
@PathVariable("p1") String path1);
}
@Bean
public ApplicationRunner paramRunner() {
return arguments -> {
@ -154,7 +149,7 @@ public class DubboSpringCloudBootstrap {
System.out.println(feignRestService.pathVariables("b", "a", "c"));
// RestTemplate call
System.out.println(restTemplate.getForEntity("http://spring-cloud-alibaba-dubbo//path-variables/{p1}/{p2}?v=c", String.class, "a", "b"));
System.out.println(restTemplate.getForEntity("http://" + providerApplicationName + "//path-variables/{p1}/{p2}?v=c", String.class, "a", "b"));
}
private void callHeaders() {
@ -184,7 +179,7 @@ public class DubboSpringCloudBootstrap {
System.out.println(feignRestService.params("1", 1));
// RestTemplate call
System.out.println(restTemplate.getForEntity("http://spring-cloud-alibaba-dubbo/param?param=小马哥", String.class));
System.out.println(restTemplate.getForEntity("http://" + providerApplicationName + "/param?param=小马哥", String.class));
}
private void callRequestBodyMap() {
@ -202,7 +197,7 @@ public class DubboSpringCloudBootstrap {
System.out.println(feignRestService.requestBody("Hello,World", data));
// RestTemplate call
System.out.println(restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/body/map?param=小马哥", data, User.class));
System.out.println(restTemplate.postForObject("http://" + providerApplicationName + "/request/body/map?param=小马哥", data, User.class));
}
@Bean
@ -213,7 +208,8 @@ public class DubboSpringCloudBootstrap {
}
public static void main(String[] args) {
new SpringApplicationBuilder(DubboSpringCloudBootstrap.class)
new SpringApplicationBuilder(DubboSpringCloudConsumerBootstrap.class)
.profiles("nacos")
.run(args);
}
}

View File

@ -0,0 +1,5 @@
dubbo:
registry:
address: spring-cloud://nacos
server:
port: 7070

View File

@ -0,0 +1,74 @@
spring:
application:
name: spring-cloud-alibaba-dubbo-consumer
main:
allow-bean-definition-overriding: true
# default disable all
cloud:
nacos:
discovery:
enabled: false
register-enabled: false
zookeeper:
enabled: false
consul:
enabled: false
eureka:
client:
enabled: false
ribbon:
nacos:
enabled: false
provider:
application:
name: spring-cloud-alibaba-dubbo-provider
---
spring:
profiles: nacos
cloud:
nacos:
discovery:
enabled: true
register-enabled: true
server-addr: 127.0.0.1:8848
ribbon:
nacos:
enabled: true
---
spring:
profiles: eureka
eureka:
client:
enabled: true
service-url:
defaultZone: http://127.0.0.1:9090/eureka/
---
spring:
profiles: zookeeper
cloud:
zookeeper:
enabled: true
connect-string: 127.0.0.1:2181
---
spring:
profiles: consul
cloud:
consul:
enabled: true
host: 127.0.0.1
port: 8500

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba-dubbo-examples</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>0.2.2.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dubbo-provider-sample</artifactId>
<name>Spring Cloud Dubbo Provider Sample</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sample API -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dubbo-sample-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- REST support dependencies -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty4</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,38 @@
/*
* 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.bootstrap;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* Dubbo Spring Cloud Provider Bootstrap
*/
@EnableDiscoveryClient
@EnableAutoConfiguration
public class DubboSpringCloudProviderBootstrap {
public static void main(String[] args) {
new SpringApplicationBuilder(DubboSpringCloudProviderBootstrap.class)
.profiles("nacos")
.run(args);
}
}

View File

@ -20,6 +20,7 @@ import com.alibaba.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@ -40,7 +41,6 @@ import javax.ws.rs.QueryParam;
import java.util.HashMap;
import java.util.Map;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;
/**
@ -109,7 +109,7 @@ public class StandardRestService implements RestService {
}
@Override
@PostMapping(value = "/request/body/map", produces = APPLICATION_JSON_UTF8_VALUE)
@PostMapping(value = "/request/body/map", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Path("/request/body/map")
@POST
@Produces(APPLICATION_JSON_VALUE)
@ -122,11 +122,11 @@ public class StandardRestService implements RestService {
return user;
}
@PostMapping(value = "/request/body/user", consumes = APPLICATION_JSON_UTF8_VALUE)
@PostMapping(value = "/request/body/user", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Path("/request/body/user")
@POST
@Override
@Consumes(APPLICATION_JSON_UTF8_VALUE)
@Consumes(MediaType.APPLICATION_JSON_UTF8_VALUE)
public Map<String, Object> requestBodyUser(@RequestBody User user) {
Map<String, Object> map = new HashMap<>();
map.put("id", user.getId());

View File

@ -0,0 +1,20 @@
dubbo:
scan:
base-packages: org.springframework.cloud.alibaba.dubbo.service
protocols:
dubbo:
name: dubbo
port: 12345
rest:
name: rest
port: 8081
server: netty
registry:
address: spring-cloud://nacos
feign:
hystrix:
enabled: true
server:
port: 8080

View File

@ -0,0 +1,63 @@
spring:
application:
name: spring-cloud-alibaba-dubbo-provider
main:
allow-bean-definition-overriding: true
# default disable all
cloud:
nacos:
discovery:
enabled: false
register-enabled: false
zookeeper:
enabled: false
consul:
enabled: false
eureka:
client:
enabled: false
---
spring:
profiles: nacos
cloud:
nacos:
discovery:
enabled: true
register-enabled: true
server-addr: 127.0.0.1:8848
---
spring:
profiles: eureka
eureka:
client:
enabled: true
service-url:
defaultZone: http://127.0.0.1:9090/eureka/
---
spring:
profiles: zookeeper
cloud:
zookeeper:
enabled: true
connect-string: 127.0.0.1:2181
---
spring:
profiles: consul
cloud:
consul:
enabled: true
host: 127.0.0.1
port: 8500

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba-dubbo-examples</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>0.2.2.BUILD-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dubbo-sample-api</artifactId>
<name>Spring Cloud Dubbo Sample API</name>
</project>

View File

@ -19,7 +19,7 @@ package org.springframework.cloud.alibaba.dubbo.service;
import java.util.Map;
/**
* Echo Service
* Rest Service
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
@ -38,5 +38,4 @@ public interface RestService {
User requestBodyMap(Map<String, Object> data, String param);
Map<String, Object> requestBodyUser(User user);
}

View File

@ -16,21 +16,19 @@
*/
package org.springframework.cloud.alibaba.dubbo.service;
import javax.ws.rs.FormParam;
import java.io.Serializable;
/**
* User Entity
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/
public class User implements Serializable {
@FormParam("id")
private Long id;
@FormParam("name")
private String name;
@FormParam("age")
private Integer age;
public Long getId() {

View File

@ -167,7 +167,7 @@ public class NacosDiscoveryProperties {
serverAddr = Objects.toString(serverAddr, "");
if (serverAddr.lastIndexOf("/") != -1) {
serverAddr.substring(0, serverAddr.length() - 1);
serverAddr = serverAddr.substring(0, serverAddr.length() - 1);
}
endpoint = Objects.toString(endpoint, "");
namespace = Objects.toString(namespace, "");

View File

@ -67,6 +67,20 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.alicloud.acm.diagnostics.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
/**
* A {@code FailureAnalyzer} that performs analysis of failures caused by a
* {@code DiamondConnectionFailureException}.
*
* @author juven.xuxb, 07/11/2016.
*/
public class DiamondConnectionFailureAnalyzer
extends AbstractFailureAnalyzer<DiamondConnectionFailureException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure,
DiamondConnectionFailureException cause) {
return new FailureAnalysis(
"Application failed to connect to Diamond, unable to access http://"
+ cause.getDomain() + ":" + cause.getPort()
+ "/diamond-server/diamond",
"config the right endpoint", cause);
}
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.alicloud.acm.diagnostics.analyzer;
/**
* A {@code DiamondConnectionFailureException} is thrown when the application fails to
* connect to Diamond Server.
*
* @author juven.xuxb, 07/11/2016.
*/
public class DiamondConnectionFailureException extends RuntimeException {
private final String domain;
private final String port;
public DiamondConnectionFailureException(String domain, String port, String message) {
super(message);
this.domain = domain;
this.port = port;
}
public DiamondConnectionFailureException(String domain, String port, String message,
Throwable cause) {
super(message, cause);
this.domain = domain;
this.port = port;
}
String getDomain() {
return domain;
}
String getPort() {
return port;
}
}

View File

@ -4,6 +4,3 @@ org.springframework.cloud.alicloud.acm.bootstrap.AcmPropertySourceLocator
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.alicloud.acm.AcmAutoConfiguration,\
org.springframework.cloud.alicloud.acm.endpoint.AcmEndpointAutoConfiguration
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.cloud.alicloud.acm.diagnostics.analyzer.DiamondConnectionFailureAnalyzer

View File

@ -0,0 +1,191 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.alicloud.acm;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import com.alibaba.edas.acm.ConfigService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.MethodProxy;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.alicloud.acm.bootstrap.AcmPropertySourceLocator;
import org.springframework.cloud.alicloud.acm.endpoint.AcmEndpointAutoConfiguration;
import org.springframework.cloud.alicloud.context.acm.AcmContextBootstrapConfiguration;
import org.springframework.cloud.alicloud.context.acm.AcmIntegrationProperties;
import org.springframework.cloud.alicloud.context.acm.AcmProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author xiaojing
*/
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest({ ConfigService.class })
@SpringBootTest(classes = AcmConfigurationTests.TestConfig.class, properties = {
"spring.application.name=test-name", "spring.profiles.active=dev,test",
"spring.cloud.alicloud.acm.server-list=127.0.0.1",
"spring.cloud.alicloud.acm.server-port=8848",
"spring.cloud.alicloud.acm.endpoint=test-endpoint",
"spring.cloud.alicloud.acm.namespace=test-namespace",
"spring.cloud.alicloud.acm.timeout=1000",
"spring.cloud.alicloud.acm.group=test-group",
"spring.cloud.alicloud.acm.refresh-enabled=false",
"spring.cloud.alicloud.acm.file-extension=properties" }, webEnvironment = NONE)
public class AcmConfigurationTests {
static {
try {
Method method = PowerMockito.method(ConfigService.class, "getConfig",
String.class, String.class, long.class);
MethodProxy.proxy(method, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("test-name.properties".equals(args[0])
&& "test-group".equals(args[1])) {
return "user.name=hello\nuser.age=12";
}
if ("test-name-dev.properties".equals(args[0])
&& "test-group".equals(args[1])) {
return "user.name=dev";
}
return "";
}
});
}
catch (Exception ignore) {
ignore.printStackTrace();
}
}
@Autowired
private Environment environment;
@Autowired
private AcmPropertySourceLocator locator;
@Autowired
private AcmIntegrationProperties integrationProperties;
@Autowired
private AcmProperties properties;
@Test
public void contextLoads() throws Exception {
assertNotNull("AcmPropertySourceLocator was not created", locator);
assertNotNull("AcmProperties was not created", properties);
assertNotNull("AcmIntegrationProperties was not created", integrationProperties);
checkoutAcmServerAddr();
checkoutAcmServerPort();
checkoutAcmEndpoint();
checkoutAcmNamespace();
checkoutAcmGroup();
checkoutAcmFileExtension();
checkoutAcmTimeout();
checkoutAcmProfiles();
checkoutAcmRefreshEnabled();
checkoutDataLoad();
}
private void checkoutAcmServerAddr() {
assertEquals("AcmProperties server address is wrong", "127.0.0.1",
properties.getServerList());
}
private void checkoutAcmServerPort() {
assertEquals("AcmProperties server port is wrong", "8848",
properties.getServerPort());
}
private void checkoutAcmEndpoint() {
assertEquals("AcmProperties endpoint is wrong", "test-endpoint",
properties.getEndpoint());
}
private void checkoutAcmNamespace() {
assertEquals("AcmProperties namespace is wrong", "test-namespace",
properties.getNamespace());
}
private void checkoutAcmGroup() {
assertEquals("AcmProperties' group is wrong", "test-group",
properties.getGroup());
}
private void checkoutAcmFileExtension() {
assertEquals("AcmProperties' file extension is wrong", "properties",
properties.getFileExtension());
}
private void checkoutAcmTimeout() {
assertEquals("AcmProperties' timeout is wrong", 1000, properties.getTimeout());
}
private void checkoutAcmRefreshEnabled() {
assertEquals("AcmProperties' refresh enabled is wrong", false,
properties.isRefreshEnabled());
}
private void checkoutAcmProfiles() {
assertArrayEquals("AcmProperties' profiles is wrong",
new String[] { "dev", "test" },
integrationProperties.getActiveProfiles());
}
private void checkoutDataLoad() {
Assert.assertEquals(environment.getProperty("user.name"), "dev");
Assert.assertEquals(environment.getProperty("user.age"), "12");
}
@Configuration
@EnableAutoConfiguration
@ImportAutoConfiguration({ AcmEndpointAutoConfiguration.class,
AcmAutoConfiguration.class, AcmContextBootstrapConfiguration.class })
public static class TestConfig {
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 the original author or authors.
*
* Licensed 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.alicloud.acm;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import com.alibaba.edas.acm.ConfigService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.MethodProxy;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.alicloud.acm.endpoint.AcmEndpointAutoConfiguration;
import org.springframework.cloud.alicloud.context.acm.AcmContextBootstrapConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
/**
* @author xiaojing
*/
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest({ ConfigService.class })
@SpringBootTest(classes = AcmGroupConfigurationTest.TestConfig.class, properties = {
"spring.application.name=test-name", "spring.application.group=com.test.hello",
"spring.cloud.alicloud.acm.server-list=127.0.0.1",
"spring.cloud.alicloud.acm.server-port=8080",
"spring.cloud.alicloud.acm.timeout=1000",
"spring.cloud.alicloud.acm.group=test-group" }, webEnvironment = NONE)
public class AcmGroupConfigurationTest {
static {
try {
Method method = PowerMockito.method(ConfigService.class, "getConfig",
String.class, String.class, long.class);
MethodProxy.proxy(method, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("com.test:application.properties".equals(args[0])
&& "test-group".equals(args[1])) {
return "com.test.value=com.test";
}
if ("com.test.hello:application.properties".equals(args[0])
&& "test-group".equals(args[1])) {
return "com.test.hello.value=com.test.hello";
}
return "";
}
});
}
catch (Exception ignore) {
ignore.printStackTrace();
}
}
@Autowired
private Environment environment;
@Test
public void contextLoads() throws Exception {
Assert.assertEquals(environment.getProperty("com.test.value"), "com.test");
Assert.assertEquals(environment.getProperty("com.test.hello.value"),
"com.test.hello");
}
@Configuration
@EnableAutoConfiguration
@ImportAutoConfiguration({ AcmEndpointAutoConfiguration.class,
AcmAutoConfiguration.class, AcmContextBootstrapConfiguration.class })
public static class TestConfig {
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.alicloud.acm.endpoint;
import static org.junit.Assert.assertEquals;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.api.support.MethodProxy;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health.Builder;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.alicloud.acm.AcmAutoConfiguration;
import org.springframework.cloud.alicloud.acm.AcmPropertySourceRepository;
import org.springframework.cloud.alicloud.acm.bootstrap.AcmPropertySourceLocator;
import org.springframework.cloud.alicloud.acm.refresh.AcmRefreshHistory;
import org.springframework.cloud.alicloud.context.acm.AcmContextBootstrapConfiguration;
import org.springframework.cloud.alicloud.context.acm.AcmIntegrationProperties;
import org.springframework.cloud.alicloud.context.acm.AcmProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;
import com.alibaba.edas.acm.ConfigService;
/**
* @author xiaojing
*/
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PrepareForTest({ ConfigService.class })
@SpringBootTest(classes = AcmEndpointTests.TestConfig.class, properties = {
"spring.application.name=test-name",
"spring.cloud.alicloud.acm.server-list=127.0.0.1",
"spring.cloud.alicloud.acm.server-port=8848",
"spring.cloud.alicloud.acm.file-extension=properties" }, webEnvironment = NONE)
public class AcmEndpointTests {
static {
try {
Method method = PowerMockito.method(ConfigService.class, "getConfig",
String.class, String.class, long.class);
MethodProxy.proxy(method, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("test-name.properties".equals(args[0])
&& "DEFAULT_GROUP".equals(args[1])) {
return "user.name=hello\nuser.age=12";
}
return "";
}
});
}
catch (Exception ignore) {
ignore.printStackTrace();
}
}
@Autowired
private AcmProperties properties;
@Autowired
private AcmRefreshHistory refreshHistory;
@Autowired
private AcmPropertySourceRepository propertySourceRepository;
@Autowired
private AcmPropertySourceRepository acmPropertySourceRepository;
@Test
public void contextLoads() throws Exception {
checkoutEndpoint();
checkoutAcmHealthIndicator();
}
private void checkoutAcmHealthIndicator() {
try {
Builder builder = new Builder();
AcmHealthIndicator healthIndicator = new AcmHealthIndicator(properties,
acmPropertySourceRepository);
healthIndicator.doHealthCheck(builder);
Builder builder1 = new Builder();
List<String> dataIds = new ArrayList<>();
dataIds.add("test-name.properties");
builder1.up().withDetail("dataIds", dataIds);
Assert.assertTrue(builder.build().equals(builder1.build()));
}
catch (Exception ignoreE) {
}
}
private void checkoutEndpoint() throws Exception {
AcmEndpoint acmEndpoint = new AcmEndpoint(properties, refreshHistory,
propertySourceRepository);
Map<String, Object> map = acmEndpoint.invoke();
assertEquals(map.get("config"), properties);
assertEquals(((Map) map.get("runtime")).get("refreshHistory"),
refreshHistory.getRecords());
}
@Configuration
@EnableAutoConfiguration
@ImportAutoConfiguration({ AcmEndpointAutoConfiguration.class,
AcmAutoConfiguration.class, AcmContextBootstrapConfiguration.class })
public static class TestConfig {
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.alicloud.ans.registry;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.alicloud.ans.AnsAutoConfiguration;
import org.springframework.cloud.alicloud.ans.AnsDiscoveryClientAutoConfiguration;
import org.springframework.cloud.alicloud.context.ans.AnsProperties;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author xiaojing
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AnsAutoServiceRegistrationEnabledTests.TestConfig.class, properties = {
"spring.application.name=myTestService1",
"spring.cloud.alicloud.ans.server-list=127.0.0.1",
"spring.cloud.alicloud.ans.server-port=8080",
"spring.cloud.alicloud.ans.register-enabled=false" }, webEnvironment = RANDOM_PORT)
public class AnsAutoServiceRegistrationEnabledTests {
@Autowired
private AnsRegistration registration;
@Autowired
private AnsAutoServiceRegistration ansAutoServiceRegistration;
@Autowired
private AnsProperties properties;
@Test
public void contextLoads() throws Exception {
assertNotNull("AnsRegistration was not created", registration);
assertNotNull("AnsProperties was not created", properties);
assertNotNull("AnsAutoServiceRegistration was not created",
ansAutoServiceRegistration);
checkEnabled();
}
private void checkEnabled() {
assertFalse("Ans Auto Registration should not start",
ansAutoServiceRegistration.isEnabled());
}
@Configuration
@EnableAutoConfiguration
@ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class,
AnsDiscoveryClientAutoConfiguration.class, AnsAutoConfiguration.class })
public static class TestConfig {
}
}

View File

@ -40,7 +40,9 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AnsAutoServiceRegistrationIpTests.TestConfig.class, properties = {
"spring.application.name=myTestService1",
"spring.cloud.alicloud.ans.client-domains=myTestService2",
"spring.cloud.alicloud.ans.server-list=127.0.0.1",
"spring.cloud.alicloud.ans.client-weight=2",
"spring.cloud.alicloud.ans.server-port=8080",
"spring.cloud.alicloud.ans.client-ip=123.123.123.123" }, webEnvironment = RANDOM_PORT)
public class AnsAutoServiceRegistrationIpTests {
@ -63,13 +65,22 @@ public class AnsAutoServiceRegistrationIpTests {
ansAutoServiceRegistration);
checkoutAnsDiscoveryServiceIP();
checkoutAnsDiscoveryServiceName();
checkoutAnsDiscoveryWeight();
}
private void checkoutAnsDiscoveryServiceIP() {
assertEquals("AnsProperties service IP was wrong", "123.123.123.123",
registration.getHost());
}
private void checkoutAnsDiscoveryServiceName() {
assertEquals("AnsDiscoveryProperties service name was wrong", "myTestService2",
properties.getClientDomains());
}
private void checkoutAnsDiscoveryWeight() {
assertEquals(2L, properties.getClientWeight(), 0);
}
@Configuration

View File

@ -54,6 +54,7 @@ import org.springframework.test.context.junit4.SpringRunner;
"spring.application.name=myTestService1",
"spring.cloud.alicloud.ans.server-list=127.0.0.1",
"spring.cloud.alicloud.ans.server-port=8080",
"spring.cloud.alicloud.ans.secure=true",
"spring.cloud.alicloud.ans.endpoint=test-endpoint" }, webEnvironment = RANDOM_PORT)
public class AnsAutoServiceRegistrationTests {
@ -86,6 +87,7 @@ public class AnsAutoServiceRegistrationTests {
checkoutAnsDiscoveryServiceName();
checkoutAnsDiscoveryServiceIP();
checkoutAnsDiscoveryServicePort();
checkoutAnsDiscoverySecure();
checkAutoRegister();
@ -101,31 +103,31 @@ public class AnsAutoServiceRegistrationTests {
private void checkoutAnsDiscoveryServerList() {
assertEquals("AnsDiscoveryProperties server list was wrong", "127.0.0.1",
properties.getServerList());
}
private void checkoutAnsDiscoveryServerPort() {
assertEquals("AnsDiscoveryProperties server port was wrong", "8080",
properties.getServerPort());
}
private void checkoutAnsDiscoveryServiceName() {
assertEquals("AnsDiscoveryProperties service name was wrong", "myTestService1",
properties.getClientDomains());
}
private void checkoutAnsDiscoveryServiceIP() {
assertEquals("AnsDiscoveryProperties service IP was wrong",
inetUtils.findFirstNonLoopbackHostInfo().getIpAddress(),
registration.getHost());
}
private void checkoutAnsDiscoveryServicePort() {
assertEquals("AnsDiscoveryProperties service Port was wrong", port,
registration.getPort());
}
private void checkoutAnsDiscoverySecure() {
assertTrue("AnsDiscoveryProperties secure should be true", properties.isSecure());
}

View File

@ -88,6 +88,10 @@ public class AcmIntegrationProperties {
this.activeProfiles = activeProfiles;
}
public String[] getActiveProfiles() {
return activeProfiles;
}
public void setAcmProperties(AcmProperties acmProperties) {
this.acmProperties = acmProperties;
}

View File

@ -15,15 +15,15 @@
*/
package org.springframework.cloud.alicloud.context.nacos;
import com.alibaba.cloud.context.edas.EdasChangeOrderConfiguration;
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.cloud.alicloud.context.listener.AbstractOnceApplicationListener;
import java.util.Properties;
import com.alibaba.cloud.context.edas.EdasChangeOrderConfiguration;
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
/**
* @author pbting
@ -54,7 +54,7 @@ public class NacosDiscoveryParameterInitListener
}
// initialize nacos configuration
Properties properties = System.getProperties();
properties.setProperty("spring.cloud.nacos.discovery.server-mode", "EDAS");
// step 1: set some properties for spring cloud alibaba nacos discovery
properties.setProperty("spring.cloud.nacos.discovery.server-addr", "");
properties.setProperty("spring.cloud.nacos.discovery.endpoint",

View File

@ -31,13 +31,33 @@ import com.aliyun.oss.ClientBuilderConfiguration;
@ConfigurationProperties("spring.cloud.alicloud.oss")
public class OssProperties {
/**
* Authorization Mode, please see <a href=
* "https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.659.29f145dc3KOwTh">oss
* docs</a>.
*/
@Value("${spring.cloud.alicloud.oss.authorization-mode:AK_SK}")
private AliCloudAuthorizationMode authorizationMode;
/**
* Endpoint, please see <a href=
* "https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.659.29f145dc3KOwTh">oss
* docs</a>.
*/
private String endpoint;
/**
* Sts token, please see <a href=
* "https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.659.29f145dc3KOwTh">oss
* docs</a>.
*/
private StsToken sts;
/**
* Client Configuration, please see <a href=
* "https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.659.29f145dc3KOwTh">oss
* docs</a>.
*/
private ClientBuilderConfiguration config;
public AliCloudAuthorizationMode getAuthorizationMode() {

View File

@ -26,8 +26,18 @@ import com.alibaba.cloud.context.scx.ScxConfiguration;
@ConfigurationProperties("spring.cloud.alicloud.scx")
public class ScxProperties implements ScxConfiguration {
/**
* Group id, please see <a href=
* "https://help.aliyun.com/document_detail/35359.html?spm=a2c4g.11186623.6.721.69ca5763p9IJly">scx
* docs</a>.
*/
private String groupId;
/**
* Domain name, please see <a href=
* "https://help.aliyun.com/document_detail/35359.html?spm=a2c4g.11186623.6.721.69ca5763p9IJly">scx
* docs</a>.
*/
private String domainName;
@Override

View File

@ -48,7 +48,9 @@ public class StatisticsTaskStarter implements InitializingBean {
private static final String NACOS_CONFIG_SERVER_MODE_KEY = "spring.cloud.nacos.config.server-mode";
private static final String NACOS_CONFIG_SERVER_MODE_VALUE = "EDAS";
private static final String NACOS_DISCOVERY_SERVER_MODE_KEY = "spring.cloud.nacos.discovery.server-mode";
private static final String NACOS_SERVER_MODE_VALUE = "EDAS";
@Autowired(required = false)
private AliCloudEdasSdk aliCloudEdasSdk;
@ -106,10 +108,14 @@ public class StatisticsTaskStarter implements InitializingBean {
if (acmContextBootstrapConfiguration != null && acmEnableEdas) {
components.add("SC-ACM");
}
if (NACOS_CONFIG_SERVER_MODE_VALUE
if (NACOS_SERVER_MODE_VALUE
.equals(System.getProperty(NACOS_CONFIG_SERVER_MODE_KEY))) {
components.add("SC-NACOS-CONFIG");
}
if (NACOS_SERVER_MODE_VALUE
.equals(System.getProperty(NACOS_DISCOVERY_SERVER_MODE_KEY))) {
components.add("SC-NACOS-DISCOVERY");
}
return components;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed 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.nacos;
/**
* @author xiaolongzuo
*/
public class NacosDiscoveryAutoConfiguration {
}

View File

@ -16,8 +16,7 @@
package org.springframework.cloud.alicloud.context.nacos;
import com.alibaba.cloud.context.ans.AliCloudAnsInitializer;
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.junit.BeforeClass;
import org.junit.Test;
@ -25,35 +24,39 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.springframework.cloud.alicloud.context.BaseAliCloudSpringApplication;
import org.springframework.cloud.alicloud.utils.ChangeOrderUtils;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import com.alibaba.cloud.context.ans.AliCloudAnsInitializer;
import com.alibaba.cloud.context.edas.EdasChangeOrderConfigurationFactory;
/**
* @author xiaolongzuo
*/
@PrepareForTest({EdasChangeOrderConfigurationFactory.class,
NacosConfigParameterInitListener.class, AliCloudAnsInitializer.class})
public class NacosDiscoveryParameterInitListenerTests extends BaseAliCloudSpringApplication {
@PrepareForTest({ EdasChangeOrderConfigurationFactory.class,
NacosDiscoveryParameterInitListener.class, AliCloudAnsInitializer.class })
public class NacosDiscoveryParameterInitListenerTests
extends BaseAliCloudSpringApplication {
@BeforeClass
public static void setUp() {
ChangeOrderUtils.mockChangeOrder();
System.getProperties().setProperty("webContext", "/vipserver");
System.getProperties().setProperty("serverPort", "80");
}
@BeforeClass
public static void setUp() {
ChangeOrderUtils.mockChangeOrder();
}
@Test
public void testNacosParameterInitListener() {
assertThat(System.getProperty("spring.cloud.nacos.config.server-addr"))
.isEqualTo("");
assertThat(System.getProperty("spring.cloud.nacos.config.endpoint"))
.isEqualTo("testDomain");
assertThat(System.getProperty("spring.cloud.nacos.config.namespace"))
.isEqualTo("testTenantId");
assertThat(System.getProperty("spring.cloud.nacos.config.access-key"))
.isEqualTo("testAK");
assertThat(System.getProperty("spring.cloud.nacos.config.secret-key"))
.isEqualTo("testSK");
assertThat(System.getProperties().getProperty("webContext")).isEqualTo("/vipserver");
assertThat(System.getProperties().getProperty("serverPort")).isEqualTo("80");
}
@Test
public void testNacosParameterInitListener() {
assertThat(System.getProperty("spring.cloud.nacos.discovery.server-mode"))
.isEqualTo("EDAS");
assertThat(System.getProperty("spring.cloud.nacos.discovery.server-addr"))
.isEqualTo("");
assertThat(System.getProperty("spring.cloud.nacos.discovery.endpoint"))
.isEqualTo("testDomain");
assertThat(System.getProperty("spring.cloud.nacos.discovery.namespace"))
.isEqualTo("testTenantId");
assertThat(System.getProperty("spring.cloud.nacos.discovery.access-key"))
.isEqualTo("testAK");
assertThat(System.getProperty("spring.cloud.nacos.discovery.secret-key"))
.isEqualTo("testSK");
assertThat(System.getProperties().getProperty("nacos.naming.web.context"))
.isEqualTo("/vipserver");
assertThat(System.getProperties().getProperty("nacos.naming.exposed.port"))
.isEqualTo("80");
}
}

View File

@ -39,10 +39,6 @@
<groupId>com.aliyun.mns</groupId>
<artifactId>aliyun-sdk-mns</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>