diff --git a/.gitignore b/.gitignore index 942b16d3..15395b04 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ hs_err_pid* .settings target .DS_Store +.flattened-pom.xml diff --git a/pom.xml b/pom.xml index 40c7f148..a6a035d9 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ - 2.0.2.RELEASE + 2.0.3.RELEASE 2.0.4.RELEASE diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml index 4174a590..f07b95fc 100644 --- a/spring-cloud-alibaba-dependencies/pom.xml +++ b/spring-cloud-alibaba-dependencies/pom.xml @@ -18,12 +18,13 @@ Spring Cloud Alibaba Dependencies - 2.0.2.RELEASE - 1.7.1 - 1.1.0 - 1.2.1 + 2.0.3.RELEASE + + 1.8.0 + 1.3.0 + 1.3.3 0.8.0 - 1.0.6 + 1.0.10 2.2.1 diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/dependency-management.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/dependency-management.adoc index 1a8ef37e..7114bb3c 100644 --- a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/dependency-management.adoc +++ b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/dependency-management.adoc @@ -10,7 +10,7 @@ Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本。 com.alibaba.cloud spring-cloud-alibaba-dependencies - 2.0.2.RELEASE + 2.0.3.RELEASE pom import diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc/dependency-management.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc/dependency-management.adoc index e4d19476..3f205fc8 100644 --- a/spring-cloud-alibaba-docs/src/main/asciidoc/dependency-management.adoc +++ b/spring-cloud-alibaba-docs/src/main/asciidoc/dependency-management.adoc @@ -8,7 +8,7 @@ If you’re a Maven Central user, add our BOM to your pom.xml com.alibaba.cloud spring-cloud-alibaba-dependencies - 2.0.2.RELEASE + 2.0.3.RELEASE pom import diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/NacosDataSourceProperties.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/NacosDataSourceProperties.java index e0aa9e74..08790ac4 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/NacosDataSourceProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/NacosDataSourceProperties.java @@ -32,6 +32,10 @@ public class NacosDataSourceProperties extends AbstractDataSourceProperties { private String serverAddr; + private String username; + + private String password; + @NotEmpty private String groupId = "DEFAULT_GROUP"; @@ -67,6 +71,22 @@ public class NacosDataSourceProperties extends AbstractDataSourceProperties { this.serverAddr = serverAddr; } + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + public String getGroupId() { return groupId; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java index a5049660..1d73e8ba 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java @@ -93,7 +93,7 @@ public class RedisDataSourceProperties extends AbstractDataSourceProperties { "RedisDataSource channel can not be empty"); } - if (!StringUtils.isEmpty(masterId) && StringUtils.isEmpty(masterId)) { + if (StringUtils.isEmpty(masterId)) { throw new IllegalArgumentException( "RedisDataSource sentinel model,masterId can not be empty"); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java index f94c5fc6..8fac117a 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java @@ -35,6 +35,10 @@ public class NacosDataSourceFactoryBean implements FactoryBean private String serverAddr; + private String username; + + private String password; + private String groupId; private String dataId; @@ -63,6 +67,12 @@ public class NacosDataSourceFactoryBean implements FactoryBean if (!StringUtils.isEmpty(this.namespace)) { properties.setProperty(PropertyKeyConst.NAMESPACE, this.namespace); } + if (!StringUtils.isEmpty(this.username)) { + properties.setProperty(PropertyKeyConst.USERNAME, this.username); + } + if (!StringUtils.isEmpty(this.password)) { + properties.setProperty(PropertyKeyConst.PASSWORD, this.password); + } return new NacosDataSource(properties, groupId, dataId, converter); } @@ -78,7 +88,23 @@ public class NacosDataSourceFactoryBean implements FactoryBean public void setServerAddr(String serverAddr) { this.serverAddr = serverAddr; } + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + public String getGroupId() { return groupId; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/scg/SentinelSCGAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/scg/SentinelSCGAutoConfiguration.java index f5003be3..9c900091 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/scg/SentinelSCGAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/scg/SentinelSCGAutoConfiguration.java @@ -92,7 +92,8 @@ public class SentinelSCGAutoConfiguration { } private void initAppType() { - System.setProperty(SentinelConfig.APP_TYPE, ConfigConstants.APP_TYPE_SCG_GATEWAY); + System.setProperty(SentinelConfig.APP_TYPE_PROP_KEY, + ConfigConstants.APP_TYPE_SCG_GATEWAY); } private void initFallback() { diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/zuul/SentinelZuulAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/zuul/SentinelZuulAutoConfiguration.java index 6b2a2653..9e32c413 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/zuul/SentinelZuulAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-gateway/src/main/java/com/alibaba/cloud/sentinel/gateway/zuul/SentinelZuulAutoConfiguration.java @@ -65,7 +65,7 @@ public class SentinelZuulAutoConfiguration { private void init() { requestOriginParserOptional .ifPresent(ZuulGatewayCallbackManager::setOriginParser); - System.setProperty(SentinelConfig.APP_TYPE, + System.setProperty(SentinelConfig.APP_TYPE_PROP_KEY, String.valueOf(ConfigConstants.APP_TYPE_ZUUL_GATEWAY)); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java index 1eae17f4..4827aebf 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -487,8 +486,7 @@ public class NacosConfigProperties { List result = new ArrayList<>(); configList.stream() .collect(Collectors.groupingBy(cfg -> (cfg.getGroup() + cfg.getDataId()), - () -> new ConcurrentHashMap<>(new LinkedHashMap<>()), - Collectors.toList())) + LinkedHashMap::new, Collectors.toList())) .forEach((key, list) -> { list.stream() .reduce((a, b) -> new Config(a.getDataId(), a.getGroup(), diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataPropertiesParser.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataPropertiesParser.java index 315caccb..6dec190e 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataPropertiesParser.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataPropertiesParser.java @@ -55,7 +55,9 @@ public class NacosDataPropertiesParser extends AbstractNacosDataParser { log.warn("the config data is invalid {}", dataLine); continue; } - result.put(dataLine.substring(0, index), dataLine.substring(index + 1)); + String key = dataLine.substring(0, index); + String value = dataLine.substring(index + 1); + result.put(key.trim(), value.trim()); } } return result; diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressBothLevelTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressBothLevelTests.java index d0e13489..2079f9f4 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressBothLevelTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressBothLevelTests.java @@ -34,9 +34,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author lyuzb */ @RunWith(SpringRunner.class) -@SpringBootTest( - classes = NacosConfigPropertiesServerAddressBothLevelTests.TestConfig.class, - properties = { "spring.cloud.nacos.config.server-addr=321,321,321,321:8848", +@SpringBootTest(classes = NacosConfigPropertiesServerAddressBothLevelTests.TestConfig.class, properties = { + "spring.cloud.nacos.config.server-addr=321,321,321,321:8848", "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, webEnvironment = RANDOM_PORT) public class NacosConfigPropertiesServerAddressBothLevelTests { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressTopLevelTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressTopLevelTests.java index c080fe6b..f79ff133 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressTopLevelTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigPropertiesServerAddressTopLevelTests.java @@ -34,10 +34,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author lyuzb */ @RunWith(SpringRunner.class) -@SpringBootTest( - classes = NacosConfigPropertiesServerAddressTopLevelTests.TestConfig.class, - properties = { "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosConfigPropertiesServerAddressTopLevelTests.TestConfig.class, properties = { + "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, webEnvironment = RANDOM_PORT) public class NacosConfigPropertiesServerAddressTopLevelTests { @Autowired diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationExtConfigTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationExtConfigTests.java index 73f8b80f..9a3789d2 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationExtConfigTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosConfigurationExtConfigTests.java @@ -50,9 +50,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosConfigService.class }) -@SpringBootTest(classes = NacosConfigurationExtConfigTests.TestConfig.class, - properties = { "spring.application.name=myTestService1", - "spring.profiles.active=dev,test", +@SpringBootTest(classes = NacosConfigurationExtConfigTests.TestConfig.class, properties = { + "spring.application.name=myTestService1", "spring.profiles.active=dev,test", "spring.cloud.nacos.config.server-addr=127.0.0.1:8848", "spring.cloud.nacos.config.encode=utf-8", "spring.cloud.nacos.config.timeout=1000", diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosFileExtensionTest.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosFileExtensionTest.java index 22961051..6b672f58 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosFileExtensionTest.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/NacosFileExtensionTest.java @@ -49,8 +49,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosConfigService.class }) -@SpringBootTest(classes = NacosFileExtensionTest.TestConfig.class, - properties = { "spring.application.name=test-name", +@SpringBootTest(classes = NacosFileExtensionTest.TestConfig.class, properties = { + "spring.application.name=test-name", "spring.cloud.nacos.config.server-addr=127.0.0.1:8848", "spring.cloud.nacos.config.file-extension=yaml" }, webEnvironment = NONE) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/endpoint/NacosConfigEndpointTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/endpoint/NacosConfigEndpointTests.java index 810137cf..025520d0 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/endpoint/NacosConfigEndpointTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/test/java/com/alibaba/cloud/nacos/endpoint/NacosConfigEndpointTests.java @@ -51,8 +51,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosConfigService.class }) -@SpringBootTest(classes = NacosConfigEndpointTests.TestConfig.class, - properties = { "spring.application.name=test-name", +@SpringBootTest(classes = NacosConfigEndpointTests.TestConfig.class, properties = { + "spring.application.name=test-name", "spring.cloud.nacos.config.server-addr=127.0.0.1:8848", "spring.cloud.nacos.config.file-extension=properties" }, webEnvironment = NONE) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ConditionalOnNacosDiscoveryEnabled.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ConditionalOnNacosDiscoveryEnabled.java index 18c4db13..2f4e4a19 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ConditionalOnNacosDiscoveryEnabled.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ConditionalOnNacosDiscoveryEnabled.java @@ -25,8 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) -@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.enabled", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.enabled", matchIfMissing = true) public @interface ConditionalOnNacosDiscoveryEnabled { } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java index 5b283c9a..bdb79ac2 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java @@ -19,7 +19,6 @@ package com.alibaba.cloud.nacos; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; -import java.net.SocketException; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -30,9 +29,7 @@ import java.util.regex.Pattern; import javax.annotation.PostConstruct; -import com.alibaba.nacos.api.NacosFactory; -import com.alibaba.nacos.api.naming.NamingMaintainFactory; -import com.alibaba.nacos.api.naming.NamingMaintainService; +import com.alibaba.cloud.nacos.event.NacosDiscoveryInfoChangedEvent; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.PreservedMetadataKeys; import com.alibaba.nacos.client.naming.utils.UtilAndComs; @@ -44,6 +41,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.commons.util.InetUtils; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; @@ -64,19 +62,17 @@ import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME; * @author xiaojing * @author Mercy * @author lyuzb + * @author eshun */ - @ConfigurationProperties("spring.cloud.nacos.discovery") public class NacosDiscoveryProperties { - private static final Logger log = LoggerFactory - .getLogger(NacosDiscoveryProperties.class); - /** * Prefix of {@link NacosDiscoveryProperties}. */ public static final String PREFIX = "spring.cloud.nacos.discovery"; - + private static final Logger log = LoggerFactory + .getLogger(NacosDiscoveryProperties.class); private static final Pattern PATTERN = Pattern.compile("-(\\w)"); /** @@ -199,18 +195,30 @@ public class NacosDiscoveryProperties { */ private Integer ipDeleteTimeout; + /** + * If instance is enabled to accept request. The default value is true. + */ + private boolean instanceEnabled = true; + + /** + * If instance is ephemeral.The default value is true. + */ + private boolean ephemeral = true; + @Autowired private InetUtils inetUtils; @Autowired private Environment environment; - private static NamingService namingService; + @Autowired + private NacosServiceManager nacosServiceManager; - private static NamingMaintainService namingMaintainService; + @Autowired + private ApplicationEventPublisher applicationEventPublisher; @PostConstruct - public void init() throws SocketException { + public void init() throws Exception { metadata.put(PreservedMetadataKeys.REGISTER_SOURCE, "SPRING_CLOUD"); if (secure) { @@ -257,6 +265,19 @@ public class NacosDiscoveryProperties { } this.overrideFromEnv(environment); + if (nacosServiceManager.isNacosDiscoveryInfoChanged(this)) { + applicationEventPublisher + .publishEvent(new NacosDiscoveryInfoChangedEvent(this)); + } + } + + /** + * recommend to use {@link NacosServiceManager#getNamingService(Properties)}. + * @return NamingService + */ + @Deprecated + public NamingService namingServiceInstance() { + return nacosServiceManager.getNamingService(this.getNacosProperties()); } public String getEndpoint() { @@ -447,6 +468,58 @@ public class NacosDiscoveryProperties { this.password = password; } + public boolean isInstanceEnabled() { + return instanceEnabled; + } + + public void setInstanceEnabled(boolean instanceEnabled) { + this.instanceEnabled = instanceEnabled; + } + + public boolean isEphemeral() { + return ephemeral; + } + + public void setEphemeral(boolean ephemeral) { + this.ephemeral = ephemeral; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NacosDiscoveryProperties that = (NacosDiscoveryProperties) o; + return Objects.equals(serverAddr, that.serverAddr) + && Objects.equals(username, that.username) + && Objects.equals(password, that.password) + && Objects.equals(endpoint, that.endpoint) + && Objects.equals(namespace, that.namespace) + && Objects.equals(logName, that.logName) + && Objects.equals(service, that.service) + && Objects.equals(clusterName, that.clusterName) + && Objects.equals(group, that.group) && Objects.equals(ip, that.ip) + && Objects.equals(port, that.port) + && Objects.equals(networkInterface, that.networkInterface) + && Objects.equals(accessKey, that.accessKey) + && Objects.equals(secretKey, that.secretKey) + && Objects.equals(heartBeatInterval, that.heartBeatInterval) + && Objects.equals(heartBeatTimeout, that.heartBeatTimeout) + && Objects.equals(ipDeleteTimeout, that.ipDeleteTimeout); + } + + @Override + public int hashCode() { + return Objects.hash(serverAddr, username, password, endpoint, namespace, + watchDelay, logName, service, weight, clusterName, group, + namingLoadCacheAtStart, registerEnabled, ip, networkInterface, port, + secure, accessKey, secretKey, heartBeatInterval, heartBeatTimeout, + ipDeleteTimeout, instanceEnabled, ephemeral); + } + @Override public String toString() { return "NacosDiscoveryProperties{" + "serverAddr='" + serverAddr + '\'' @@ -510,41 +583,7 @@ public class NacosDiscoveryProperties { } } - public NamingService namingServiceInstance() { - - if (null != namingService) { - return namingService; - } - - try { - namingService = NacosFactory.createNamingService(getNacosProperties()); - } - catch (Exception e) { - log.error("create naming service error!properties={},e=,", this, e); - return null; - } - return namingService; - } - - @Deprecated - public NamingMaintainService namingMaintainServiceInstance() { - - if (null != namingMaintainService) { - return namingMaintainService; - } - - try { - namingMaintainService = NamingMaintainFactory - .createMaintainService(getNacosProperties()); - } - catch (Exception e) { - log.error("create naming service error!properties={},e=,", this, e); - return null; - } - return namingMaintainService; - } - - private Properties getNacosProperties() { + public Properties getNacosProperties() { Properties properties = new Properties(); properties.put(SERVER_ADDR, serverAddr); properties.put(USERNAME, Objects.toString(username, "")); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceAutoConfiguration.java new file mode 100644 index 00000000..04b09d76 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceAutoConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.nacos; + +import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author yuhuangbin + */ +@Configuration +@ConditionalOnDiscoveryEnabled +@ConditionalOnNacosDiscoveryEnabled +public class NacosServiceAutoConfiguration { + + @Bean + public NacosServiceManager nacosServiceManager() { + return new NacosServiceManager(); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceInstance.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceInstance.java index 1db22449..fb467ef1 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceInstance.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceInstance.java @@ -42,21 +42,37 @@ public class NacosServiceInstance implements ServiceInstance { return serviceId; } + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + @Override public String getHost() { return host; } + public void setHost(String host) { + this.host = host; + } + @Override public int getPort() { return port; } + public void setPort(int port) { + this.port = port; + } + @Override public boolean isSecure() { return secure; } + public void setSecure(boolean secure) { + this.secure = secure; + } + @Override public URI getUri() { return DefaultServiceInstance.getUri(this); @@ -67,22 +83,6 @@ public class NacosServiceInstance implements ServiceInstance { return metadata; } - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - public void setHost(String host) { - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - public void setMetadata(Map metadata) { this.metadata = metadata; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceManager.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceManager.java new file mode 100644 index 00000000..c672bbac --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosServiceManager.java @@ -0,0 +1,134 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.nacos; + +import java.util.Objects; +import java.util.Properties; + +import com.alibaba.cloud.nacos.registry.NacosRegistration; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingMaintainService; +import com.alibaba.nacos.api.naming.NamingService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.context.event.EventListener; + +import static com.alibaba.nacos.api.NacosFactory.createMaintainService; +import static com.alibaba.nacos.api.NacosFactory.createNamingService; +import static org.springframework.beans.BeanUtils.copyProperties; + +/** + * @author yuhuangbin + */ +public class NacosServiceManager { + + private static final Logger log = LoggerFactory.getLogger(NacosServiceManager.class); + + private NacosDiscoveryProperties nacosDiscoveryPropertiesCache; + + private NamingService namingService; + + private NamingMaintainService namingMaintainService; + + public NamingService getNamingService(Properties properties) { + if (Objects.isNull(this.namingService)) { + buildNamingService(properties); + } + return namingService; + } + + public NamingMaintainService getNamingMaintainService(Properties properties) { + if (Objects.isNull(namingMaintainService)) { + buildNamingMaintainService(properties); + } + return namingMaintainService; + } + + public boolean isNacosDiscoveryInfoChanged( + NacosDiscoveryProperties nacosDiscoveryProperties) { + if (Objects.isNull(nacosDiscoveryPropertiesCache) + || this.nacosDiscoveryPropertiesCache.equals(nacosDiscoveryProperties)) { + return false; + } + copyProperties(nacosDiscoveryProperties, nacosDiscoveryPropertiesCache); + return true; + } + + private NamingMaintainService buildNamingMaintainService(Properties properties) { + if (Objects.isNull(namingMaintainService)) { + synchronized (NacosServiceManager.class) { + if (Objects.isNull(namingMaintainService)) { + namingMaintainService = createNamingMaintainService(properties); + } + } + } + return namingMaintainService; + } + + private NamingService buildNamingService(Properties properties) { + if (Objects.isNull(namingService)) { + synchronized (NacosServiceManager.class) { + if (Objects.isNull(namingService)) { + namingService = createNewNamingService(properties); + } + } + } + return namingService; + } + + private NamingService createNewNamingService(Properties properties) { + try { + return createNamingService(properties); + } + catch (NacosException e) { + throw new RuntimeException(e); + } + } + + private NamingMaintainService createNamingMaintainService(Properties properties) { + try { + return createMaintainService(properties); + } + catch (NacosException e) { + throw new RuntimeException(e); + } + } + + public void nacosServiceShutDown() throws NacosException { + this.namingService.shutDown(); + namingService = null; + namingMaintainService = null; + } + + @EventListener + public void onInstancePreRegisteredEvent( + InstancePreRegisteredEvent instancePreRegisteredEvent) { + Registration registration = instancePreRegisteredEvent.getRegistration(); + if (Objects.isNull(nacosDiscoveryPropertiesCache) + && registration instanceof NacosRegistration) { + NacosDiscoveryProperties nacosDiscoveryProperties = ((NacosRegistration) registration) + .getNacosDiscoveryProperties(); + + nacosDiscoveryPropertiesCache = new NacosDiscoveryProperties(); + copyProperties(nacosDiscoveryProperties, nacosDiscoveryPropertiesCache); + } + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryAutoConfiguration.java index 0af3a187..748942b6 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryAutoConfiguration.java @@ -18,6 +18,7 @@ package com.alibaba.cloud.nacos.discovery; import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; @@ -41,8 +42,9 @@ public class NacosDiscoveryAutoConfiguration { @Bean @ConditionalOnMissingBean public NacosServiceDiscovery nacosServiceDiscovery( - NacosDiscoveryProperties discoveryProperties) { - return new NacosServiceDiscovery(discoveryProperties); + NacosDiscoveryProperties discoveryProperties, + NacosServiceManager nacosServiceManager) { + return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClient.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClient.java index d446e292..f410c538 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClient.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClient.java @@ -32,13 +32,11 @@ import org.springframework.cloud.client.discovery.DiscoveryClient; */ public class NacosDiscoveryClient implements DiscoveryClient { - private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryClient.class); - /** * Nacos Discovery Client Description. */ public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client"; - + private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryClient.class); private NacosServiceDiscovery serviceDiscovery; public NacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java index 893b9e69..b0dd3628 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosDiscoveryClientConfiguration.java @@ -18,6 +18,7 @@ package com.alibaba.cloud.nacos.discovery; import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -38,9 +39,8 @@ import org.springframework.scheduling.TaskScheduler; */ @Configuration @ConditionalOnDiscoveryEnabled -//@ConditionalOnBlockingDiscoveryEnabled -@ConditionalOnProperty(value = "spring.cloud.discovery.blocking.enabled", - matchIfMissing = true) +// @ConditionalOnBlockingDiscoveryEnabled +@ConditionalOnProperty(value = "spring.cloud.discovery.blocking.enabled", matchIfMissing = true) @ConditionalOnNacosDiscoveryEnabled @AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class }) @@ -55,11 +55,12 @@ public class NacosDiscoveryClientConfiguration { @Bean @ConditionalOnMissingBean - @ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", - matchIfMissing = true) - public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties, - ObjectProvider taskScheduler) { - return new NacosWatch(nacosDiscoveryProperties, taskScheduler); + @ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", matchIfMissing = true) + public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager, + NacosDiscoveryProperties nacosDiscoveryProperties, + ObjectProvider taskExecutorObjectProvider) { + return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties, + taskExecutorObjectProvider); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java index ffe73aaf..5a15bdcf 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscovery.java @@ -23,7 +23,9 @@ import java.util.Map; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.NacosServiceInstance; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ListView; @@ -36,33 +38,12 @@ public class NacosServiceDiscovery { private NacosDiscoveryProperties discoveryProperties; - public NacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties) { + private NacosServiceManager nacosServiceManager; + + public NacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties, + NacosServiceManager nacosServiceManager) { this.discoveryProperties = discoveryProperties; - } - - /** - * Return all instances for the given service. - * @param serviceId id of service - * @return list of instances - * @throws NacosException nacosException - */ - public List getInstances(String serviceId) throws NacosException { - String group = discoveryProperties.getGroup(); - List instances = discoveryProperties.namingServiceInstance() - .selectInstances(serviceId, group, true); - return hostToServiceInstanceList(instances, serviceId); - } - - /** - * Return the names of all services. - * @return list of service names - * @throws NacosException nacosException - */ - public List getServices() throws NacosException { - String group = discoveryProperties.getGroup(); - ListView services = discoveryProperties.namingServiceInstance() - .getServicesOfServer(1, Integer.MAX_VALUE, group); - return services.getData(); + this.nacosServiceManager = nacosServiceManager; } public static List hostToServiceInstanceList( @@ -92,7 +73,10 @@ public class NacosServiceDiscovery { metadata.put("nacos.weight", instance.getWeight() + ""); metadata.put("nacos.healthy", instance.isHealthy() + ""); metadata.put("nacos.cluster", instance.getClusterName() + ""); - metadata.putAll(instance.getMetadata()); + if (instance.getMetadata() != null) { + metadata.putAll(instance.getMetadata()); + } + metadata.put("nacos.ephemeral", String.valueOf(instance.isEphemeral())); nacosServiceInstance.setMetadata(metadata); if (metadata.containsKey("secure")) { @@ -102,4 +86,34 @@ public class NacosServiceDiscovery { return nacosServiceInstance; } + /** + * Return all instances for the given service. + * @param serviceId id of service + * @return list of instances + * @throws NacosException nacosException + */ + public List getInstances(String serviceId) throws NacosException { + String group = discoveryProperties.getGroup(); + List instances = namingService().selectInstances(serviceId, group, + true); + return hostToServiceInstanceList(instances, serviceId); + } + + /** + * Return the names of all services. + * @return list of service names + * @throws NacosException nacosException + */ + public List getServices() throws NacosException { + String group = discoveryProperties.getGroup(); + ListView services = namingService().getServicesOfServer(1, + Integer.MAX_VALUE, group); + return services.getData(); + } + + private NamingService namingService() { + return nacosServiceManager + .getNamingService(discoveryProperties.getNacosProperties()); + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java index d10ef0a5..b0c0c48c 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/NacosWatch.java @@ -16,11 +16,23 @@ package com.alibaba.cloud.nacos.discovery; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.listener.Event; +import com.alibaba.nacos.api.naming.listener.EventListener; +import com.alibaba.nacos.api.naming.listener.NamingEvent; +import com.alibaba.nacos.api.naming.pojo.Instance; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,47 +46,31 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** * @author xiaojing + * @author yuhuangbin */ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycle { private static final Logger log = LoggerFactory.getLogger(NacosWatch.class); - - private final NacosDiscoveryProperties properties; - - private final TaskScheduler taskScheduler; - - private final AtomicLong nacosWatchIndex = new AtomicLong(0); - private final AtomicBoolean running = new AtomicBoolean(false); - + private final AtomicLong nacosWatchIndex = new AtomicLong(0); + private final NacosDiscoveryProperties properties; + private final TaskScheduler taskScheduler; + private Map listenerMap = new ConcurrentHashMap<>(16); private ApplicationEventPublisher publisher; - private ScheduledFuture watchFuture; + private NacosServiceManager nacosServiceManager; - public NacosWatch(NacosDiscoveryProperties properties) { - this(properties, getTaskScheduler()); - } - - public NacosWatch(NacosDiscoveryProperties properties, TaskScheduler taskScheduler) { - this.properties = properties; - this.taskScheduler = taskScheduler; - } - - /** - * The constructor with {@link NacosDiscoveryProperties} bean and the optional. - * {@link TaskScheduler} bean - * @param properties {@link NacosDiscoveryProperties} bean - * @param taskScheduler the optional {@link TaskScheduler} bean - * @since 2.2.0 - */ - public NacosWatch(NacosDiscoveryProperties properties, + public NacosWatch(NacosServiceManager nacosServiceManager, + NacosDiscoveryProperties properties, ObjectProvider taskScheduler) { - this(properties, taskScheduler.getIfAvailable(NacosWatch::getTaskScheduler)); + this.nacosServiceManager = nacosServiceManager; + this.properties = properties; + this.taskScheduler = taskScheduler.getIfAvailable(NacosWatch::getTaskScheduler); } private static ThreadPoolTaskScheduler getTaskScheduler() { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); - taskScheduler.setBeanName("Nacso-Watch-Task-Scheduler"); + taskScheduler.setBeanName("Nacos-Watch-Task-Scheduler"); taskScheduler.initialize(); return taskScheduler; } @@ -98,19 +94,75 @@ public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycl @Override public void start() { if (this.running.compareAndSet(false, true)) { + EventListener eventListener = listenerMap.computeIfAbsent(buildKey(), + event -> new EventListener() { + @Override + public void onEvent(Event event) { + if (event instanceof NamingEvent) { + List instances = ((NamingEvent) event) + .getInstances(); + Optional instanceOptional = selectCurrentInstance( + instances); + instanceOptional.ifPresent(currentInstance -> { + resetIfNeeded(currentInstance); + }); + } + } + }); + + NamingService namingService = nacosServiceManager + .getNamingService(properties.getNacosProperties()); + try { + namingService.subscribe(properties.getService(), properties.getGroup(), + Arrays.asList(properties.getClusterName()), eventListener); + } + catch (Exception e) { + log.error("namingService subscribe failed, properties:{}", properties, e); + } + this.watchFuture = this.taskScheduler.scheduleWithFixedDelay( this::nacosServicesWatch, this.properties.getWatchDelay()); } } + private String buildKey() { + return String.join(":", properties.getService(), properties.getGroup()); + } + + private void resetIfNeeded(Instance instance) { + if (!properties.getMetadata().equals(instance.getMetadata())) { + properties.setMetadata(instance.getMetadata()); + } + } + + private Optional selectCurrentInstance(List instances) { + return instances.stream() + .filter(instance -> properties.getIp().equals(instance.getIp()) + && properties.getPort() == instance.getPort()) + .findFirst(); + } + @Override public void stop() { - if (this.running.compareAndSet(true, false) && this.watchFuture != null) { - // shutdown current user-thread, - // then the other daemon-threads will terminate automatic. - ((ThreadPoolTaskScheduler) this.taskScheduler).shutdown(); + if (this.running.compareAndSet(true, false)) { + if (this.watchFuture != null) { + // shutdown current user-thread, + // then the other daemon-threads will terminate automatic. + ((ThreadPoolTaskScheduler) this.taskScheduler).shutdown(); + this.watchFuture.cancel(true); + } - this.watchFuture.cancel(true); + EventListener eventListener = listenerMap.get(buildKey()); + try { + NamingService namingService = nacosServiceManager + .getNamingService(properties.getNacosProperties()); + namingService.unsubscribe(properties.getService(), properties.getGroup(), + Arrays.asList(properties.getClusterName()), eventListener); + } + catch (NacosException e) { + log.error("namingService unsubscribe failed, properties:{}", properties, + e); + } } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java index 5a925ec3..ea63c583 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java @@ -26,7 +26,6 @@ import org.springframework.boot.actuate.health.HealthIndicator; * The {@link HealthIndicator} for Nacos Discovery. * * @author Mercy - * @since 2.2.0 * @see HealthIndicator */ public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/configclient/NacosDiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/configclient/NacosDiscoveryClientConfigServiceBootstrapConfiguration.java index 08ab5c12..f50aca92 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/configclient/NacosDiscoveryClientConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/configclient/NacosDiscoveryClientConfigServiceBootstrapConfiguration.java @@ -31,11 +31,10 @@ import org.springframework.context.annotation.Configuration; * @author JevonYang */ @ConditionalOnClass(ConfigServicePropertySourceLocator.class) -@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", - matchIfMissing = false) +@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false) @Configuration @ImportAutoConfiguration({ NacosDiscoveryAutoConfiguration.class, - NacosDiscoveryClientConfiguration.class}) + NacosDiscoveryClientConfiguration.class }) public class NacosDiscoveryClientConfigServiceBootstrapConfiguration { } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpoint.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpoint.java index a824675e..9f88830e 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpoint.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpoint.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import org.slf4j.Logger; @@ -41,9 +42,13 @@ public class NacosDiscoveryEndpoint { private static final Logger log = LoggerFactory .getLogger(NacosDiscoveryEndpoint.class); + private NacosServiceManager nacosServiceManager; + private NacosDiscoveryProperties nacosDiscoveryProperties; - public NacosDiscoveryEndpoint(NacosDiscoveryProperties nacosDiscoveryProperties) { + public NacosDiscoveryEndpoint(NacosServiceManager nacosServiceManager, + NacosDiscoveryProperties nacosDiscoveryProperties) { + this.nacosServiceManager = nacosServiceManager; this.nacosDiscoveryProperties = nacosDiscoveryProperties; } @@ -55,7 +60,8 @@ public class NacosDiscoveryEndpoint { Map result = new HashMap<>(); result.put("NacosDiscoveryProperties", nacosDiscoveryProperties); - NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); + NamingService namingService = nacosServiceManager + .getNamingService(nacosDiscoveryProperties.getNacosProperties()); List subscribe = Collections.emptyList(); try { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java index ff3b65f3..de581564 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java @@ -16,8 +16,11 @@ package com.alibaba.cloud.nacos.endpoint; +import java.util.Properties; + import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.discovery.actuate.health.NacosDiscoveryHealthIndicator; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; @@ -44,16 +47,19 @@ public class NacosDiscoveryEndpointAutoConfiguration { @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public NacosDiscoveryEndpoint nacosDiscoveryEndpoint( + NacosServiceManager nacosServiceManager, NacosDiscoveryProperties nacosDiscoveryProperties) { - return new NacosDiscoveryEndpoint(nacosDiscoveryProperties); + return new NacosDiscoveryEndpoint(nacosServiceManager, nacosDiscoveryProperties); } @Bean @ConditionalOnEnabledHealthIndicator("nacos-discovery") public HealthIndicator nacosDiscoveryHealthIndicator( + NacosServiceManager nacosServiceManager, NacosDiscoveryProperties nacosDiscoveryProperties) { + Properties nacosProperties = nacosDiscoveryProperties.getNacosProperties(); return new NacosDiscoveryHealthIndicator( - nacosDiscoveryProperties.namingServiceInstance()); + nacosServiceManager.getNamingService(nacosProperties)); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/event/NacosDiscoveryInfoChangedEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/event/NacosDiscoveryInfoChangedEvent.java new file mode 100644 index 00000000..4e922e81 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/event/NacosDiscoveryInfoChangedEvent.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.nacos.event; + +import com.alibaba.cloud.nacos.NacosDiscoveryProperties; + +import org.springframework.context.ApplicationEvent; + +/** + * @author yuhuangbin + */ +public class NacosDiscoveryInfoChangedEvent extends ApplicationEvent { + + public NacosDiscoveryInfoChangedEvent( + NacosDiscoveryProperties nacosDiscoveryProperties) { + super(nacosDiscoveryProperties); + } + + @Override + public NacosDiscoveryProperties getSource() { + return (NacosDiscoveryProperties) super.getSource(); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistration.java index 649ddd67..097ddc85 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistration.java @@ -16,6 +16,7 @@ package com.alibaba.cloud.nacos.registry; +import com.alibaba.cloud.nacos.event.NacosDiscoveryInfoChangedEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,6 +24,7 @@ import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegis import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.context.event.EventListener; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -102,4 +104,14 @@ public class NacosAutoServiceRegistration return StringUtils.isEmpty(appName) ? super.getAppName() : appName; } + @EventListener + public void onNacosDiscoveryInfoChangedEvent(NacosDiscoveryInfoChangedEvent event) { + restart(); + } + + private void restart() { + this.stop(); + this.start(); + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistration.java index aac1b82f..0d76e62b 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistration.java @@ -17,12 +17,12 @@ package com.alibaba.cloud.nacos.registry; import java.net.URI; +import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; -import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.PreservedMetadataKeys; import org.springframework.cloud.client.DefaultServiceInstance; @@ -58,16 +58,30 @@ public class NacosRegistration implements Registration, ServiceInstance { */ public static final String MANAGEMENT_ENDPOINT_BASE_PATH = "management.endpoints.web.base-path"; + private List registrationCustomizers; + private NacosDiscoveryProperties nacosDiscoveryProperties; private ApplicationContext context; - public NacosRegistration(NacosDiscoveryProperties nacosDiscoveryProperties, + public NacosRegistration(List registrationCustomizers, + NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) { + this.registrationCustomizers = registrationCustomizers; this.nacosDiscoveryProperties = nacosDiscoveryProperties; this.context = context; } + private static void customize( + List registrationCustomizers, + NacosRegistration registration) { + if (registrationCustomizers != null) { + for (NacosRegistrationCustomizer customizer : registrationCustomizers) { + customizer.customize(registration); + } + } + } + @PostConstruct public void init() { @@ -105,6 +119,7 @@ public class NacosRegistration implements Registration, ServiceInstance { metadata.put(PreservedMetadataKeys.IP_DELETE_TIMEOUT, nacosDiscoveryProperties.getIpDeleteTimeout().toString()); } + customize(registrationCustomizers, this); } @Override @@ -157,10 +172,6 @@ public class NacosRegistration implements Registration, ServiceInstance { return nacosDiscoveryProperties; } - public NamingService getNacosNamingService() { - return nacosDiscoveryProperties.namingServiceInstance(); - } - @Override public String toString() { return "NacosRegistration{" + "nacosDiscoveryProperties=" diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistrationCustomizer.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistrationCustomizer.java new file mode 100644 index 00000000..e0437602 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosRegistrationCustomizer.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.nacos.registry; + +/** + * @author L.cm + */ +public interface NacosRegistrationCustomizer { + + /** + * customize NacosRegistration. + * @param registration NacosRegistration + */ + void customize(NacosRegistration registration); + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java index b0974a55..0efd8642 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java @@ -17,13 +17,17 @@ package com.alibaba.cloud.nacos.registry; import java.util.List; +import java.util.Properties; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; +import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.util.StringUtils; @@ -33,6 +37,7 @@ import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; /** * @author xiaojing * @author Mercy + * @author eshun */ public class NacosServiceRegistry implements ServiceRegistry { @@ -40,11 +45,11 @@ public class NacosServiceRegistry implements ServiceRegistry { private final NacosDiscoveryProperties nacosDiscoveryProperties; - private final NamingService namingService; + @Autowired + private NacosServiceManager nacosServiceManager; public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) { this.nacosDiscoveryProperties = nacosDiscoveryProperties; - this.namingService = nacosDiscoveryProperties.namingServiceInstance(); } @Override @@ -55,6 +60,7 @@ public class NacosServiceRegistry implements ServiceRegistry { return; } + NamingService namingService = namingService(); String serviceId = registration.getServiceId(); String group = nacosDiscoveryProperties.getGroup(); @@ -84,7 +90,7 @@ public class NacosServiceRegistry implements ServiceRegistry { return; } - NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); + NamingService namingService = namingService(); String serviceId = registration.getServiceId(); String group = nacosDiscoveryProperties.getGroup(); @@ -102,7 +108,12 @@ public class NacosServiceRegistry implements ServiceRegistry { @Override public void close() { - + try { + nacosServiceManager.nacosServiceShutDown(); + } + catch (NacosException e) { + log.error("Nacos namingService shutDown failed", e); + } } @Override @@ -125,7 +136,8 @@ public class NacosServiceRegistry implements ServiceRegistry { } try { - nacosDiscoveryProperties.namingMaintainServiceInstance() + Properties nacosProperties = nacosDiscoveryProperties.getNacosProperties(); + nacosServiceManager.getNamingMaintainService(nacosProperties) .updateInstance(serviceId, instance); } catch (Exception e) { @@ -139,8 +151,7 @@ public class NacosServiceRegistry implements ServiceRegistry { String serviceName = registration.getServiceId(); try { - List instances = nacosDiscoveryProperties.namingServiceInstance() - .getAllInstances(serviceName); + List instances = namingService().getAllInstances(serviceName); for (Instance instance : instances) { if (instance.getIp().equalsIgnoreCase(nacosDiscoveryProperties.getIp()) && instance.getPort() == nacosDiscoveryProperties.getPort()) { @@ -160,9 +171,15 @@ public class NacosServiceRegistry implements ServiceRegistry { instance.setPort(registration.getPort()); instance.setWeight(nacosDiscoveryProperties.getWeight()); instance.setClusterName(nacosDiscoveryProperties.getClusterName()); + instance.setEnabled(nacosDiscoveryProperties.isInstanceEnabled()); instance.setMetadata(registration.getMetadata()); - + instance.setEphemeral(nacosDiscoveryProperties.isEphemeral()); return instance; } + private NamingService namingService() { + return nacosServiceManager + .getNamingService(nacosDiscoveryProperties.getNacosProperties()); + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.java index 5ff6fa22..1b00f5bc 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.java @@ -16,10 +16,13 @@ package com.alibaba.cloud.nacos.registry; +import java.util.List; + import com.alibaba.cloud.nacos.ConditionalOnNacosDiscoveryEnabled; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -38,8 +41,7 @@ import org.springframework.context.annotation.Configuration; @Configuration @EnableConfigurationProperties @ConditionalOnNacosDiscoveryEnabled -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class, AutoServiceRegistrationAutoConfiguration.class, NacosDiscoveryAutoConfiguration.class }) @@ -54,9 +56,11 @@ public class NacosServiceRegistryAutoConfiguration { @Bean @ConditionalOnBean(AutoServiceRegistrationProperties.class) public NacosRegistration nacosRegistration( + ObjectProvider> registrationCustomizers, NacosDiscoveryProperties nacosDiscoveryProperties, ApplicationContext context) { - return new NacosRegistration(nacosDiscoveryProperties, context); + return new NacosRegistration(registrationCustomizers.getIfAvailable(), + nacosDiscoveryProperties, context); } @Bean diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ribbon/NacosRule.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ribbon/NacosRule.java index db0a6d9c..8d705b04 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ribbon/NacosRule.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/ribbon/NacosRule.java @@ -21,6 +21,7 @@ import java.util.Objects; import java.util.stream.Collectors; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.netflix.client.config.IClientConfig; @@ -47,16 +48,20 @@ public class NacosRule extends AbstractLoadBalancerRule { @Autowired private NacosDiscoveryProperties nacosDiscoveryProperties; + @Autowired + private NacosServiceManager nacosServiceManager; + @Override public Server choose(Object key) { try { String clusterName = this.nacosDiscoveryProperties.getClusterName(); + String group = this.nacosDiscoveryProperties.getGroup(); DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer(); String name = loadBalancer.getName(); - NamingService namingService = nacosDiscoveryProperties - .namingServiceInstance(); - List instances = namingService.selectInstances(name, true); + NamingService namingService = nacosServiceManager + .getNamingService(nacosDiscoveryProperties.getNacosProperties()); + List instances = namingService.selectInstances(name, group, true); if (CollectionUtils.isEmpty(instances)) { LOGGER.warn("no instance in service {}", name); return null; diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 5cb5e588..f4eb2626 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -24,6 +24,18 @@ "description": "enable nacos discovery or not." }, { + "name": "spring.cloud.nacos.discovery.instance-enabled", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "If instance is enabled to accept request. The default value is true." + }, + { + "name": "spring.cloud.nacos.discovery.ephemeral", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "If instance is ephemeral.The default value is true." + }, + { "name": "spring.cloud.nacos.discovery.namingLoadCacheAtStart", "type": "java.lang.Boolean", "defaultValue": "false", diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories index c7a516de..e2c189e2 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories @@ -4,6 +4,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\ com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\ com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\ + com.alibaba.cloud.nacos.NacosServiceAutoConfiguration,\ com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressBothLevelTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressBothLevelTests.java index 9e1ce8ae..0d513704 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressBothLevelTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressBothLevelTests.java @@ -36,11 +36,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author lyuzb */ @RunWith(SpringRunner.class) -@SpringBootTest( - classes = NacosDiscoveryPropertiesServerAddressBothLevelTests.TestConfig.class, - properties = { "spring.cloud.nacos.discovery.server-addr=321.321.321.321:8848", - "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosDiscoveryPropertiesServerAddressBothLevelTests.TestConfig.class, properties = { + "spring.cloud.nacos.discovery.server-addr=321.321.321.321:8848", + "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, webEnvironment = RANDOM_PORT) public class NacosDiscoveryPropertiesServerAddressBothLevelTests { @Autowired diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressTopLevelTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressTopLevelTests.java index db90b57a..857675a7 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressTopLevelTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/NacosDiscoveryPropertiesServerAddressTopLevelTests.java @@ -37,10 +37,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * */ @RunWith(SpringRunner.class) -@SpringBootTest( - classes = NacosDiscoveryPropertiesServerAddressTopLevelTests.TestConfig.class, - properties = { "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosDiscoveryPropertiesServerAddressTopLevelTests.TestConfig.class, properties = { + "spring.cloud.nacos.server-addr=123.123.123.123:8848" }, webEnvironment = RANDOM_PORT) public class NacosDiscoveryPropertiesServerAddressTopLevelTests { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscoveryTest.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscoveryTest.java index 74404079..97ecc683 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscoveryTest.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/discovery/NacosServiceDiscoveryTest.java @@ -22,6 +22,7 @@ import java.util.LinkedList; import java.util.List; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; @@ -60,16 +61,19 @@ public class NacosServiceDiscoveryTest { NacosDiscoveryProperties nacosDiscoveryProperties = mock( NacosDiscoveryProperties.class); + NacosServiceManager nacosServiceManager = mock(NacosServiceManager.class); NamingService namingService = mock(NamingService.class); - when(nacosDiscoveryProperties.namingServiceInstance()).thenReturn(namingService); + when(nacosServiceManager + .getNamingService(nacosDiscoveryProperties.getNacosProperties())) + .thenReturn(namingService); when(nacosDiscoveryProperties.getGroup()).thenReturn("DEFAULT"); when(namingService.selectInstances(eq(serviceName), eq("DEFAULT"), eq(true))) .thenReturn(instances); NacosServiceDiscovery serviceDiscovery = new NacosServiceDiscovery( - nacosDiscoveryProperties); + nacosDiscoveryProperties, nacosServiceManager); List serviceInstances = serviceDiscovery .getInstances(serviceName); @@ -99,16 +103,19 @@ public class NacosServiceDiscoveryTest { NacosDiscoveryProperties nacosDiscoveryProperties = mock( NacosDiscoveryProperties.class); + NacosServiceManager nacosServiceManager = mock(NacosServiceManager.class); NamingService namingService = mock(NamingService.class); - when(nacosDiscoveryProperties.namingServiceInstance()).thenReturn(namingService); + when(nacosServiceManager + .getNamingService(nacosDiscoveryProperties.getNacosProperties())) + .thenReturn(namingService); when(nacosDiscoveryProperties.getGroup()).thenReturn("DEFAULT"); when(namingService.getServicesOfServer(eq(1), eq(Integer.MAX_VALUE), eq("DEFAULT"))).thenReturn(nacosServices); NacosServiceDiscovery serviceDiscovery = new NacosServiceDiscovery( - nacosDiscoveryProperties); + nacosDiscoveryProperties, nacosServiceManager); List services = serviceDiscovery.getServices(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/MockNamingService.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/MockNamingService.java index 66753af7..ffca3607 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/MockNamingService.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/MockNamingService.java @@ -328,4 +328,9 @@ public class MockNamingService implements NamingService { return null; } + @Override + public void shutDown() throws NacosException { + + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpNetworkInterfaceTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpNetworkInterfaceTests.java index dc8f5376..e59059a9 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpNetworkInterfaceTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpNetworkInterfaceTests.java @@ -56,25 +56,11 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosFactory.class }) -@SpringBootTest( - classes = NacosAutoServiceRegistrationIpNetworkInterfaceTests.TestConfig.class, - properties = { "spring.application.name=myTestService1", - "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosAutoServiceRegistrationIpNetworkInterfaceTests.TestConfig.class, properties = { + "spring.application.name=myTestService1", + "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848" }, webEnvironment = RANDOM_PORT) public class NacosAutoServiceRegistrationIpNetworkInterfaceTests { - @Autowired - private NacosRegistration registration; - - @Autowired - private NacosAutoServiceRegistration nacosAutoServiceRegistration; - - @Autowired - private NacosDiscoveryProperties properties; - - @Autowired - private InetUtils inetUtils; - static { try { Method method = PowerMockito.method(NacosFactory.class, "createNamingService", @@ -92,6 +78,15 @@ public class NacosAutoServiceRegistrationIpNetworkInterfaceTests { } } + @Autowired + private NacosRegistration registration; + @Autowired + private NacosAutoServiceRegistration nacosAutoServiceRegistration; + @Autowired + private NacosDiscoveryProperties properties; + @Autowired + private InetUtils inetUtils; + @Test public void contextLoads() throws Exception { assertThat(registration).isNotNull(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpTests.java index 99fef767..5cacdba0 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationIpTests.java @@ -51,22 +51,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosFactory.class }) -@SpringBootTest(classes = NacosAutoServiceRegistrationIpTests.TestConfig.class, - properties = { "spring.application.name=myTestService1", - "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", - "spring.cloud.nacos.discovery.ip=123.123.123.123" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosAutoServiceRegistrationIpTests.TestConfig.class, properties = { + "spring.application.name=myTestService1", + "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", + "spring.cloud.nacos.discovery.ip=123.123.123.123" }, webEnvironment = RANDOM_PORT) public class NacosAutoServiceRegistrationIpTests { - @Autowired - private NacosRegistration registration; - - @Autowired - private NacosAutoServiceRegistration nacosAutoServiceRegistration; - - @Autowired - private NacosDiscoveryProperties properties; - static { try { Method method = PowerMockito.method(NacosFactory.class, "createNamingService", @@ -84,6 +74,13 @@ public class NacosAutoServiceRegistrationIpTests { } } + @Autowired + private NacosRegistration registration; + @Autowired + private NacosAutoServiceRegistration nacosAutoServiceRegistration; + @Autowired + private NacosDiscoveryProperties properties; + @Test public void contextLoads() throws Exception { assertThat(registration).isNotNull(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationManagementPortTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationManagementPortTests.java index 83989ca8..48e70526 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationManagementPortTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationManagementPortTests.java @@ -51,25 +51,13 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosFactory.class }) -@SpringBootTest( - classes = NacosAutoServiceRegistrationManagementPortTests.TestConfig.class, - properties = { "spring.application.name=myTestService1", - "management.server.port=8888", - "management.server.servlet.context-path=/test-context-path", - "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", - "spring.cloud.nacos.discovery.port=8888" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosAutoServiceRegistrationManagementPortTests.TestConfig.class, properties = { + "spring.application.name=myTestService1", "management.server.port=8888", + "management.server.servlet.context-path=/test-context-path", + "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", + "spring.cloud.nacos.discovery.port=8888" }, webEnvironment = RANDOM_PORT) public class NacosAutoServiceRegistrationManagementPortTests { - @Autowired - private NacosRegistration registration; - - @Autowired - private NacosAutoServiceRegistration nacosAutoServiceRegistration; - - @Autowired - private NacosDiscoveryProperties properties; - static { try { Method method = PowerMockito.method(NacosFactory.class, "createNamingService", @@ -87,6 +75,13 @@ public class NacosAutoServiceRegistrationManagementPortTests { } } + @Autowired + private NacosRegistration registration; + @Autowired + private NacosAutoServiceRegistration nacosAutoServiceRegistration; + @Autowired + private NacosDiscoveryProperties properties; + @Test public void contextLoads() throws Exception { assertThat(registration).isNotNull(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationPortTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationPortTests.java index 1c52b391..5854620c 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationPortTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationPortTests.java @@ -51,22 +51,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosFactory.class }) -@SpringBootTest(classes = NacosAutoServiceRegistrationPortTests.TestConfig.class, - properties = { "spring.application.name=myTestService1", - "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", - "spring.cloud.nacos.discovery.port=8888" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosAutoServiceRegistrationPortTests.TestConfig.class, properties = { + "spring.application.name=myTestService1", + "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", + "spring.cloud.nacos.discovery.port=8888" }, webEnvironment = RANDOM_PORT) public class NacosAutoServiceRegistrationPortTests { - @Autowired - private NacosRegistration registration; - - @Autowired - private NacosAutoServiceRegistration nacosAutoServiceRegistration; - - @Autowired - private NacosDiscoveryProperties properties; - static { try { Method method = PowerMockito.method(NacosFactory.class, "createNamingService", @@ -84,6 +74,13 @@ public class NacosAutoServiceRegistrationPortTests { } } + @Autowired + private NacosRegistration registration; + @Autowired + private NacosAutoServiceRegistration nacosAutoServiceRegistration; + @Autowired + private NacosDiscoveryProperties properties; + @Test public void contextLoads() throws Exception { assertThat(registration).isNotNull(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationTests.java index 926afb17..2bee87b8 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/registry/NacosAutoServiceRegistrationTests.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Properties; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration; import com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpoint; import com.alibaba.nacos.api.NacosFactory; @@ -55,40 +56,24 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @PowerMockIgnore("javax.management.*") @PowerMockRunnerDelegate(SpringRunner.class) @PrepareForTest({ NacosFactory.class }) -@SpringBootTest(classes = NacosAutoServiceRegistrationTests.TestConfig.class, - properties = { "spring.application.name=myTestService1", - "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", - "spring.cloud.nacos.discovery.endpoint=test-endpoint", - "spring.cloud.nacos.discovery.namespace=test-namespace", - "spring.cloud.nacos.discovery.log-name=test-logName", - "spring.cloud.nacos.discovery.weight=2", - "spring.cloud.nacos.discovery.clusterName=test-cluster", - "spring.cloud.nacos.discovery.namingLoadCacheAtStart=true", - "spring.cloud.nacos.discovery.secure=true", - "spring.cloud.nacos.discovery.accessKey=test-accessKey", - "spring.cloud.nacos.discovery.ip=8.8.8.8", - "spring.cloud.nacos.discovery.secretKey=test-secretKey", - "spring.cloud.nacos.discovery.heart-beat-interval=3", - "spring.cloud.nacos.discovery.heart-beat-timeout=6", - "spring.cloud.nacos.discovery.ip-delete-timeout=9" }, - webEnvironment = RANDOM_PORT) +@SpringBootTest(classes = NacosAutoServiceRegistrationTests.TestConfig.class, properties = { + "spring.application.name=myTestService1", + "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", + "spring.cloud.nacos.discovery.endpoint=test-endpoint", + "spring.cloud.nacos.discovery.namespace=test-namespace", + "spring.cloud.nacos.discovery.log-name=test-logName", + "spring.cloud.nacos.discovery.weight=2", + "spring.cloud.nacos.discovery.clusterName=test-cluster", + "spring.cloud.nacos.discovery.namingLoadCacheAtStart=true", + "spring.cloud.nacos.discovery.secure=true", + "spring.cloud.nacos.discovery.accessKey=test-accessKey", + "spring.cloud.nacos.discovery.ip=8.8.8.8", + "spring.cloud.nacos.discovery.secretKey=test-secretKey", + "spring.cloud.nacos.discovery.heart-beat-interval=3", + "spring.cloud.nacos.discovery.heart-beat-timeout=6", + "spring.cloud.nacos.discovery.ip-delete-timeout=9" }, webEnvironment = RANDOM_PORT) public class NacosAutoServiceRegistrationTests { - @Autowired - private NacosRegistration registration; - - @Autowired - private NacosAutoServiceRegistration nacosAutoServiceRegistration; - - @LocalServerPort - private int port; - - @Autowired - private NacosDiscoveryProperties properties; - - @Autowired - private InetUtils inetUtils; - static { try { Method method = PowerMockito.method(NacosFactory.class, "createNamingService", @@ -106,6 +91,19 @@ public class NacosAutoServiceRegistrationTests { } } + @Autowired + private NacosRegistration registration; + @Autowired + private NacosAutoServiceRegistration nacosAutoServiceRegistration; + @LocalServerPort + private int port; + @Autowired + private NacosDiscoveryProperties properties; + @Autowired + private NacosServiceManager nacosServiceManager; + @Autowired + private InetUtils inetUtils; + @Test public void contextLoads() throws Exception { assertThat(registration).isNotNull(); @@ -207,7 +205,7 @@ public class NacosAutoServiceRegistrationTests { private void checkoutEndpoint() throws Exception { NacosDiscoveryEndpoint nacosDiscoveryEndpoint = new NacosDiscoveryEndpoint( - properties); + nacosServiceManager, properties); Map map = nacosDiscoveryEndpoint.nacosDiscovery(); assertThat(properties).isEqualTo(map.get("NacosDiscoveryProperties")); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/ribbon/NacosRibbonClientPropertyOverrideTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/ribbon/NacosRibbonClientPropertyOverrideTests.java index 3692414f..d5f30409 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/ribbon/NacosRibbonClientPropertyOverrideTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/test/java/com/alibaba/cloud/nacos/ribbon/NacosRibbonClientPropertyOverrideTests.java @@ -39,14 +39,14 @@ import org.springframework.test.context.junit4.SpringRunner; * @author liujunjie */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = NacosRibbonClientPropertyOverrideTests.TestConfiguration.class, - properties = { "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", - "spring.cloud.nacos.discovery.port=18080", - "spring.cloud.nacos.discovery.service=remoteApp", - "localApp.ribbon.NIWSServerListClassName=" - + "com.netflix.loadbalancer.ConfigurationBasedServerList", - "localApp.ribbon.listOfServers=127.0.0.1:19090", - "localApp.ribbon.ServerListRefreshInterval=15000" }) +@SpringBootTest(classes = NacosRibbonClientPropertyOverrideTests.TestConfiguration.class, properties = { + "spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848", + "spring.cloud.nacos.discovery.port=18080", + "spring.cloud.nacos.discovery.service=remoteApp", + "localApp.ribbon.NIWSServerListClassName=" + + "com.netflix.loadbalancer.ConfigurationBasedServerList", + "localApp.ribbon.listOfServers=127.0.0.1:19090", + "localApp.ribbon.ServerListRefreshInterval=15000" }) public class NacosRibbonClientPropertyOverrideTests { @Autowired diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/SeataFeignClient.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/SeataFeignClient.java index 5bcaebca..9d5c9870 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/SeataFeignClient.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/SeataFeignClient.java @@ -36,15 +36,13 @@ import org.springframework.util.StringUtils; */ public class SeataFeignClient implements Client { - private final Client delegate; - - private final BeanFactory beanFactory; - private static final int MAP_SIZE = 16; + private final Client delegate; + private final BeanFactory beanFactory; SeataFeignClient(BeanFactory beanFactory) { this.beanFactory = beanFactory; - this.delegate = new Client.Default(null, null); + this.delegate = new Default(null, null); } SeataFeignClient(BeanFactory beanFactory, Client delegate) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java index 338d1c92..2aa507bd 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java @@ -46,6 +46,7 @@ public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy private final Logger logger = LoggerFactory .getLogger(SeataHystrixConcurrencyStrategy.class); + private HystrixConcurrencyStrategy delegate; public SeataHystrixConcurrencyStrategy() { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/rest/SeataRestTemplateAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/rest/SeataRestTemplateAutoConfiguration.java index 40c37af3..68f1ff7d 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/rest/SeataRestTemplateAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/rest/SeataRestTemplateAutoConfiguration.java @@ -35,17 +35,16 @@ import org.springframework.web.client.RestTemplate; @Configuration public class SeataRestTemplateAutoConfiguration { + @Autowired(required = false) + private Collection restTemplates; + @Autowired + private SeataRestTemplateInterceptor seataRestTemplateInterceptor; + @Bean public SeataRestTemplateInterceptor seataRestTemplateInterceptor() { return new SeataRestTemplateInterceptor(); } - @Autowired(required = false) - private Collection restTemplates; - - @Autowired - private SeataRestTemplateInterceptor seataRestTemplateInterceptor; - @PostConstruct public void init() { if (this.restTemplates != null) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/web/SeataHandlerInterceptor.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/web/SeataHandlerInterceptor.java index dcc0b28c..bc1e76de 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/web/SeataHandlerInterceptor.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/web/SeataHandlerInterceptor.java @@ -19,21 +19,21 @@ package com.alibaba.cloud.seata.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import io.seata.common.util.StringUtils; import io.seata.core.context.RootContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; /** * @author xiaojing * * Seata HandlerInterceptor, Convert Seata information into - * @see io.seata.core.context.RootContext from http request's header in - * {@link org.springframework.web.servlet.HandlerInterceptor#preHandle(HttpServletRequest , HttpServletResponse , Object )}, + * @see RootContext from http request's header in + * {@link HandlerInterceptor#preHandle(HttpServletRequest, HttpServletResponse, Object )}, * And clean up Seata information after servlet method invocation in - * {@link org.springframework.web.servlet.HandlerInterceptor#afterCompletion(HttpServletRequest, HttpServletResponse, Object, Exception)} + * {@link HandlerInterceptor#afterCompletion(HttpServletRequest, HttpServletResponse, Object, Exception)} */ public class SeataHandlerInterceptor implements HandlerInterceptor { @@ -50,7 +50,7 @@ public class SeataHandlerInterceptor implements HandlerInterceptor { log.debug("xid in RootContext {} xid in RpcContext {}", xid, rpcXid); } - if (xid == null && rpcXid != null) { + if (StringUtils.isBlank(xid) && rpcXid != null) { RootContext.bind(rpcXid); if (log.isDebugEnabled()) { log.debug("bind {} to RootContext", rpcXid); @@ -62,22 +62,23 @@ public class SeataHandlerInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { + if (StringUtils.isNotBlank(RootContext.getXID())) { + String rpcXid = request.getHeader(RootContext.KEY_XID); - String rpcXid = request.getHeader(RootContext.KEY_XID); + if (StringUtils.isEmpty(rpcXid)) { + return; + } - if (StringUtils.isEmpty(rpcXid)) { - return; - } - - String unbindXid = RootContext.unbind(); - if (log.isDebugEnabled()) { - log.debug("unbind {} from RootContext", unbindXid); - } - if (!rpcXid.equalsIgnoreCase(unbindXid)) { - log.warn("xid in change during RPC from {} to {}", rpcXid, unbindXid); - if (unbindXid != null) { - RootContext.bind(unbindXid); - log.warn("bind {} back to RootContext", unbindXid); + String unbindXid = RootContext.unbind(); + if (log.isDebugEnabled()) { + log.debug("unbind {} from RootContext", unbindXid); + } + if (!rpcXid.equalsIgnoreCase(unbindXid)) { + log.warn("xid in change during RPC from {} to {}", rpcXid, unbindXid); + if (unbindXid != null) { + RootContext.bind(unbindXid); + log.warn("bind {} back to RootContext", unbindXid); + } } } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelProperties.java index b6322c6f..d4397b22 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelProperties.java @@ -102,6 +102,20 @@ public class SentinelProperties { */ private Boolean httpMethodSpecify = false; + /** + * Specify whether unify web context(i.e. use the default context name), and is true + * by default. + */ + private Boolean webContextUnify = true; + + public Boolean getWebContextUnify() { + return webContextUnify; + } + + public void setWebContextUnify(Boolean webContextUnify) { + this.webContextUnify = webContextUnify; + } + public boolean isEager() { return eager; } @@ -218,9 +232,8 @@ public class SentinelProperties { private String blockPage; @Deprecated - @DeprecatedConfigurationProperty( - reason = "replaced to SentinelProperties#blockPage.", - replacement = SentinelConstants.PROPERTY_PREFIX + ".block-page") + @DeprecatedConfigurationProperty(reason = "replaced to SentinelProperties#blockPage.", replacement = SentinelConstants.PROPERTY_PREFIX + + ".block-page") public String getBlockPage() { return blockPage; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebAutoConfiguration.java index d2e89ddc..8f55d3fd 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebAutoConfiguration.java @@ -83,19 +83,18 @@ public class SentinelWebAutoConfiguration implements WebMvcConfigurer { } @Bean - @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", - matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", matchIfMissing = true) public SentinelWebInterceptor sentinelWebInterceptor( SentinelWebMvcConfig sentinelWebMvcConfig) { return new SentinelWebInterceptor(sentinelWebMvcConfig); } @Bean - @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", - matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", matchIfMissing = true) public SentinelWebMvcConfig sentinelWebMvcConfig() { SentinelWebMvcConfig sentinelWebMvcConfig = new SentinelWebMvcConfig(); sentinelWebMvcConfig.setHttpMethodSpecify(properties.getHttpMethodSpecify()); + sentinelWebMvcConfig.setWebContextUnify(properties.getWebContextUnify()); if (blockExceptionHandlerOptional.isPresent()) { blockExceptionHandlerOptional diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebFluxAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebFluxAutoConfiguration.java index e42133c3..57f297b3 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebFluxAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/SentinelWebFluxAutoConfiguration.java @@ -77,16 +77,14 @@ public class SentinelWebFluxAutoConfiguration { @Bean @Order(-2) - @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", - matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", matchIfMissing = true) public SentinelBlockExceptionHandler sentinelBlockExceptionHandler() { return new SentinelBlockExceptionHandler(viewResolvers, serverCodecConfigurer); } @Bean @Order(-1) - @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", - matchIfMissing = true) + @ConditionalOnProperty(name = "spring.cloud.sentinel.filter.enabled", matchIfMissing = true) public SentinelWebFluxFilter sentinelWebFluxFilter() { log.info("[Sentinel Starter] register Sentinel SentinelWebFluxFilter"); return new SentinelWebFluxFilter(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/BlockClassRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/BlockClassRegistry.java index 7bb1bf4d..b07aeb57 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/BlockClassRegistry.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/BlockClassRegistry.java @@ -27,16 +27,14 @@ import com.alibaba.csp.sentinel.util.StringUtil; */ final class BlockClassRegistry { + private static final Map FALLBACK_MAP = new ConcurrentHashMap<>(); + private static final Map BLOCK_HANDLER_MAP = new ConcurrentHashMap<>(); + private static final Map URL_CLEANER_MAP = new ConcurrentHashMap<>(); + private BlockClassRegistry() { } - private static final Map FALLBACK_MAP = new ConcurrentHashMap<>(); - - private static final Map BLOCK_HANDLER_MAP = new ConcurrentHashMap<>(); - - private static final Map URL_CLEANER_MAP = new ConcurrentHashMap<>(); - static Method lookupFallback(Class clazz, String name) { return FALLBACK_MAP.get(getKey(clazz, name)); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelAutoConfiguration.java index 3d8d362c..2089d0e6 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelAutoConfiguration.java @@ -31,7 +31,6 @@ import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; import com.alibaba.csp.sentinel.slots.system.SystemRule; import com.alibaba.csp.sentinel.transport.config.TransportConfig; -import com.alibaba.csp.sentinel.util.AppNameUtil; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; @@ -79,9 +78,9 @@ public class SentinelAutoConfiguration { System.setProperty(LogBase.LOG_NAME_USE_PID, String.valueOf(properties.getLog().isSwitchPid())); } - if (StringUtils.isEmpty(System.getProperty(AppNameUtil.APP_NAME)) + if (StringUtils.isEmpty(System.getProperty(SentinelConfig.APP_NAME_PROP_KEY)) && StringUtils.hasText(projectName)) { - System.setProperty(AppNameUtil.APP_NAME, projectName); + System.setProperty(SentinelConfig.APP_NAME_PROP_KEY, projectName); } if (StringUtils.isEmpty(System.getProperty(TransportConfig.SERVER_PORT)) && StringUtils.hasText(properties.getTransport().getPort())) { @@ -146,8 +145,7 @@ public class SentinelAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnClass(name = "org.springframework.web.client.RestTemplate") - @ConditionalOnProperty(name = "resttemplate.sentinel.enabled", havingValue = "true", - matchIfMissing = true) + @ConditionalOnProperty(name = "resttemplate.sentinel.enabled", havingValue = "true", matchIfMissing = true) public SentinelBeanPostProcessor sentinelBeanPostProcessor( ApplicationContext applicationContext) { return new SentinelBeanPostProcessor(applicationContext); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelBeanPostProcessor.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelBeanPostProcessor.java index 79eff6ce..94745bdf 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelBeanPostProcessor.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelBeanPostProcessor.java @@ -56,13 +56,12 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces .getLogger(SentinelBeanPostProcessor.class); private final ApplicationContext applicationContext; + private ConcurrentHashMap cache = new ConcurrentHashMap<>(); public SentinelBeanPostProcessor(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } - private ConcurrentHashMap cache = new ConcurrentHashMap<>(); - @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java index 2de7727c..963c612a 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/custom/SentinelDataSourceHandler.java @@ -52,20 +52,13 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { private static final Logger log = LoggerFactory .getLogger(SentinelDataSourceHandler.class); - - private List dataTypeList = Arrays.asList("json", "xml"); - private final String DATA_TYPE_FIELD = "dataType"; - private final String CUSTOM_DATA_TYPE = "custom"; - private final String CONVERTER_CLASS_FIELD = "converterClass"; - private final DefaultListableBeanFactory beanFactory; - private final SentinelProperties sentinelProperties; - private final Environment env; + private List dataTypeList = Arrays.asList("json", "xml"); public SentinelDataSourceHandler(DefaultListableBeanFactory beanFactory, SentinelProperties sentinelProperties, Environment env) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelEndpoint.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelEndpoint.java index c1f38a85..b10844b4 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelEndpoint.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelEndpoint.java @@ -61,7 +61,7 @@ public class SentinelEndpoint { result.put("metricsFileSize", SentinelConfig.singleMetricFileSize()); result.put("metricsFileCharset", SentinelConfig.charset()); result.put("totalMetricsFileCount", SentinelConfig.totalMetricFileCount()); - result.put("consoleServer", TransportConfig.getConsoleServer()); + result.put("consoleServer", TransportConfig.getConsoleServerList()); result.put("clientIp", TransportConfig.getHeartbeatClientIp()); result.put("heartbeatIntervalMs", TransportConfig.getHeartbeatIntervalMs()); result.put("clientPort", TransportConfig.getPort()); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java index 74bdf075..ea8aacd0 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java @@ -17,6 +17,7 @@ package com.alibaba.cloud.sentinel.endpoint; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.alibaba.cloud.sentinel.SentinelProperties; @@ -24,13 +25,14 @@ import com.alibaba.csp.sentinel.datasource.AbstractDataSource; import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider; import com.alibaba.csp.sentinel.transport.HeartbeatSender; import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import com.alibaba.csp.sentinel.util.function.Tuple2; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.Status; -import org.springframework.util.StringUtils; +import org.springframework.util.CollectionUtils; /** * A {@link HealthIndicator} for Sentinel, which checks the status of Sentinel Dashboard @@ -82,8 +84,9 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator { // Check health of Dashboard boolean dashboardUp = true; - String consoleServer = TransportConfig.getConsoleServer(); - if (StringUtils.isEmpty(consoleServer)) { + List> consoleServerList = TransportConfig + .getConsoleServerList(); + if (CollectionUtils.isEmpty(consoleServerList)) { // If Dashboard isn't configured, it's OK and mark the status of Dashboard // with UNKNOWN. detailMap.put("dashboard", @@ -101,8 +104,10 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator { else { // If failed to send heartbeat message, means that the Dashboard is DOWN dashboardUp = false; - detailMap.put("dashboard", new Status(Status.DOWN.getCode(), - consoleServer + " can't be connected")); + detailMap.put("dashboard", + new Status(Status.UNKNOWN.getCode(), String.format( + "the dashboard servers [%s] one of them can't be connected", + consoleServerList))); } } @@ -133,7 +138,7 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator { // DOWN dataSourceUp = false; dataSourceDetailMap.put(dataSourceBeanName, - new Status(Status.DOWN.getCode(), e.getMessage())); + new Status(Status.UNKNOWN.getCode(), e.getMessage())); } } @@ -142,7 +147,7 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator { withDetails(builder.up(), detailMap); } else { - withDetails(builder.down(), detailMap); + withDetails(builder.unknown(), detailMap); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelContractHolder.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelContractHolder.java index 9a5acfd3..cf0716c7 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelContractHolder.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelContractHolder.java @@ -32,13 +32,12 @@ import feign.MethodMetadata; */ public class SentinelContractHolder implements Contract { - private final Contract delegate; - /** * map key is constructed by ClassFullName + configKey. configKey is constructed by * {@link feign.Feign#configKey} */ public final static Map METADATA_MAP = new HashMap<>(); + private final Contract delegate; public SentinelContractHolder(Contract delegate) { this.delegate = delegate; diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelFeign.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelFeign.java index f6af13fe..6445e776 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelFeign.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelFeign.java @@ -33,6 +33,7 @@ import org.springframework.cloud.openfeign.FeignContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; /** * {@link Feign.Builder} like {@link HystrixFeign.Builder}. @@ -86,7 +87,11 @@ public final class SentinelFeign { "fallback"); Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean, "fallbackFactory"); - String beanName = (String) getFieldValue(feignClientFactoryBean, "name"); + String beanName = (String) getFieldValue(feignClientFactoryBean, + "contextId"); + if (!StringUtils.hasText(beanName)) { + beanName = (String) getFieldValue(feignClientFactoryBean, "name"); + } Object fallbackInstance; FallbackFactory fallbackFactoryInstance; @@ -132,12 +137,14 @@ public final class SentinelFeign { private Object getFieldValue(Object instance, String fieldName) { Field field = ReflectionUtils.findField(instance.getClass(), fieldName); - field.setAccessible(true); - try { - return field.get(instance); - } - catch (IllegalAccessException e) { - // ignore + if (field != null) { + field.setAccessible(true); + try { + return field.get(instance); + } + catch (IllegalAccessException e) { + // ignore + } } return null; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelInvocationHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelInvocationHandler.java index 8c2eb550..a9b4e066 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelInvocationHandler.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/feign/SentinelInvocationHandler.java @@ -65,13 +65,23 @@ public class SentinelInvocationHandler implements InvocationHandler { this.dispatch = checkNotNull(dispatch, "dispatch"); } + static Map toFallbackMethod(Map dispatch) { + Map result = new LinkedHashMap<>(); + for (Method method : dispatch.keySet()) { + method.setAccessible(true); + result.put(method, method); + } + return result; + } + @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if ("equals".equals(method.getName())) { try { Object otherHandler = args.length > 0 && args[0] != null - ? Proxy.getInvocationHandler(args[0]) : null; + ? Proxy.getInvocationHandler(args[0]) + : null; return equals(otherHandler); } catch (IllegalArgumentException e) { @@ -166,13 +176,4 @@ public class SentinelInvocationHandler implements InvocationHandler { return target.toString(); } - static Map toFallbackMethod(Map dispatch) { - Map result = new LinkedHashMap<>(); - for (Method method : dispatch.keySet()) { - method.setAccessible(true); - result.put(method, method); - } - return result; - } - } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 93acd7e5..49b06b0d 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -19,7 +19,12 @@ "description": "earlier initialize heart-beat when the spring container starts when the transport dependency is on classpath, the configuration is effective." }, { - "name": "spring.cloud.sentinel.transport.port", + "name": "spring.cloud.sentinel.web-context-unify", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "Specify whether unify web context(i.e. use the default context name), and is true by default." + }, + { "name": "spring.cloud.sentinel.transport.port", "type": "java.lang.String", "defaultValue": "8719", "description": "sentinel api port." diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/ContextIdSentinelFeignTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/ContextIdSentinelFeignTests.java deleted file mode 100644 index 2066ba49..00000000 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/ContextIdSentinelFeignTests.java +++ /dev/null @@ -1,136 +0,0 @@ -///* -// * Copyright 2013-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 -// * -// * https://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 com.alibaba.cloud.sentinel; -// -//import com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfiguration; -//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.openfeign.EnableFeignClients; -//import org.springframework.cloud.openfeign.FeignClient; -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.test.context.junit4.SpringRunner; -//import org.springframework.web.bind.annotation.GetMapping; -//import org.springframework.web.bind.annotation.PathVariable; -//import org.springframework.web.bind.annotation.RequestMapping; -//import org.springframework.web.bind.annotation.RequestParam; -// -//import static org.assertj.core.api.Assertions.assertThat; -// -///** -// * Add this unit test to verify https://github.com/alibaba/spring-cloud-alibaba/pull/838. -// * -// * @author Jim -// */ -//@RunWith(SpringRunner.class) -//@SpringBootTest(classes = { ContextIdSentinelFeignTests.TestConfig.class }, -// properties = { "feign.sentinel.enabled=true" }) -//public class ContextIdSentinelFeignTests { -// -// @Autowired -// private EchoService echoService; -// -// @Autowired -// private FooService fooService; -// -// @Test -// public void testFeignClient() { -// assertThat(echoService.echo("test")).isEqualTo("echo fallback"); -// assertThat(fooService.echo("test")).isEqualTo("foo fallback"); -// assertThat(fooService.toString()).isNotEqualTo(echoService.toString()); -// assertThat(fooService.hashCode()).isNotEqualTo(echoService.hashCode()); -// assertThat(echoService.equals(fooService)).isEqualTo(Boolean.FALSE); -// } -// -// @Configuration -// @EnableAutoConfiguration -// @ImportAutoConfiguration({ SentinelFeignAutoConfiguration.class }) -// @EnableFeignClients -// public static class TestConfig { -// -// } -// -// @FeignClient(name = "service-provider", -// fallback = EchoServiceFallback.class, -// configuration = FeignConfiguration.class) -// public interface EchoService { -// -// @GetMapping("/echo/{str}") -// String echo(@PathVariable("str") String str); -// -// } -// -// @FeignClient(value = "foo-service", -// fallbackFactory = CustomFallbackFactory.class, -// configuration = FeignConfiguration.class) -// public interface FooService { -// -// @RequestMapping(path = "echo/{str}") -// String echo(@RequestParam("str") String param); -// -// } -// -// public static class FeignConfiguration { -// -// @Bean -// public EchoServiceFallback echoServiceFallback() { -// return new EchoServiceFallback(); -// } -// -// @Bean -// public CustomFallbackFactory customFallbackFactory() { -// return new CustomFallbackFactory(); -// } -// -// } -// -// public static class EchoServiceFallback implements EchoService { -// -// @Override -// public String echo(@RequestParam("str") String param) { -// return "echo fallback"; -// } -// -// } -// -// public static class FooServiceFallback implements FooService { -// -// @Override -// public String echo(@RequestParam("str") String param) { -// return "foo fallback"; -// } -// -// } -// -// public static class CustomFallbackFactory -// implements feign.hystrix.FallbackFactory { -// -// private FooService fooService = new FooServiceFallback(); -// -// @Override -// public FooService create(Throwable throwable) { -// return fooService; -// } -// -// } -// -//} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java index ae67bd38..f79c1e18 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java @@ -28,11 +28,10 @@ import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.log.LogBase; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.csp.sentinel.slots.block.RuleConstant; -import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; -import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import com.alibaba.csp.sentinel.util.function.Tuple2; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -64,8 +63,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author jiashuai.xie */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = { SentinelAutoConfigurationTests.TestConfig.class }, - properties = { "spring.cloud.sentinel.filter.order=123", +@SpringBootTest(classes = { + SentinelAutoConfigurationTests.TestConfig.class }, properties = { + "spring.cloud.sentinel.filter.order=123", "spring.cloud.sentinel.filter.urlPatterns=/*,/test", "spring.cloud.sentinel.metric.fileSingleSize=9999", "spring.cloud.sentinel.metric.fileTotalCount=100", @@ -73,11 +73,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen "spring.cloud.sentinel.flow.coldFactor=3", "spring.cloud.sentinel.eager=true", "spring.cloud.sentinel.log.switchPid=true", - "spring.cloud.sentinel.transport.dashboard=http://localhost:8080", + "spring.cloud.sentinel.transport.dashboard=http://localhost:8080,http://localhost:8081", "spring.cloud.sentinel.transport.port=9999", "spring.cloud.sentinel.transport.clientIp=1.1.1.1", - "spring.cloud.sentinel.transport.heartbeatIntervalMs=20000" }, - webEnvironment = RANDOM_PORT) + "spring.cloud.sentinel.transport.heartbeatIntervalMs=20000" }, webEnvironment = RANDOM_PORT) public class SentinelAutoConfigurationTests { @Autowired @@ -115,13 +114,6 @@ public class SentinelAutoConfigurationTests { rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); rule.setStrategy(RuleConstant.STRATEGY_DIRECT); FlowRuleManager.loadRules(Arrays.asList(rule)); - - DegradeRule degradeRule = new DegradeRule(); - degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT); - degradeRule.setResource("GET:" + degradeUrl); - degradeRule.setCount(0); - degradeRule.setTimeWindow(60); - DegradeRuleManager.loadRules(Arrays.asList(degradeRule)); } @Test @@ -142,7 +134,9 @@ public class SentinelAutoConfigurationTests { Map map = sentinelEndpoint.invoke(); assertThat(map.get("logUsePid")).isEqualTo(Boolean.TRUE); - assertThat(map.get("consoleServer")).isEqualTo("http://localhost:8080"); + assertThat(map.get("consoleServer").toString()).isEqualTo( + Arrays.asList(Tuple2.of("localhost", 8080), Tuple2.of("localhost", 8081)) + .toString()); assertThat(map.get("clientPort")).isEqualTo("9999"); assertThat(map.get("heartbeatIntervalMs")).isEqualTo(20000L); assertThat(map.get("clientIp")).isEqualTo("1.1.1.1"); @@ -174,7 +168,7 @@ public class SentinelAutoConfigurationTests { private void checkSentinelTransport() { assertThat(sentinelProperties.getTransport().getPort()).isEqualTo("9999"); assertThat(sentinelProperties.getTransport().getDashboard()) - .isEqualTo("http://localhost:8080"); + .isEqualTo("http://localhost:8080,http://localhost:8081"); assertThat(sentinelProperties.getTransport().getClientIp()).isEqualTo("1.1.1.1"); assertThat(sentinelProperties.getTransport().getHeartbeatIntervalMs()) .isEqualTo("20000"); @@ -191,7 +185,9 @@ public class SentinelAutoConfigurationTests { @Test public void testSentinelSystemProperties() { assertThat(LogBase.isLogNameUsePid()).isEqualTo(true); - assertThat(TransportConfig.getConsoleServer()).isEqualTo("http://localhost:8080"); + assertThat(TransportConfig.getConsoleServerList().toString()).isEqualTo( + Arrays.asList(Tuple2.of("localhost", 8080), Tuple2.of("localhost", 8081)) + .toString()); assertThat(TransportConfig.getPort()).isEqualTo("9999"); assertThat(TransportConfig.getHeartbeatIntervalMs().longValue()) .isEqualTo(20000L); @@ -203,7 +199,7 @@ public class SentinelAutoConfigurationTests { } @Test - public void testFlowRestTemplate() { + public void testRestTemplateBlockHandler() { assertThat(restTemplate.getInterceptors().size()).isEqualTo(2); assertThat(restTemplateWithBlockClass.getInterceptors().size()).isEqualTo(1); @@ -231,15 +227,6 @@ public class SentinelAutoConfigurationTests { }).isInstanceOf(RestClientException.class); } - @Test - public void testFallbackRestTemplate() { - ResponseEntity responseEntity = restTemplateWithFallbackClass - .getForEntity(degradeUrl, String.class); - - assertThat(responseEntity.getBody()).isEqualTo("Oops fallback"); - assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - @Configuration static class SentinelTestConfiguration { @@ -252,15 +239,13 @@ public class SentinelAutoConfigurationTests { } @Bean - @SentinelRestTemplate(blockHandlerClass = ExceptionUtil.class, - blockHandler = "handleException") + @SentinelRestTemplate(blockHandlerClass = ExceptionUtil.class, blockHandler = "handleException") RestTemplate restTemplateWithBlockClass() { return new RestTemplate(); } @Bean - @SentinelRestTemplate(fallbackClass = ExceptionUtil.class, - fallback = "fallbackException") + @SentinelRestTemplate(fallbackClass = ExceptionUtil.class, fallback = "fallbackException") RestTemplate restTemplateWithFallbackClass() { return new RestTemplate(); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelBeanAutowiredTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelBeanAutowiredTests.java index 899dde60..05f3ad57 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelBeanAutowiredTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelBeanAutowiredTests.java @@ -41,8 +41,8 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Jim */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = { SentinelBeanAutowiredTests.TestConfig.class }, - properties = { "spring.cloud.sentinel.filter.order=111" }) +@SpringBootTest(classes = { SentinelBeanAutowiredTests.TestConfig.class }, properties = { + "spring.cloud.sentinel.filter.order=111" }) public class SentinelBeanAutowiredTests { @Autowired diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelFeignTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelFeignTests.java index 0939bf0b..9b6228a9 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelFeignTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelFeignTests.java @@ -45,8 +45,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; * @author Jim */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = { SentinelFeignTests.TestConfig.class }, - properties = { "feign.sentinel.enabled=true" }) +@SpringBootTest(classes = { SentinelFeignTests.TestConfig.class }, properties = { + "feign.sentinel.enabled=true" }) public class SentinelFeignTests { @Autowired @@ -118,24 +118,6 @@ public class SentinelFeignTests { assertThat(echoService.equals(fooService)).isEqualTo(Boolean.FALSE); } - @Configuration - @EnableAutoConfiguration - @ImportAutoConfiguration({ SentinelFeignAutoConfiguration.class }) - @EnableFeignClients - public static class TestConfig { - - @Bean - public EchoServiceFallback echoServiceFallback() { - return new EchoServiceFallback(); - } - - @Bean - public CustomFallbackFactory customFallbackFactory() { - return new CustomFallbackFactory(); - } - - } - @FeignClient(value = "test-service", fallback = EchoServiceFallback.class) public interface EchoService { @@ -172,6 +154,24 @@ public class SentinelFeignTests { } + @Configuration + @EnableAutoConfiguration + @ImportAutoConfiguration({ SentinelFeignAutoConfiguration.class }) + @EnableFeignClients + public static class TestConfig { + + @Bean + public EchoServiceFallback echoServiceFallback() { + return new EchoServiceFallback(); + } + + @Bean + public CustomFallbackFactory customFallbackFactory() { + return new CustomFallbackFactory(); + } + + } + public static class EchoServiceFallback implements EchoService { @Override diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelRestTemplateTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelRestTemplateTests.java index 5fb912dd..1e1dc040 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelRestTemplateTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelRestTemplateTests.java @@ -188,13 +188,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - blockHandlerClass = SentinelRestTemplateTests.ExceptionUtil.class, - blockHandler = "handleException", - fallbackClass = SentinelRestTemplateTests.ExceptionUtil.class, - fallback = "fallbackException", - urlCleanerClass = SentinelRestTemplateTests.UrlCleanUtil.class, - urlCleaner = "clean") + @SentinelRestTemplate(blockHandlerClass = ExceptionUtil.class, blockHandler = "handleException", fallbackClass = ExceptionUtil.class, fallback = "fallbackException", urlCleanerClass = UrlCleanUtil.class, urlCleaner = "clean") RestTemplate restTemplate() { return new RestTemplate(); } @@ -211,9 +205,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - blockHandlerClass = SentinelRestTemplateTests.ExceptionUtil.class, - blockHandler = "handleException1") + @SentinelRestTemplate(blockHandlerClass = ExceptionUtil.class, blockHandler = "handleException1") RestTemplate restTemplate() { return new RestTemplate(); } @@ -230,9 +222,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - fallbackClass = SentinelRestTemplateTests.ExceptionUtil.class, - fallback = "fallbackException1") + @SentinelRestTemplate(fallbackClass = ExceptionUtil.class, fallback = "fallbackException1") RestTemplate restTemplate() { return new RestTemplate(); } @@ -249,9 +239,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - blockHandlerClass = SentinelRestTemplateTests.ExceptionUtil.class, - blockHandler = "handleException2") + @SentinelRestTemplate(blockHandlerClass = ExceptionUtil.class, blockHandler = "handleException2") RestTemplate restTemplate() { return new RestTemplate(); } @@ -268,9 +256,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - fallbackClass = SentinelRestTemplateTests.ExceptionUtil.class, - fallback = "fallbackException2") + @SentinelRestTemplate(fallbackClass = ExceptionUtil.class, fallback = "fallbackException2") RestTemplate restTemplate() { return new RestTemplate(); } @@ -344,9 +330,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - urlCleanerClass = SentinelRestTemplateTests.UrlCleanUtil.class, - urlCleaner = "clean1") + @SentinelRestTemplate(urlCleanerClass = UrlCleanUtil.class, urlCleaner = "clean1") RestTemplate restTemplate() { return new RestTemplate(); } @@ -363,9 +347,7 @@ public class SentinelRestTemplateTests { } @Bean - @SentinelRestTemplate( - urlCleanerClass = SentinelRestTemplateTests.UrlCleanUtil.class, - urlCleaner = "clean2") + @SentinelRestTemplate(urlCleanerClass = UrlCleanUtil.class, urlCleaner = "clean2") RestTemplate restTemplate() { return new RestTemplate(); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicatorTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicatorTests.java index b8d68d52..71ddb799 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicatorTests.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicatorTests.java @@ -109,9 +109,9 @@ public class SentinelHealthIndicatorTests { Health health = sentinelHealthIndicator.health(); - assertThat(health.getStatus()).isEqualTo(Status.DOWN); - assertThat(health.getDetails().get("dashboard")).isEqualTo( - new Status(Status.DOWN.getCode(), "localhost:8080 can't be connected")); + assertThat(health.getStatus()).isEqualTo(Status.UNKNOWN); + assertThat(health.getDetails().get("dashboard")).isEqualTo(new Status( + Status.UNKNOWN.getCode(), "localhost:8080 can't be connected")); } @Test @@ -163,13 +163,13 @@ public class SentinelHealthIndicatorTests { Health health = sentinelHealthIndicator.health(); - assertThat(health.getStatus()).isEqualTo(Status.DOWN); + assertThat(health.getStatus()).isEqualTo(Status.UNKNOWN); Map dataSourceDetailMap = (Map) health .getDetails().get("dataSource"); assertThat(dataSourceDetailMap.get("ds1-sentinel-file-datasource")) .isEqualTo(Status.UP); assertThat(dataSourceDetailMap.get("ds2-sentinel-file-datasource")) - .isEqualTo(new Status(Status.DOWN.getCode(), "fileDataSource2 error")); + .isEqualTo(new Status(Status.UNKNOWN.getCode(), "fileDataSource2 error")); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarAutoConfiguration.java index 83ac8c93..6343548b 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarAutoConfiguration.java @@ -18,7 +18,6 @@ package com.alibaba.cloud.sidecar; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; @@ -28,7 +27,6 @@ import org.springframework.web.client.RestTemplate; * @author www.itmuch.com */ @Configuration -@EnableConfigurationProperties(SidecarProperties.class) public class SidecarAutoConfiguration { @Bean diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java index 2976e875..fabccd12 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarHealthChecker.java @@ -16,6 +16,9 @@ package com.alibaba.cloud.sidecar; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; @@ -28,11 +31,14 @@ import org.springframework.core.env.ConfigurableEnvironment; /** * @author www.itmuch.com + * @author yuhuangbin */ public class SidecarHealthChecker { private static final Logger log = LoggerFactory.getLogger(SidecarHealthChecker.class); + private final Map sidecarInstanceCacheMap = new ConcurrentHashMap<>(); + private final SidecarDiscoveryClient sidecarDiscoveryClient; private final HealthIndicator healthIndicator; @@ -52,26 +58,59 @@ public class SidecarHealthChecker { public void check() { Schedulers.single().schedulePeriodically(() -> { + String applicationName = environment.getProperty("spring.application.name"); String ip = sidecarProperties.getIp(); Integer port = sidecarProperties.getPort(); Status status = healthIndicator.health().getStatus(); - String applicationName = environment.getProperty("spring.application.name"); + instanceCache(applicationName, ip, port, status); if (status.equals(Status.UP)) { - this.sidecarDiscoveryClient.registerInstance(applicationName, ip, port); - log.debug( - "Health check success. register this instance. applicationName = {}, ip = {}, port = {}, status = {}", - applicationName, ip, port, status); + if (needRegister(applicationName, ip, port, status)) { + this.sidecarDiscoveryClient.registerInstance(applicationName, ip, + port); + log.info( + "Polyglot service changed and Health check success. register the new instance. applicationName = {}, ip = {}, port = {}, status = {}", + applicationName, ip, port, status); + } } else { log.warn( "Health check failed. unregister this instance. applicationName = {}, ip = {}, port = {}, status = {}", applicationName, ip, port, status); this.sidecarDiscoveryClient.deregisterInstance(applicationName, ip, port); + sidecarInstanceCacheMap.put(applicationName, + buildCache(ip, port, status)); } }, 0, sidecarProperties.getHealthCheckInterval(), TimeUnit.MILLISECONDS); } + private void instanceCache(String applicationName, String ip, Integer port, + Status status) { + sidecarInstanceCacheMap.putIfAbsent(applicationName, + buildCache(ip, port, status)); + } + + private boolean needRegister(String applicationName, String ip, Integer port, + Status status) { + SidecarInstanceCache cacheRecord = sidecarInstanceCacheMap.get(applicationName); + SidecarInstanceCache cache = buildCache(ip, port, status); + + if (!Objects.equals(cache, cacheRecord)) { + // modify the cache info + sidecarInstanceCacheMap.put(applicationName, cache); + return true; + } + return false; + } + + private SidecarInstanceCache buildCache(String ip, Integer port, Status status) { + SidecarInstanceCache cache = new SidecarInstanceCache(); + cache.setIp(ip); + cache.setPort(port); + cache.setStatus(status); + return cache; + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarInstanceCache.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarInstanceCache.java new file mode 100644 index 00000000..0c18f1aa --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/SidecarInstanceCache.java @@ -0,0 +1,76 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.sidecar; + +import java.util.Objects; + +import org.springframework.boot.actuate.health.Status; + +/** + * @author yuhuangbin + */ +public class SidecarInstanceCache { + + private String ip; + + private Integer port; + + private Status status; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SidecarInstanceCache that = (SidecarInstanceCache) o; + return Objects.equals(ip, that.ip) && Objects.equals(port, that.port) + && Objects.equals(status, that.status); + } + + @Override + public int hashCode() { + return Objects.hash(ip, port, status); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulAutoConfiguration.java deleted file mode 100644 index 3789f440..00000000 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulAutoConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-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 - * - * https://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 com.alibaba.cloud.sidecar.consul; - -import java.util.List; - -import com.alibaba.cloud.sidecar.SidecarAutoConfiguration; -import com.alibaba.cloud.sidecar.SidecarDiscoveryClient; -import com.alibaba.cloud.sidecar.SidecarProperties; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; -import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; -import org.springframework.cloud.consul.discovery.HeartbeatProperties; -import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration; -import org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration; -import org.springframework.cloud.consul.serviceregistry.ConsulRegistrationCustomizer; -import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry; -import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author www.itmuch.com - */ -@Configuration -@ConditionalOnClass(ConsulServiceRegistryAutoConfiguration.class) -@AutoConfigureBefore({ ConsulAutoServiceRegistrationAutoConfiguration.class, - SidecarAutoConfiguration.class }) -public class SidecarConsulAutoConfiguration { - - @Bean - public ConsulAutoRegistration consulRegistration( - AutoServiceRegistrationProperties autoServiceRegistrationProperties, - ConsulDiscoveryProperties properties, ApplicationContext applicationContext, - ObjectProvider> registrationCustomizers, - HeartbeatProperties heartbeatProperties, - SidecarProperties sidecarProperties) { - return SidecarConsulAutoRegistration.registration( - autoServiceRegistrationProperties, properties, applicationContext, - registrationCustomizers.getIfAvailable(), - heartbeatProperties, - sidecarProperties); - } - - @Bean - public SidecarDiscoveryClient sidecarDiscoveryClient( - ConsulDiscoveryProperties properties, ConsulServiceRegistry serviceRegistry, - ConsulAutoRegistration registration) { - return new SidecarConsulDiscoveryClient(properties, serviceRegistry, - registration); - } - -} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulAutoRegistration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulAutoRegistration.java deleted file mode 100644 index fa9d3642..00000000 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulAutoRegistration.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-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 - * - * https://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 com.alibaba.cloud.sidecar.consul; - -import java.util.List; - -import com.alibaba.cloud.sidecar.SidecarProperties; -import com.ecwid.consul.v1.agent.model.NewService; - -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; -import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; -import org.springframework.cloud.consul.discovery.HeartbeatProperties; -import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration; -import org.springframework.cloud.consul.serviceregistry.ConsulRegistrationCustomizer; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.Environment; - -/** - * @author www.itmuch.com - */ -public class SidecarConsulAutoRegistration extends ConsulAutoRegistration { - - public SidecarConsulAutoRegistration(NewService service, - AutoServiceRegistrationProperties autoServiceRegistrationProperties, - ConsulDiscoveryProperties properties, ApplicationContext context, - HeartbeatProperties heartbeatProperties) { - super(service, autoServiceRegistrationProperties, properties, context, - heartbeatProperties); - } - - public static ConsulAutoRegistration registration( - AutoServiceRegistrationProperties autoServiceRegistrationProperties, - ConsulDiscoveryProperties properties, ApplicationContext context, - List registrationCustomizers, - HeartbeatProperties heartbeatProperties, - SidecarProperties sidecarProperties) { - - NewService service = new NewService(); - String appName = getAppName(properties, context.getEnvironment()); - service.setId(getInstanceId(sidecarProperties, context.getEnvironment())); - if (!properties.isPreferAgentAddress()) { - service.setAddress(sidecarProperties.getIp()); - } - service.setName(normalizeForDns(appName)); - service.setTags(createTags(properties)); - - // set health check, use alibaba sidecar self's port rather than polyglot app's - // port. - service.setPort( - Integer.valueOf(context.getEnvironment().getProperty("server.port"))); - setCheck(service, autoServiceRegistrationProperties, properties, context, - heartbeatProperties); - - service.setPort(sidecarProperties.getPort()); - - ConsulAutoRegistration registration = new ConsulAutoRegistration(service, - autoServiceRegistrationProperties, properties, context, - heartbeatProperties); - customize(registrationCustomizers, registration); - return registration; - } - - public static String getInstanceId(SidecarProperties sidecarProperties, - Environment environment) { - return String.format("%s-%s-%s", - environment.getProperty("spring.application.name"), - sidecarProperties.getIp(), sidecarProperties.getPort()); - } - -} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulDiscoveryClient.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulDiscoveryClient.java deleted file mode 100644 index 49088f3a..00000000 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/consul/SidecarConsulDiscoveryClient.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013-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 - * - * https://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 com.alibaba.cloud.sidecar.consul; - -import com.alibaba.cloud.sidecar.SidecarDiscoveryClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; -import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration; -import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry; - -/** - * @author www.itmuch.com - */ -public class SidecarConsulDiscoveryClient implements SidecarDiscoveryClient { - - private static final Logger log = LoggerFactory - .getLogger(SidecarConsulDiscoveryClient.class); - - private final ConsulDiscoveryProperties properties; - - private final ConsulServiceRegistry serviceRegistry; - - private final ConsulAutoRegistration registration; - - public SidecarConsulDiscoveryClient(ConsulDiscoveryProperties properties, - ConsulServiceRegistry serviceRegistry, ConsulAutoRegistration registration) { - this.properties = properties; - this.serviceRegistry = serviceRegistry; - this.registration = registration; - } - - @Override - public void registerInstance(String applicationName, String ip, Integer port) { - - if (!this.properties.isRegister()) { - log.debug("Registration disabled."); - return; - } - - serviceRegistry.register(registration); - - } - - @Override - public void deregisterInstance(String applicationName, String ip, Integer port) { - if (!this.properties.isRegister() || !this.properties.isDeregister()) { - return; - } - serviceRegistry.deregister(registration); - } - -} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosAutoConfiguration.java index 0e80d6e9..feaf86fe 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosAutoConfiguration.java @@ -17,6 +17,7 @@ package com.alibaba.cloud.sidecar.nacos; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration; import com.alibaba.cloud.sidecar.SidecarAutoConfiguration; import com.alibaba.cloud.sidecar.SidecarDiscoveryClient; @@ -25,6 +26,7 @@ import com.alibaba.cloud.sidecar.SidecarProperties; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -35,6 +37,7 @@ import org.springframework.context.annotation.Configuration; @AutoConfigureBefore({ NacosDiscoveryAutoConfiguration.class, SidecarAutoConfiguration.class }) @ConditionalOnClass(NacosDiscoveryProperties.class) +@EnableConfigurationProperties(SidecarProperties.class) public class SidecarNacosAutoConfiguration { @Bean @@ -47,8 +50,10 @@ public class SidecarNacosAutoConfiguration { @Bean @ConditionalOnMissingBean public SidecarDiscoveryClient sidecarDiscoveryClient( + NacosServiceManager nacosServiceManager, SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties) { - return new SidecarNacosDiscoveryClient(sidecarNacosDiscoveryProperties); + return new SidecarNacosDiscoveryClient(nacosServiceManager, + sidecarNacosDiscoveryProperties); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryClient.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryClient.java index e4302afe..0c32fde4 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryClient.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryClient.java @@ -16,8 +16,10 @@ package com.alibaba.cloud.sidecar.nacos; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.sidecar.SidecarDiscoveryClient; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,10 +30,10 @@ public class SidecarNacosDiscoveryClient implements SidecarDiscoveryClient { private static final Logger log = LoggerFactory .getLogger(SidecarNacosDiscoveryClient.class); - private final SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties; + private NacosServiceManager nacosServiceManager; - public SidecarNacosDiscoveryClient( + public SidecarNacosDiscoveryClient(NacosServiceManager nacosServiceManager, SidecarNacosDiscoveryProperties sidecarNacosDiscoveryProperties) { this.sidecarNacosDiscoveryProperties = sidecarNacosDiscoveryProperties; } @@ -39,8 +41,8 @@ public class SidecarNacosDiscoveryClient implements SidecarDiscoveryClient { @Override public void registerInstance(String applicationName, String ip, Integer port) { try { - this.sidecarNacosDiscoveryProperties.namingServiceInstance() - .registerInstance(applicationName, ip, port); + this.namingService().registerInstance(applicationName, + sidecarNacosDiscoveryProperties.getGroup(), ip, port); } catch (NacosException e) { log.warn("nacos exception happens", e); @@ -50,12 +52,17 @@ public class SidecarNacosDiscoveryClient implements SidecarDiscoveryClient { @Override public void deregisterInstance(String applicationName, String ip, Integer port) { try { - this.sidecarNacosDiscoveryProperties.namingServiceInstance() - .deregisterInstance(applicationName, ip, port); + this.namingService().deregisterInstance(applicationName, + sidecarNacosDiscoveryProperties.getGroup(), ip, port); } catch (NacosException e) { log.warn("nacos exception happens", e); } } + private NamingService namingService() { + return nacosServiceManager + .getNamingService(sidecarNacosDiscoveryProperties.getNacosProperties()); + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryProperties.java index d58c60c1..a6c5a978 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sidecar/src/main/java/com/alibaba/cloud/sidecar/nacos/SidecarNacosDiscoveryProperties.java @@ -16,29 +16,29 @@ package com.alibaba.cloud.sidecar.nacos; -import java.net.SocketException; - import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.sidecar.SidecarProperties; -import org.apache.commons.lang3.StringUtils; + +import org.springframework.util.StringUtils; /** * @author itmuch.com + * @author yuhuangbin */ public class SidecarNacosDiscoveryProperties extends NacosDiscoveryProperties { - private final SidecarProperties sidecarProperties; + SidecarProperties sidecarProperties; public SidecarNacosDiscoveryProperties(SidecarProperties sidecarProperties) { this.sidecarProperties = sidecarProperties; } @Override - public void init() throws SocketException { + public void init() throws Exception { super.init(); String ip = sidecarProperties.getIp(); - if (StringUtils.isNotBlank(ip)) { + if (!StringUtils.isEmpty(ip)) { this.setIp(ip); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/actuate/DubboMetadataEndpointAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/actuate/DubboMetadataEndpointAutoConfiguration.java index d260f5d1..6ffea53b 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/actuate/DubboMetadataEndpointAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/actuate/DubboMetadataEndpointAutoConfiguration.java @@ -31,8 +31,7 @@ import org.springframework.context.annotation.PropertySource; * * @author Mercy */ -@ConditionalOnClass( - name = "org.springframework.boot.actuate.endpoint.annotation.Endpoint") +@ConditionalOnClass(name = "org.springframework.boot.actuate.endpoint.annotation.Endpoint") @PropertySource("classpath:/META-INF/dubbo/default/actuator-endpoints.properties") @ManagementContextConfiguration public class DubboMetadataEndpointAutoConfiguration { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java index 725950b3..efe083ea 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/annotation/DubboTransported.java @@ -37,12 +37,16 @@ import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_RETRIES; * Spring Cloud Service-to-Service call is transported by Dubbo under the hood, there are * two main scenarios: *
    - *
  1. {@link FeignClient @FeignClient} annotated classes: If - * {@link DubboTransported @DubboTransported} annotated classes, the invocation of all + *
  2. {@link FeignClient @FeignClient} annotated classes: + *
      + * If {@link DubboTransported @DubboTransported} annotated classes, the invocation of all * methods of {@link FeignClient @FeignClient} annotated classes. - * + *
    + *
      * If {@link DubboTransported @DubboTransported} annotated methods of - * {@link FeignClient @FeignClient} annotated classes. + * {@link FeignClient @FeignClient} annotated classes. + *
    + *
  3. *
  4. {@link LoadBalanced @LoadBalanced} {@link RestTemplate} annotated field, method and * parameters
  5. *
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java index 23b7987d..b0bdd5f5 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboLoadBalancedRestTemplateAutoConfiguration.java @@ -111,7 +111,8 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements @Override public void afterSingletonsInstantiated() { loadBalancerInterceptorBean = retryLoadBalancerInterceptor != null - ? retryLoadBalancerInterceptor : loadBalancerInterceptor; + ? retryLoadBalancerInterceptor + : loadBalancerInterceptor; } /** @@ -145,7 +146,7 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements * Gets the annotation attributes {@link RestTemplate} bean being annotated * {@link DubboTransported @DubboTransported}. * @param beanName the bean name of {@link LoadBalanced @LoadBalanced} - * {@link RestTemplate} + * {@link RestTemplate} * @param attributesResolver {@link DubboTransportedAttributesResolver} * @return non-null {@link Map} */ @@ -170,8 +171,8 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements * {@link LoadBalancerInterceptor} Bean. * @param restTemplate {@link LoadBalanced @LoadBalanced} {@link RestTemplate} Bean * @param dubboTranslatedAttributes the annotation dubboTranslatedAttributes - * {@link RestTemplate} bean being annotated - * {@link DubboTransported @DubboTransported} + * {@link RestTemplate} bean being annotated + * {@link DubboTransported @DubboTransported} */ private void adaptRestTemplate(RestTemplate restTemplate, Map dubboTranslatedAttributes) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java index 5b1cddf7..f8946fa7 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java @@ -17,18 +17,18 @@ package com.alibaba.cloud.dubbo.autoconfigure; import java.util.Collection; -import java.util.Optional; import java.util.function.Supplier; import com.alibaba.cloud.dubbo.metadata.DubboProtocolConfigSupplier; import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; -import com.alibaba.cloud.dubbo.metadata.repository.MetadataServiceInstanceSelector; +import com.alibaba.cloud.dubbo.metadata.repository.RandomServiceInstanceSelector; +import com.alibaba.cloud.dubbo.metadata.repository.ServiceInstanceSelector; import com.alibaba.cloud.dubbo.metadata.resolver.DubboServiceBeanMetadataResolver; import com.alibaba.cloud.dubbo.metadata.resolver.MetadataResolver; -import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory; import com.alibaba.cloud.dubbo.service.DubboMetadataServiceExporter; import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy; import com.alibaba.cloud.dubbo.service.IntrospectiveDubboMetadataService; +import com.alibaba.cloud.dubbo.util.DubboMetadataUtils; import com.alibaba.cloud.dubbo.util.JSONUtils; import feign.Contract; import org.apache.dubbo.config.ProtocolConfig; @@ -44,7 +44,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.EventListener; -import org.springframework.util.CollectionUtils; /** * Spring Boot Auto-Configuration class for Dubbo Metadata. @@ -53,7 +52,8 @@ import org.springframework.util.CollectionUtils; */ @Configuration @Import({ DubboServiceMetadataRepository.class, IntrospectiveDubboMetadataService.class, - DubboMetadataServiceExporter.class, JSONUtils.class }) + DubboMetadataServiceExporter.class, JSONUtils.class, + DubboMetadataServiceProxy.class, DubboMetadataUtils.class }) public class DubboMetadataAutoConfiguration { @Autowired @@ -73,9 +73,8 @@ public class DubboMetadataAutoConfiguration { @Bean @ConditionalOnMissingBean - public MetadataServiceInstanceSelector metadataServiceInstanceSelector() { - return serviceInstances -> CollectionUtils.isEmpty(serviceInstances) - ? Optional.empty() : serviceInstances.stream().findAny(); + public ServiceInstanceSelector metadataServiceInstanceSelector() { + return new RandomServiceInstanceSelector(); } @Bean @@ -84,15 +83,7 @@ public class DubboMetadataAutoConfiguration { return new DubboProtocolConfigSupplier(protocols); } - @Bean - @ConditionalOnMissingBean - public DubboMetadataServiceProxy dubboMetadataConfigServiceProxy( - DubboGenericServiceFactory factory) { - return new DubboMetadataServiceProxy(factory); - } - // Event-Handling - @EventListener(ServiceBeanExportedEvent.class) public void onServiceBeanExported(ServiceBeanExportedEvent event) { ServiceBean serviceBean = event.getServiceBean(); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java index e378e753..c0be4eae 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java @@ -35,8 +35,8 @@ import static com.alibaba.cloud.dubbo.autoconfigure.DubboOpenFeignAutoConfigurat * @author Mercy */ @ConditionalOnClass(name = { "feign.Feign", TARGETER_CLASS_NAME }) -@AutoConfigureAfter( - name = { "org.springframework.cloud.openfeign.FeignAutoConfiguration" }) +@AutoConfigureAfter(name = { + "org.springframework.cloud.openfeign.FeignAutoConfiguration" }) @Configuration public class DubboOpenFeignAutoConfiguration { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceAutoConfiguration.java index 1e9fe56f..38a35e25 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceAutoConfiguration.java @@ -24,15 +24,11 @@ import com.alibaba.cloud.dubbo.service.parameter.RequestBodyServiceParameterReso import com.alibaba.cloud.dubbo.service.parameter.RequestHeaderServiceParameterResolver; import com.alibaba.cloud.dubbo.service.parameter.RequestParamServiceParameterResolver; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; 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.Environment; -import org.springframework.core.env.PropertyResolver; /** * Spring Boot Auto-Configuration class for Dubbo Service. @@ -49,17 +45,6 @@ public class DubboServiceAutoConfiguration { return new DubboGenericServiceFactory(); } - /** - * Build a primary {@link PropertyResolver} bean to {@link Autowired @Autowired}. - * @param environment {@link Environment} - * @return alias bean for {@link Environment} - */ - @Bean - @Primary - public PropertyResolver primaryPropertyResolver(Environment environment) { - return environment; - } - @Configuration @Import({ DubboGenericServiceExecutionContextFactory.class, RequestParamServiceParameterResolver.class, diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceDiscoveryAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceDiscoveryAutoConfiguration.java index be9311ba..0deb8897 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceDiscoveryAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceDiscoveryAutoConfiguration.java @@ -33,6 +33,7 @@ import com.alibaba.cloud.dubbo.registry.AbstractSpringCloudRegistry; import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent; import com.alibaba.cloud.dubbo.registry.event.SubscribedServicesChangedEvent; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.discovery.NacosWatch; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; @@ -56,6 +57,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -97,12 +99,11 @@ import static org.springframework.util.StringUtils.hasText; @Configuration @ConditionalOnClass(name = "org.springframework.cloud.client.discovery.DiscoveryClient") @ConditionalOnProperty(name = "spring.cloud.discovery.enabled", matchIfMissing = true) -@AutoConfigureAfter( - name = { EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME, - ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME, - CONSUL_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME, - NACOS_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME }, - value = { DubboServiceRegistrationAutoConfiguration.class }) +@AutoConfigureAfter(name = { EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME, + ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME, + CONSUL_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME, + NACOS_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME }, value = { + DubboServiceRegistrationAutoConfiguration.class }) public class DubboServiceDiscoveryAutoConfiguration { /** @@ -135,6 +136,9 @@ public class DubboServiceDiscoveryAutoConfiguration { */ private final ObjectProvider> heartbeatEventChangedPredicate; + @Value("${spring.application.name:${dubbo.application.name:application}}") + private String currentApplicationName; + public DubboServiceDiscoveryAutoConfiguration( DubboServiceMetadataRepository dubboServiceMetadataRepository, ApplicationEventPublisher applicationEventPublisher, @@ -154,10 +158,12 @@ public class DubboServiceDiscoveryAutoConfiguration { * NotifyListener) */ private void dispatchServiceInstancesChangedEvent(String serviceName, - Collection serviceInstances) { - if (!hasText(serviceName) || serviceInstances == null) { + List serviceInstances) { + if (!hasText(serviceName) || Objects.equals(currentApplicationName, serviceName) + || serviceInstances == null) { return; } + ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent(serviceName, serviceInstances); if (logger.isInfoEnabled()) { @@ -512,8 +518,10 @@ public class DubboServiceDiscoveryAutoConfiguration { */ private final Set listeningServices; - NacosConfiguration(NacosDiscoveryProperties nacosDiscoveryProperties) { - this.namingService = nacosDiscoveryProperties.namingServiceInstance(); + NacosConfiguration(NacosServiceManager nacosServiceManager, + NacosDiscoveryProperties nacosDiscoveryProperties) { + this.namingService = nacosServiceManager + .getNamingService(nacosDiscoveryProperties.getNacosProperties()); this.nacosDiscoveryProperties = nacosDiscoveryProperties; this.listeningServices = new ConcurrentSkipListSet<>(); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index 855b4381..3415bcee 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -66,12 +66,11 @@ import static org.springframework.util.ObjectUtils.isEmpty; */ @Configuration @Import({ DubboServiceRegistrationEventPublishingAspect.class }) -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter(name = { EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME, CONSUL_AUTO_SERVICE_AUTO_CONFIGURATION_CLASS_NAME, - "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration" }, - value = { DubboMetadataAutoConfiguration.class }) + "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration" }, value = { + DubboMetadataAutoConfiguration.class }) public class DubboServiceRegistrationAutoConfiguration { /** diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java index 9c411506..a7d19424 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java @@ -53,8 +53,7 @@ import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAuto */ @Configuration @ConditionalOnNotWebApplication -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", - matchIfMissing = true) +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter(DubboServiceRegistrationAutoConfiguration.class) @Aspect public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { @@ -76,12 +75,17 @@ public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { @Around("execution(* org.springframework.cloud.client.serviceregistry.Registration.getPort())") public Object getPort(ProceedingJoinPoint pjp) throws Throwable { + /** + * move setServerPort from onApplicationStarted() to here for this issue : + * https://github.com/alibaba/spring-cloud-alibaba/issues/1383 + * @author theonefx + */ + setServerPort(); return serverPort != null ? serverPort : pjp.proceed(); } @EventListener(ApplicationStartedEvent.class) public void onApplicationStarted() { - setServerPort(); register(); } @@ -99,18 +103,22 @@ public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { */ private void setServerPort() { if (serverPort == null) { - for (List urls : repository.getAllExportedUrls().values()) { - urls.stream() - .filter(url -> REST_PROTOCOL.equalsIgnoreCase(url.getProtocol())) - .findFirst().ifPresent(url -> { - serverPort = url.getPort(); - }); - - // If REST protocol is not present, use any applied port. + synchronized (this) { if (serverPort == null) { - urls.stream().findAny().ifPresent(url -> { - serverPort = url.getPort(); - }); + for (List urls : repository.getAllExportedUrls().values()) { + urls.stream().filter( + url -> REST_PROTOCOL.equalsIgnoreCase(url.getProtocol())) + .findFirst().ifPresent(url -> { + serverPort = url.getPort(); + }); + + // If REST protocol is not present, use any applied port. + if (serverPort == null) { + urls.stream().findAny().ifPresent(url -> { + serverPort = url.getPort(); + }); + } + } } } } @@ -126,6 +134,7 @@ public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered( ServiceInstancePreRegisteredEvent event) { + setServerPort(); registration.setPort(serverPort); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java index 80a0a072..577d19e5 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java @@ -22,6 +22,8 @@ import java.util.Set; import org.springframework.boot.context.properties.ConfigurationProperties; +import static com.alibaba.cloud.dubbo.util.DubboCloudConstants.CONFIG_PROPERTY_PREFIX; +import static com.alibaba.cloud.dubbo.util.DubboCloudConstants.DUBBO_CLOUD_REGISTRY_PROPERTY_VALUE; import static org.springframework.util.StringUtils.commaDelimitedListToStringArray; import static org.springframework.util.StringUtils.hasText; import static org.springframework.util.StringUtils.trimAllWhitespace; @@ -31,7 +33,7 @@ import static org.springframework.util.StringUtils.trimAllWhitespace; * * @author Mercy */ -@ConfigurationProperties(prefix = "dubbo.cloud") +@ConfigurationProperties(prefix = CONFIG_PROPERTY_PREFIX) public class DubboCloudProperties { /** @@ -47,6 +49,8 @@ public class DubboCloudProperties { */ private String subscribedServices = ALL_DUBBO_SERVICES; + private String registryType = DUBBO_CLOUD_REGISTRY_PROPERTY_VALUE; + public String getSubscribedServices() { return subscribedServices; } @@ -79,4 +83,12 @@ public class DubboCloudProperties { return Collections.unmodifiableSet(subscribedServices); } + public String getRegistryType() { + return registryType; + } + + public void setRegistryType(String registryType) { + this.registryType = registryType; + } + } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java index 10b7b743..5af1e58f 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboNonWebApplicationEnvironmentPostProcessor.java @@ -34,8 +34,8 @@ import org.springframework.core.env.PropertySource; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_PROTOCOL; import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties; +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_PROTOCOL; /** * Dubbo {@link WebApplicationType#NONE Non-Web Application} @@ -141,7 +141,8 @@ public class DubboNonWebApplicationEnvironmentPostProcessor DEFAULT_PROTOCOL); return isRestProtocol(protocol) - ? environment.getProperty(PROTOCOL_PORT_PROPERTY_NAME) : null; + ? environment.getProperty(PROTOCOL_PORT_PROPERTY_NAME) + : null; } private String getRestPortFromProtocolsProperties( diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestConsumersMatcher.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestConsumersMatcher.java index e97f2559..90b0f115 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestConsumersMatcher.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestConsumersMatcher.java @@ -41,7 +41,7 @@ public class HttpRequestConsumersMatcher extends AbstractHttpRequestMatcher { /** * Creates a new instance from 0 or more "consumes" expressions. * @param consumes consumes expressions if 0 expressions are provided, the condition - * will match to every request + * will match to every request */ public HttpRequestConsumersMatcher(String... consumes) { this(consumes, null); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestParamsMatcher.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestParamsMatcher.java index 159c8746..fd9ab679 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestParamsMatcher.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/http/matcher/HttpRequestParamsMatcher.java @@ -34,10 +34,10 @@ public class HttpRequestParamsMatcher extends AbstractHttpRequestMatcher { /** * @param params The pattern of params : - *
    - *
  • name=value
  • - *
  • name
  • - *
+ *
    + *
  • name=value
  • + *
  • name
  • + *
*/ public HttpRequestParamsMatcher(String... params) { this.expressions = parseExpressions(params); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboProtocolConfigSupplier.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboProtocolConfigSupplier.java index 1dfb8e73..775d360c 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboProtocolConfigSupplier.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboProtocolConfigSupplier.java @@ -65,7 +65,6 @@ public class DubboProtocolConfigSupplier implements Supplier { if (protocolConfig == null) { protocolConfig = new ProtocolConfig(); protocolConfig.setName(DEFAULT_PROTOCOL); - protocolConfig.setPort(-1); } return protocolConfig; diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java index 372604a0..a5be34df 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java @@ -22,9 +22,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.PostConstruct; @@ -38,6 +36,7 @@ import com.alibaba.cloud.dubbo.registry.event.SubscribedServicesChangedEvent; import com.alibaba.cloud.dubbo.service.DubboMetadataService; import com.alibaba.cloud.dubbo.service.DubboMetadataServiceExporter; import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy; +import com.alibaba.cloud.dubbo.util.DubboMetadataUtils; import com.alibaba.cloud.dubbo.util.JSONUtils; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; @@ -61,15 +60,15 @@ import org.springframework.util.MultiValueMap; import static com.alibaba.cloud.dubbo.env.DubboCloudProperties.ALL_DUBBO_SERVICES; import static com.alibaba.cloud.dubbo.http.DefaultHttpRequest.builder; -import static java.lang.String.format; import static java.lang.String.valueOf; -import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; -import static java.util.Collections.unmodifiableList; import static java.util.Collections.unmodifiableMap; import static java.util.Collections.unmodifiableSet; -import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_PREFIX; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME; import static org.springframework.util.CollectionUtils.isEmpty; import static org.springframework.util.StringUtils.hasText; @@ -85,14 +84,15 @@ public class DubboServiceMetadataRepository /** * The prefix of {@link DubboMetadataService} : "dubbo.metadata-service.". */ - public static final String DUBBO_METADATA_SERVICE_PREFIX = "dubbo.metadata-service."; + @Deprecated + public static final String DUBBO_METADATA_SERVICE_PREFIX = METADATA_SERVICE_PREFIX; /** * The {@link URL URLs} property name of {@link DubboMetadataService} : * "dubbo.metadata-service.urls". */ - public static final String DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME = DUBBO_METADATA_SERVICE_PREFIX - + "urls"; + @Deprecated + public static final String DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_URLS_PROPERTY_NAME; /** * The {@link String#format(String, Object...) pattern} of dubbo protocols port. @@ -108,11 +108,6 @@ public class DubboServiceMetadataRepository */ private final Object monitor = new Object(); - /** - * A {@link Set} of service names that had been initialized. - */ - private final Set initializedServices = new LinkedHashSet<>(); - /** * All exported {@link URL urls} {@link Map} whose key is the return value of * {@link URL#getServiceKey()} method and value is the {@link List} of {@link URL @@ -122,12 +117,6 @@ public class DubboServiceMetadataRepository // =================================== Registration // =================================== // - /** - * The subscribed {@link URL urls} {@link Map} of {@link DubboMetadataService}, whose - * key is the return value of {@link URL#getServiceKey()} method and value is the - * {@link List} of {@link URL URLs}. - */ - private final MultiValueMap subscribedDubboMetadataServiceURLs = new LinkedMultiValueMap<>(); // ==================================================================================== // // @@ -172,7 +161,7 @@ public class DubboServiceMetadataRepository private DiscoveryClient discoveryClient; @Autowired - private MetadataServiceInstanceSelector metadataServiceInstanceSelector; + private ServiceInstanceSelector serviceInstanceSelector; @Autowired private JSONUtils jsonUtils; @@ -180,6 +169,9 @@ public class DubboServiceMetadataRepository @Autowired private InetUtils inetUtils; + @Autowired + private DubboMetadataUtils dubboMetadataUtils; + @Value("${spring.application.name}") private String currentApplicationName; @@ -275,28 +267,11 @@ public class DubboServiceMetadataRepository * @param serviceName service of name */ public void initializeMetadata(String serviceName) { - synchronized (monitor) { - if (initializedServices.contains(serviceName)) { - if (logger.isDebugEnabled()) { - logger.debug( - "The metadata of Dubbo service[name : {}] has been initialized", - serviceName); - } - } - else { - if (logger.isInfoEnabled()) { - logger.info( - "The metadata of Dubbo service[name : {}] is about to be initialized", - serviceName); - } + initDubboRestServiceMetadataRepository(serviceName); + } - if (initSubscribedDubboMetadataService(serviceName)) { - // mark this service name having been initialized - initializedServices.add(serviceName); - } - - } - } + private DubboMetadataService getProxy(String serviceName) { + return dubboMetadataConfigServiceProxy.getProxy(serviceName); } /** @@ -307,15 +282,8 @@ public class DubboServiceMetadataRepository */ public void removeMetadataAndInitializedService(String serviceName, URL url) { synchronized (monitor) { - initializedServices.remove(serviceName); + dubboMetadataConfigServiceProxy.removeProxy(serviceName); dubboRestServiceMetadataRepository.remove(serviceName); - // fix #1260 if the subscribedDubboMetadataServiceURLs removed fail,old meta - // information will be retained - if (DubboMetadataService.class.getName().equals(url.getServiceInterface())) { - String serviceKey = url.getServiceKey(); - subscribedDubboMetadataServiceURLs.remove(serviceKey); - } - } } @@ -345,8 +313,7 @@ public class DubboServiceMetadataRepository private void addDubboMetadataServiceURLsMetadata(Map metadata, List dubboMetadataServiceURLs) { String dubboMetadataServiceURLsJSON = jsonUtils.toJSON(dubboMetadataServiceURLs); - metadata.put(DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME, - dubboMetadataServiceURLsJSON); + metadata.put(METADATA_SERVICE_URLS_PROPERTY_NAME, dubboMetadataServiceURLsJSON); } private void addDubboProtocolsPortMetadata(Map metadata) { @@ -359,15 +326,6 @@ public class DubboServiceMetadataRepository }); } - /** - * Get the property name of Dubbo Protocol. - * @param protocol Dubbo Protocol - * @return non-null - */ - public String getDubboProtocolPropertyName(String protocol) { - return format(DUBBO_PROTOCOLS_PORT_PROPERTY_NAME_PATTERN, protocol); - } - /** * Publish the {@link Set} of {@link ServiceRestMetadata}. * @param serviceRestMetadataSet the {@link Set} of {@link ServiceRestMetadata} @@ -389,27 +347,6 @@ public class DubboServiceMetadataRepository return unmodifiableSet(serviceRestMetadata); } - public List findSubscribedDubboMetadataServiceURLs(String serviceName, - String group, String version, String protocol) { - String serviceKey = URL.buildKey(serviceName, group, version); - - List urls = null; - - synchronized (monitor) { - urls = subscribedDubboMetadataServiceURLs.get(serviceKey); - } - - if (isEmpty(urls)) { - return emptyList(); - } - - return hasText(protocol) - ? urls.stream() - .filter(url -> url.getProtocol().equalsIgnoreCase(protocol)) - .collect(Collectors.toList()) - : unmodifiableList(urls); - } - /** * The specified service is subscribe or not. * @param serviceName the service name @@ -459,24 +396,13 @@ public class DubboServiceMetadataRepository return allExportedURLs.keySet(); } - /** - * Get the {@link URL urls} that {@link DubboMetadataService} exported by the - * specified {@link ServiceInstance}. - * @param serviceInstance {@link ServiceInstance} - * @return the mutable {@link URL urls} - */ - public List getDubboMetadataServiceURLs(ServiceInstance serviceInstance) { - Map metadata = serviceInstance.getMetadata(); - String dubboURLsJSON = metadata.get(DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME); - return jsonUtils.toURLs(dubboURLsJSON); - } - public Integer getDubboProtocolPort(ServiceInstance serviceInstance, String protocol) { - String protocolProperty = getDubboProtocolPropertyName(protocol); - Map metadata = serviceInstance.getMetadata(); - String protocolPort = metadata.get(protocolProperty); - return hasText(protocolPort) ? Integer.valueOf(protocolPort) : null; + return dubboMetadataUtils.getDubboProtocolPort(serviceInstance, protocol); + } + + private String getDubboProtocolPropertyName(String protocol) { + return dubboMetadataUtils.getDubboProtocolPropertyName(protocol); } public List getExportedURLs(String serviceInterface, String group, @@ -492,6 +418,11 @@ public class DubboServiceMetadataRepository protected void initDubboRestServiceMetadataRepository(String serviceName) { if (dubboRestServiceMetadataRepository.containsKey(serviceName)) { + if (logger.isDebugEnabled()) { + logger.debug( + "The metadata of Dubbo service[name : {}] has been initialized", + serviceName); + } return; } @@ -600,8 +531,7 @@ public class DubboServiceMetadataRepository Set metadata = emptySet(); - DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy - .getProxy(serviceName); + DubboMetadataService dubboMetadataService = getProxy(serviceName); if (dubboMetadataService != null) { try { @@ -626,68 +556,29 @@ public class DubboServiceMetadataRepository subscribedServices.remove(currentApplicationName); } - protected Boolean initSubscribedDubboMetadataService(String serviceName) { - // this need to judge whether the initialization is successful or not. The failed - // initialization will not change the initializedServices - Optional optionalServiceInstance = metadataServiceInstanceSelector - .choose(discoveryClient.getInstances(serviceName)); - if (!((Optional) optionalServiceInstance).isPresent()) { - return false; - } - ServiceInstance serviceInstance = optionalServiceInstance.get(); - if (null == serviceInstance) { - return false; - } - List dubboMetadataServiceURLs = getDubboMetadataServiceURLs(serviceInstance); - if (dubboMetadataServiceURLs.isEmpty()) { - return false; - } - for (URL dubboMetadataServiceURL : dubboMetadataServiceURLs) { - try { - initSubscribedDubboMetadataServiceURL(dubboMetadataServiceURL); - DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy - .getProxy(serviceName); - if (dubboMetadataService == null) { - dubboMetadataService = initDubboMetadataServiceProxy( - dubboMetadataServiceURL); - } - - if (dubboMetadataService == null) { - removeMetadataAndInitializedService(serviceName, - dubboMetadataServiceURL); - return false; - } - } - catch (Throwable e) { - if (logger.isErrorEnabled()) { - logger.error(e.getMessage(), e); - } - return false; - } - } - initDubboRestServiceMetadataRepository(serviceName); - return true; - } - - private void initSubscribedDubboMetadataServiceURL(URL dubboMetadataServiceURL) { - // add subscriptions - String serviceKey = dubboMetadataServiceURL.getServiceKey(); - subscribedDubboMetadataServiceURLs.add(serviceKey, dubboMetadataServiceURL); - } - - private DubboMetadataService initDubboMetadataServiceProxy( - URL dubboMetadataServiceURL) { - String serviceName = dubboMetadataServiceURL.getParameter(APPLICATION_KEY); - String version = dubboMetadataServiceURL.getParameter(VERSION_KEY); - // Initialize DubboMetadataService with right version - return dubboMetadataConfigServiceProxy.initProxy(serviceName, version); - - } - @Override public void setApplicationEventPublisher( ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } -} \ No newline at end of file + public List findSubscribedDubboMetadataServiceURLs(URL subscribedURL) { + // The parameter of "group" as the service name + String serviceInterface = subscribedURL.getServiceInterface(); + String group = subscribedURL.getParameter(GROUP_KEY); + String version = subscribedURL.getParameter(VERSION_KEY); + String protocol = subscribedURL.getParameter(PROTOCOL_KEY); + List serviceInstances = discoveryClient.getInstances(group); + List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances, + serviceInterface, version, protocol); + + if (logger.isInfoEnabled()) { + logger.info( + "The DubboMetadataService of service [name : {} , instances : {}] URLs[protocol : {} , size : {}] has been subscribed.", + group, serviceInstances.size(), protocol, urls.size()); + } + + return urls; + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/RandomServiceInstanceSelector.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/RandomServiceInstanceSelector.java new file mode 100644 index 00000000..3cc911c4 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/RandomServiceInstanceSelector.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.dubbo.metadata.repository; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +import org.springframework.cloud.client.ServiceInstance; + +import static java.util.Optional.of; +import static org.springframework.util.CollectionUtils.isEmpty; + +/** + * Random {@link ServiceInstanceSelector}. + * + * @author Mercy + */ +public class RandomServiceInstanceSelector implements ServiceInstanceSelector { + + @Override + public Optional select(List serviceInstances) { + if (isEmpty(serviceInstances)) { + return Optional.empty(); + } + ThreadLocalRandom random = ThreadLocalRandom.current(); + return of(serviceInstances.get(random.nextInt(serviceInstances.size()))); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/MetadataServiceInstanceSelector.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/ServiceInstanceSelector.java similarity index 86% rename from spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/MetadataServiceInstanceSelector.java rename to spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/ServiceInstanceSelector.java index 821e3043..575cdcf0 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/MetadataServiceInstanceSelector.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/ServiceInstanceSelector.java @@ -26,13 +26,13 @@ import org.springframework.cloud.client.ServiceInstance; * * @author liuxx */ -public interface MetadataServiceInstanceSelector { +public interface ServiceInstanceSelector { /** - * choose a service instance to get metadata. + * Select a service instance to get metadata. * @param serviceInstances all service instance * @return the service instance to get metadata */ - Optional choose(List serviceInstances); + Optional select(List serviceInstances); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java index ae511c28..f6434f3c 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java @@ -63,6 +63,7 @@ import static org.springframework.util.StringUtils.hasText; * * @author Mercy */ +@Deprecated public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { /** @@ -370,12 +371,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { } private void subscribeDubboMetadataServiceURLs(URL url, NotifyListener listener) { - String serviceInterface = url.getServiceInterface(); - String group = url.getParameter(GROUP_KEY); - String version = url.getParameter(VERSION_KEY); - String protocol = url.getParameter(PROTOCOL_KEY); - List urls = repository.findSubscribedDubboMetadataServiceURLs( - serviceInterface, group, version, protocol); + List urls = repository.findSubscribedDubboMetadataServiceURLs(url); listener.notify(urls); } @@ -398,4 +394,4 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface()); } -} \ No newline at end of file +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java new file mode 100644 index 00000000..dbede698 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java @@ -0,0 +1,511 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.dubbo.registry; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; +import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent; +import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory; +import com.alibaba.cloud.dubbo.service.DubboMetadataService; +import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy; +import com.alibaba.cloud.dubbo.util.DubboMetadataUtils; +import com.alibaba.cloud.dubbo.util.JSONUtils; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.URLBuilder; +import org.apache.dubbo.registry.NotifyListener; +import org.apache.dubbo.registry.support.FailbackRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.util.CollectionUtils; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.stream.StreamSupport.stream; +import static org.apache.dubbo.common.URLBuilder.from; +import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; +import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY; +import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL; +import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty; +import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME; +import static org.springframework.util.StringUtils.hasText; + +/** + * Dubbo Cloud {@link FailbackRegistry} is based on Spring Cloud {@link DiscoveryClient}. + * + * @author Mercy + */ +public class DubboCloudRegistry extends FailbackRegistry { + + /** + * The parameter name of {@link #servicesLookupInterval}. + */ + public static final String SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.services.lookup.interval"; + + protected static final String DUBBO_METADATA_SERVICE_CLASS_NAME = DubboMetadataService.class + .getName(); + + /** + * Caches the IDs of {@link ApplicationListener}. + */ + private static final Set registerListeners = new HashSet<>(); + + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + private final DiscoveryClient discoveryClient; + + private final DubboServiceMetadataRepository repository; + + private final DubboMetadataServiceProxy dubboMetadataConfigServiceProxy; + + private final JSONUtils jsonUtils; + + private final DubboGenericServiceFactory dubboGenericServiceFactory; + + private final DubboMetadataUtils dubboMetadataUtils; + + /** + * The interval in second of lookup service names(only for Dubbo-OPS). + */ + private final long servicesLookupInterval; + + private final ConfigurableApplicationContext applicationContext; + + private final String currentApplicationName; + + public DubboCloudRegistry(URL url, DiscoveryClient discoveryClient, + DubboServiceMetadataRepository repository, + DubboMetadataServiceProxy dubboMetadataConfigServiceProxy, + JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory, + ConfigurableApplicationContext applicationContext) { + + super(url); + this.servicesLookupInterval = url + .getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L); + this.discoveryClient = discoveryClient; + this.repository = repository; + this.dubboMetadataConfigServiceProxy = dubboMetadataConfigServiceProxy; + this.jsonUtils = jsonUtils; + this.dubboGenericServiceFactory = dubboGenericServiceFactory; + this.applicationContext = applicationContext; + this.dubboMetadataUtils = getBean(DubboMetadataUtils.class); + this.currentApplicationName = dubboMetadataUtils.getCurrentApplicationName(); + } + + private T getBean(Class beanClass) { + return this.applicationContext.getBean(beanClass); + } + + protected boolean shouldRegister(URL url) { + String side = url.getParameter(SIDE_KEY); + + boolean should = PROVIDER_SIDE.equals(side); // Only register the Provider. + + if (!should) { + if (logger.isDebugEnabled()) { + logger.debug("The URL[{}] should not be registered.", url.toString()); + } + } + + return should; + } + + @Override + public final void doRegister(URL url) { + if (!shouldRegister(url)) { + return; + } + repository.exportURL(url); + } + + @Override + public final void doUnregister(URL url) { + if (!shouldRegister(url)) { + return; + } + repository.unexportURL(url); + } + + @Override + public final void doSubscribe(URL url, NotifyListener listener) { + + if (isAdminURL(url)) { + // TODO in future + if (logger.isWarnEnabled()) { + logger.warn("This feature about admin will be supported in the future."); + } + } + else if (isDubboMetadataServiceURL(url)) { // for DubboMetadataService + subscribeDubboMetadataServiceURLs(url, listener); + } + else { // for general Dubbo Services + subscribeURLs(url, listener); + } + } + + private void subscribeURLs(URL url, NotifyListener listener) { + + // Sync subscription + subscribeURLs(url, getServices(url), listener); + + // Async subscription + registerServiceInstancesChangedListener(url, event -> { + + Set serviceNames = getServices(url); + + String serviceName = event.getServiceName(); + + if (serviceNames.contains(serviceName)) { + subscribeURLs(url, serviceNames, listener); + } + }); + } + + private void subscribeURLs(URL url, Set serviceNames, + NotifyListener listener) { + + List subscribedURLs = new LinkedList<>(); + + serviceNames.forEach(serviceName -> { + + subscribeURLs(url, subscribedURLs, serviceName, + () -> getServiceInstances(serviceName)); + + }); + + // Notify all + notifyAllSubscribedURLs(url, subscribedURLs, listener); + } + + private void registerServiceInstancesChangedListener(URL url, + ApplicationListener listener) { + String listenerId = generateId(url); + if (registerListeners.add(listenerId)) { + applicationContext.addApplicationListener(listener); + } + } + + private void subscribeURLs(URL subscribedURL, List subscribedURLs, + String serviceName, + Supplier> serviceInstancesSupplier) { + List serviceInstances = serviceInstancesSupplier.get(); + subscribeURLs(subscribedURL, subscribedURLs, serviceName, serviceInstances); + } + + private void subscribeURLs(URL subscribedURL, List subscribedURLs, + String serviceName, List serviceInstances) { + + if (CollectionUtils.isEmpty(serviceInstances)) { + if (logger.isWarnEnabled()) { + logger.warn(format("There is no instance in service[name : %s]", + serviceName)); + } + } + + List exportedURLs = getExportedURLs(subscribedURL, serviceName, + serviceInstances); + + /** + * Add the exported URLs from {@link MetadataService} + */ + subscribedURLs.addAll(exportedURLs); + } + + private List getExportedURLs(URL subscribedURL, String serviceName, + List serviceInstances) { + + List validServiceInstances = filter(serviceInstances); + + // If there is no valid ServiceInstance, return empty result + if (isEmpty(validServiceInstances)) { + if (logger.isWarnEnabled()) { + logger.warn( + "There is no instance from service[name : {}], and then Dubbo Service[key : {}] will not be " + + "available , please make sure the further impact", + serviceName, subscribedURL.getServiceKey()); + } + return emptyList(); + } + + List subscribedURLs = cloneExportedURLs(subscribedURL, serviceInstances); + + // clear local service instances, help GC + validServiceInstances.clear(); + + return subscribedURLs; + } + + /** + * Clone the subscribed URLs based on the template URLs. + * @param subscribedURL the URL to be subscribed + * @param serviceInstances the list of {@link ServiceInstance service instances} + * @return non-null + */ + private List cloneExportedURLs(URL subscribedURL, + List serviceInstances) { + + List clonedExportedURLs = new LinkedList<>(); + + serviceInstances.forEach(serviceInstance -> { + + String host = serviceInstance.getHost(); + + getTemplateExportedURLs(subscribedURL, serviceInstances).stream() + .map(templateURL -> templateURL.removeParameter(TIMESTAMP_KEY)) + .map(templateURL -> templateURL.removeParameter(PID_KEY)) + .map(templateURL -> { + String protocol = templateURL.getProtocol(); + int port = repository.getDubboProtocolPort(serviceInstance, + protocol); + if (Objects.equals(templateURL.getHost(), host) + && Objects.equals(templateURL.getPort(), port)) { // use + // templateURL + // if + // equals + return templateURL; + } + + URLBuilder clonedURLBuilder = from(templateURL) // remove the + // parameters from + // the template + // URL + .setHost(host) // reset the host + .setPort(port); // reset the port + + return clonedURLBuilder.build(); + }).forEach(clonedExportedURLs::add); + }); + return clonedExportedURLs; + } + + private List getTemplateExportedURLs(URL subscribedURL, + List serviceInstances) { + + DubboMetadataService dubboMetadataService = getProxy(serviceInstances); + + List templateExportedURLs = emptyList(); + + if (dubboMetadataService != null) { + templateExportedURLs = getExportedURLs(dubboMetadataService, subscribedURL); + } + else { + if (logger.isWarnEnabled()) { + logger.warn( + "The metadata of Dubbo service[key : {}] still can't be found, it could effect the further " + + "Dubbo service invocation", + subscribedURL.getServiceKey()); + } + + } + + return templateExportedURLs; + } + + private DubboMetadataService getProxy(List serviceInstances) { + return dubboMetadataConfigServiceProxy.getProxy(serviceInstances); + } + + private List filter(Collection serviceInstances) { + return serviceInstances.stream().filter(this::isDubboServiceInstance) + .collect(Collectors.toList()); + } + + private boolean isDubboServiceInstance(ServiceInstance serviceInstance) { + Map metadata = serviceInstance.getMetadata(); + return metadata.containsKey(METADATA_SERVICE_URLS_PROPERTY_NAME); + } + + private Set getServices(URL url) { + Set subscribedServices = repository.getSubscribedServices(); + // TODO Add the filter feature + return subscribedServices; + } + + private void notifyAllSubscribedURLs(URL url, List subscribedURLs, + NotifyListener listener) { + + if (isEmpty(subscribedURLs)) { + // Add the EMPTY_PROTOCOL URL + subscribedURLs.add(emptyURL(url)); + + if (isDubboMetadataServiceURL(url)) { + // if meta service change, and serviceInstances is zero, will clean up + // information about this client + String serviceName = url.getParameter(GROUP_KEY); + repository.removeMetadataAndInitializedService(serviceName, url); + } + } + + if (logger.isDebugEnabled()) { + logger.debug("The subscribed URL[{}] will notify all URLs : {}", url, + subscribedURLs); + } + + // Notify all + listener.notify(subscribedURLs); + } + + private List getServiceInstances(Iterable serviceNames) { + return stream(serviceNames.spliterator(), false).map(this::getServiceInstances) + .flatMap(Collection::stream).collect(Collectors.toList()); + } + + private List getServiceInstances(String serviceName) { + return hasText(serviceName) ? doGetServiceInstances(serviceName) : emptyList(); + } + + private List doGetServiceInstances(String serviceName) { + List serviceInstances = emptyList(); + try { + serviceInstances = discoveryClient.getInstances(serviceName); + } + catch (Exception e) { + if (logger.isErrorEnabled()) { + logger.error(e.getMessage(), e); + } + } + return serviceInstances; + } + + private String generateId(URL url) { + return url.getServiceKey(); + } + + private URL emptyURL(URL url) { + // issue : When the last service provider is closed, the client still periodically + // connects to the last provider.n + // fix https://github.com/alibaba/spring-cloud-alibaba/issues/1259 + return from(url).setProtocol(EMPTY_PROTOCOL).removeParameter(CATEGORY_KEY) + .build(); + } + + private List getExportedURLs(DubboMetadataService dubboMetadataService, + URL subscribedURL) { + String serviceInterface = subscribedURL.getServiceInterface(); + String group = subscribedURL.getParameter(GROUP_KEY); + String version = subscribedURL.getParameter(VERSION_KEY); + // The subscribed protocol may be null + String subscribedProtocol = subscribedURL.getParameter(PROTOCOL_KEY); + String exportedURLsJSON = dubboMetadataService.getExportedURLs(serviceInterface, + group, version); + return jsonUtils.toURLs(exportedURLsJSON).stream() + .filter(exportedURL -> subscribedProtocol == null + || subscribedProtocol.equalsIgnoreCase(exportedURL.getProtocol())) + .collect(Collectors.toList()); + } + + private void subscribeDubboMetadataServiceURLs(URL subscribedURL, + NotifyListener listener) { + + // Sync subscription + subscribeDubboMetadataServiceURLs(subscribedURL, listener, + getServiceName(subscribedURL)); + + // Sync subscription + if (containsProviderCategory(subscribedURL)) { + registerServiceInstancesChangedListener(subscribedURL, event -> { + + String sourceServiceName = event.getServiceName(); + String serviceName = getServiceName(subscribedURL); + + if (Objects.equals(sourceServiceName, serviceName)) { + subscribeDubboMetadataServiceURLs(subscribedURL, listener, + sourceServiceName); + } + }); + } + } + + private String getServiceName(URL subscribedURL) { + return subscribedURL.getParameter(GROUP_KEY); + } + + private void subscribeDubboMetadataServiceURLs(URL subscribedURL, + NotifyListener listener, String serviceName) { + + String serviceInterface = subscribedURL.getServiceInterface(); + String version = subscribedURL.getParameter(VERSION_KEY); + String protocol = subscribedURL.getParameter(PROTOCOL_KEY); + + List serviceInstances = getServiceInstances(serviceName); + + List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances, + serviceInterface, version, protocol); + + notifyAllSubscribedURLs(subscribedURL, urls, listener); + } + + // private void subscribeDubboMetadataServiceURLs(URL subscribedURL, + // NotifyListener listener, Set serviceNames) { + // + // String serviceInterface = subscribedURL.getServiceInterface(); + // String version = subscribedURL.getParameter(VERSION_KEY); + // String protocol = subscribedURL.getParameter(PROTOCOL_KEY); + // + // List serviceInstances = getServiceInstances(serviceNames); + // + // List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances, + // serviceInterface, version, protocol); + // + // notifyAllSubscribedURLs(subscribedURL, urls, listener); + // } + + private boolean containsProviderCategory(URL subscribedURL) { + String category = subscribedURL.getParameter(CATEGORY_KEY); + return category == null ? false : category.contains(PROVIDER); + } + + @Override + public final void doUnsubscribe(URL url, NotifyListener listener) { + // TODO + } + + @Override + public boolean isAvailable() { + return !discoveryClient.getServices().isEmpty(); + } + + protected boolean isAdminURL(URL url) { + return ADMIN_PROTOCOL.equals(url.getProtocol()); + } + + protected boolean isDubboMetadataServiceURL(URL url) { + return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface()); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistry.java index 3e4a1a5c..07afb6fc 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistry.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistry.java @@ -31,7 +31,10 @@ import org.springframework.context.ConfigurableApplicationContext; * protocol is "spring-cloud". * * @author Mercy + * @deprecated It's a legacy and not recommended implementation, being replacing to be + * {@link DubboCloudRegistry} */ +@Deprecated public class SpringCloudRegistry extends AbstractSpringCloudRegistry { private final DubboServiceMetadataRepository dubboServiceMetadataRepository; diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java index be13cb91..f8b7896d 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java @@ -16,6 +16,7 @@ package com.alibaba.cloud.dubbo.registry; +import com.alibaba.cloud.dubbo.env.DubboCloudProperties; import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory; import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy; @@ -23,11 +24,12 @@ import com.alibaba.cloud.dubbo.util.JSONUtils; import org.apache.dubbo.common.URL; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.RegistryFactory; +import org.apache.dubbo.registry.support.AbstractRegistryFactory; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.context.ConfigurableApplicationContext; -import static java.lang.System.getProperty; +import static com.alibaba.cloud.dubbo.util.DubboCloudConstants.SPRING_CLOUD_REGISTRY_PROPERTY_VALUE; /** * Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose @@ -37,7 +39,7 @@ import static java.lang.System.getProperty; * @see RegistryFactory * @see SpringCloudRegistry */ -public class SpringCloudRegistryFactory implements RegistryFactory { +public class SpringCloudRegistryFactory extends AbstractRegistryFactory { /** * Spring Cloud Protocol. @@ -49,10 +51,6 @@ public class SpringCloudRegistryFactory implements RegistryFactory { */ public static String ADDRESS = "localhost"; - private static String SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX = getProperty( - "dubbo.services.lookup.scheduler.thread.name.prefix ", - "dubbo-services-lookup-"); - private static ConfigurableApplicationContext applicationContext; private DiscoveryClient discoveryClient; @@ -65,8 +63,6 @@ public class SpringCloudRegistryFactory implements RegistryFactory { private DubboGenericServiceFactory dubboGenericServiceFactory; - private volatile boolean initialized = false; - public SpringCloudRegistryFactory() { } @@ -76,9 +72,6 @@ public class SpringCloudRegistryFactory implements RegistryFactory { } protected void init() { - if (initialized || applicationContext == null) { - return; - } this.discoveryClient = applicationContext.getBean(DiscoveryClient.class); this.dubboServiceMetadataRepository = applicationContext .getBean(DubboServiceMetadataRepository.class); @@ -90,11 +83,28 @@ public class SpringCloudRegistryFactory implements RegistryFactory { } @Override - public Registry getRegistry(URL url) { + public Registry createRegistry(URL url) { init(); - return new SpringCloudRegistry(url, discoveryClient, - dubboServiceMetadataRepository, dubboMetadataConfigServiceProxy, - jsonUtils, dubboGenericServiceFactory, applicationContext); + + DubboCloudProperties dubboCloudProperties = applicationContext + .getBean(DubboCloudProperties.class); + + Registry registry = null; + + switch (dubboCloudProperties.getRegistryType()) { + case SPRING_CLOUD_REGISTRY_PROPERTY_VALUE: + registry = new SpringCloudRegistry(url, discoveryClient, + dubboServiceMetadataRepository, dubboMetadataConfigServiceProxy, + jsonUtils, dubboGenericServiceFactory, applicationContext); + break; + default: + registry = new DubboCloudRegistry(url, discoveryClient, + dubboServiceMetadataRepository, dubboMetadataConfigServiceProxy, + jsonUtils, dubboGenericServiceFactory, applicationContext); + break; + } + + return registry; } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancesChangedEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancesChangedEvent.java index f69954b3..0f778f82 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancesChangedEvent.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancesChangedEvent.java @@ -16,14 +16,14 @@ package com.alibaba.cloud.dubbo.registry.event; -import java.util.Collection; +import java.util.List; import org.springframework.cloud.client.ServiceInstance; import org.springframework.context.ApplicationEvent; import org.springframework.context.event.ApplicationEventMulticaster; import org.springframework.context.event.SimpleApplicationEventMulticaster; -import static java.util.Collections.unmodifiableCollection; +import static java.util.Collections.unmodifiableList; /** * An event raised after the {@link ServiceInstance instances} of one service has been @@ -35,7 +35,7 @@ public class ServiceInstancesChangedEvent extends ApplicationEvent { private final String serviceName; - private final Collection serviceInstances; + private final List serviceInstances; /** * Current event has been processed or not. Typically, Spring Event was based on sync @@ -51,10 +51,10 @@ public class ServiceInstancesChangedEvent extends ApplicationEvent { * @throws IllegalArgumentException if source is null. */ public ServiceInstancesChangedEvent(String serviceName, - Collection serviceInstances) { + List serviceInstances) { super(serviceName); this.serviceName = serviceName; - this.serviceInstances = unmodifiableCollection(serviceInstances); + this.serviceInstances = unmodifiableList(serviceInstances); } /** @@ -67,7 +67,7 @@ public class ServiceInstancesChangedEvent extends ApplicationEvent { /** * @return all {@link ServiceInstance service instances}. */ - public Collection getServiceInstances() { + public List getServiceInstances() { return serviceInstances; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboGenericServiceFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboGenericServiceFactory.java index 9ddee6b3..89b99491 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboGenericServiceFactory.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboGenericServiceFactory.java @@ -95,10 +95,9 @@ public class DubboGenericServiceFactory { private ReferenceBean build(String interfaceName, String version, String group, Map dubboTranslatedAttributes) { - Integer key = Objects.hash(interfaceName, version, group, - dubboTranslatedAttributes); + String key = createKey(interfaceName, version, group, dubboTranslatedAttributes); - return cache.computeIfAbsent(group + key, k -> { + return cache.computeIfAbsent(key, k -> { ReferenceBean referenceBean = new ReferenceBean<>(); referenceBean.setGeneric(true); referenceBean.setInterface(interfaceName); @@ -110,6 +109,12 @@ public class DubboGenericServiceFactory { }); } + private String createKey(String interfaceName, String version, String group, + Map dubboTranslatedAttributes) { + return group + "#" + + Objects.hash(interfaceName, version, group, dubboTranslatedAttributes); + } + private void bindReferenceBean(ReferenceBean referenceBean, Map dubboTranslatedAttributes) { DataBinder dataBinder = new DataBinder(referenceBean); @@ -122,12 +127,11 @@ public class DubboGenericServiceFactory { new PropertyEditorSupport() { @Override - public void setAsText(String text) - throws java.lang.IllegalArgumentException { + public void setAsText(String text) throws IllegalArgumentException { // Trim all whitespace String content = StringUtils.trimAllWhitespace(text); if (!StringUtils.hasText(content)) { // No content , ignore - // directly + // directly return; } // replace "=" to "," @@ -155,7 +159,7 @@ public class DubboGenericServiceFactory { cache.clear(); } - public synchronized void destroy(String serviceName) { + public void destroy(String serviceName) { Set removeGroups = new HashSet<>(cache.keySet()); for (String key : removeGroups) { if (key.contains(serviceName)) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboMetadataServiceProxy.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboMetadataServiceProxy.java index 359ee5e0..ff70950d 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboMetadataServiceProxy.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/DubboMetadataServiceProxy.java @@ -16,13 +16,25 @@ package com.alibaba.cloud.dubbo.service; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import com.alibaba.cloud.dubbo.metadata.repository.ServiceInstanceSelector; +import com.alibaba.cloud.dubbo.util.DubboMetadataUtils; +import org.apache.dubbo.common.URL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.DisposableBean; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; import static java.lang.reflect.Proxy.newProxyInstance; +import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; /** * The proxy of {@link DubboMetadataService}. @@ -31,26 +43,29 @@ import static java.lang.reflect.Proxy.newProxyInstance; */ public class DubboMetadataServiceProxy implements BeanClassLoaderAware, DisposableBean { + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final DubboGenericServiceFactory dubboGenericServiceFactory; + private final DubboMetadataUtils dubboMetadataUtils; + + private final ServiceInstanceSelector serviceInstanceSelector; + + private final DiscoveryClient discoveryClient; + private final Map dubboMetadataServiceCache = new ConcurrentHashMap<>(); private ClassLoader classLoader; public DubboMetadataServiceProxy( - DubboGenericServiceFactory dubboGenericServiceFactory) { + DubboGenericServiceFactory dubboGenericServiceFactory, + DubboMetadataUtils dubboMetadataUtils, + ServiceInstanceSelector serviceInstanceSelector, + DiscoveryClient discoveryClient) { this.dubboGenericServiceFactory = dubboGenericServiceFactory; - } - - /** - * Initializes {@link DubboMetadataService}'s Proxy. - * @param serviceName the service name - * @param version the service version - * @return a {@link DubboMetadataService} proxy - */ - public DubboMetadataService initProxy(String serviceName, String version) { - return dubboMetadataServiceCache.computeIfAbsent(serviceName, - name -> newProxy(name, version)); + this.dubboMetadataUtils = dubboMetadataUtils; + this.serviceInstanceSelector = serviceInstanceSelector; + this.discoveryClient = discoveryClient; } /** @@ -59,6 +74,79 @@ public class DubboMetadataServiceProxy implements BeanClassLoaderAware, Disposab */ public void removeProxy(String serviceName) { dubboMetadataServiceCache.remove(serviceName); + dubboGenericServiceFactory.destroy(serviceName); + } + + /** + * Get the proxy of {@link DubboMetadataService} if possible. + * @param serviceInstances the instances of {@link DubboMetadataService} + * @return null if initialization can't be done + */ + public DubboMetadataService getProxy(List serviceInstances) { + + DubboMetadataService dubboMetadataService = null; + + // attempt to get the proxy of DubboMetadataService in maximum times + int attempts = serviceInstances.size(); + + for (int i = 0; i < attempts; i++) { + Optional serviceInstance = select(serviceInstances); + + if (serviceInstance.isPresent()) { + + List dubboMetadataServiceURLs = getDubboMetadataServiceURLs( + serviceInstance.get()); + + for (URL dubboMetadataServiceURL : dubboMetadataServiceURLs) { + dubboMetadataService = createProxyIfAbsent(dubboMetadataServiceURL); + if (dubboMetadataService != null) { + return dubboMetadataService; + } + } + } + } + + return dubboMetadataService; + } + + /** + * Is the {@link DubboMetadataService}'s Proxy initialized or not. + * @param serviceName the service name + * @return true if initialized , or return false + */ + public boolean isInitialized(String serviceName) { + return dubboMetadataServiceCache.containsKey(serviceName); + } + + /** + * Create a {@link DubboMetadataService}'s Proxy If abstract. + * @param dubboMetadataServiceURL the {@link URL} of {@link DubboMetadataService} + * @return a {@link DubboMetadataService} proxy + */ + private DubboMetadataService createProxyIfAbsent(URL dubboMetadataServiceURL) { + String serviceName = dubboMetadataServiceURL.getParameter(APPLICATION_KEY); + String version = dubboMetadataServiceURL.getParameter(VERSION_KEY); + // Initialize DubboMetadataService with right version + return createProxyIfAbsent(serviceName, version); + } + + /** + * Initializes {@link DubboMetadataService}'s Proxy. + * @param serviceName the service name + * @param version the service version + * @return a {@link DubboMetadataService} proxy + */ + private DubboMetadataService createProxyIfAbsent(String serviceName, String version) { + return dubboMetadataServiceCache.computeIfAbsent(serviceName, + name -> createProxy(name, version)); + } + + private Optional select(List serviceInstances) { + return serviceInstanceSelector.select(serviceInstances); + } + + private List getDubboMetadataServiceURLs(ServiceInstance serviceInstance) { + return dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstance); } /** @@ -68,7 +156,12 @@ public class DubboMetadataServiceProxy implements BeanClassLoaderAware, Disposab * @return a {@link DubboMetadataService} proxy */ public DubboMetadataService getProxy(String serviceName) { - return dubboMetadataServiceCache.get(serviceName); + return dubboMetadataServiceCache.getOrDefault(serviceName, + getProxy0(serviceName)); + } + + private DubboMetadataService getProxy0(String serviceName) { + return getProxy(discoveryClient.getInstances(serviceName)); } @Override @@ -88,7 +181,14 @@ public class DubboMetadataServiceProxy implements BeanClassLoaderAware, Disposab * @param version the service version * @return a {@link DubboMetadataService} proxy */ - protected DubboMetadataService newProxy(String serviceName, String version) { + protected DubboMetadataService createProxy(String serviceName, String version) { + + if (logger.isInfoEnabled()) { + logger.info( + "The metadata of Dubbo service[name : {}] is about to be initialized", + serviceName); + } + return (DubboMetadataService) newProxyInstance(classLoader, new Class[] { DubboMetadataService.class }, new DubboMetadataServiceInvocationHandler(serviceName, version, diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/util/DubboCloudConstants.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/util/DubboCloudConstants.java new file mode 100644 index 00000000..34641697 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/util/DubboCloudConstants.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.dubbo.util; + +/** + * The constants for Dubbo Spring Cloud. + * + * @author Mercy + */ +public final class DubboCloudConstants { + + /** + * The property prefix of Configuration. + */ + public static final String CONFIG_PROPERTY_PREFIX = "dubbo.cloud"; + + /** + * The property name of Registry type. + */ + public static final String REGISTRY_TYPE_PROPERTY_NAME = CONFIG_PROPERTY_PREFIX + + ".registry-type"; + + /** + * The property value of Spring Cloud Registry. + */ + public static final String SPRING_CLOUD_REGISTRY_PROPERTY_VALUE = "spring-cloud"; + + /** + * The property value of Dubbo Cloud Registry. + */ + public static final String DUBBO_CLOUD_REGISTRY_PROPERTY_VALUE = "dubbo-cloud"; + + private DubboCloudConstants() { + throw new AssertionError("Must not instantiate constant utility class"); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/util/DubboMetadataUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/util/DubboMetadataUtils.java new file mode 100644 index 00000000..af3c5946 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/util/DubboMetadataUtils.java @@ -0,0 +1,118 @@ +/* + * Copyright 2013-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 + * + * https://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 com.alibaba.cloud.dubbo.util; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import com.alibaba.cloud.dubbo.service.DubboMetadataService; +import org.apache.dubbo.common.URL; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.env.Environment; + +import static java.lang.String.format; +import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME; +import static org.springframework.util.StringUtils.hasText; + +/** + * The utilities class of Dubbo Metadata. + * + * @author Mercy + */ +public class DubboMetadataUtils { + + /** + * The {@link String#format(String, Object...) pattern} of dubbo protocols port. + */ + public static final String DUBBO_PROTOCOLS_PORT_PROPERTY_NAME_PATTERN = "dubbo.protocols.%s.port"; + + private final JSONUtils jsonUtils; + + private final Environment environment; + + private final String currentApplicationName; + + public DubboMetadataUtils(JSONUtils jsonUtils, Environment environment) { + this.jsonUtils = jsonUtils; + this.environment = environment; + this.currentApplicationName = environment.getProperty("spring.application.name", + environment.getProperty("dubbo.application.name", "application")); + } + + /** + * Get the current application name. + * @return non-null + */ + public String getCurrentApplicationName() { + return currentApplicationName; + } + + /** + * Get the {@link URL urls} that {@link DubboMetadataService} exported by the + * specified {@link ServiceInstance}. + * @param serviceInstance {@link ServiceInstance} + * @return the mutable {@link URL urls} + */ + public List getDubboMetadataServiceURLs(ServiceInstance serviceInstance) { + Map metadata = serviceInstance.getMetadata(); + String dubboURLsJSON = metadata.get(METADATA_SERVICE_URLS_PROPERTY_NAME); + return jsonUtils.toURLs(dubboURLsJSON); + } + + /** + * Get the {@link URL urls} that {@link DubboMetadataService} exported by the + * specified {@link ServiceInstance ServiceInstances}. + * @param serviceInstances the list of {@link ServiceInstance ServiceInstances} + * @param serviceInterface the interface name of Dubbo service + * @param version the version of Dubbo service + * @param protocol the protocol that Dubbo Service exports + * @return the mutable {@link URL urls} + */ + public List getDubboMetadataServiceURLs(List serviceInstances, + String serviceInterface, String version, String protocol) { + return serviceInstances.stream().map(this::getDubboMetadataServiceURLs) + .flatMap(List::stream) + .filter(url -> protocol == null + || Objects.equals(protocol, url.getProtocol())) + .filter(url -> Objects.equals(serviceInterface, + url.getServiceInterface())) + .filter(url -> Objects.equals(version, url.getParameter(VERSION_KEY))) + .collect(Collectors.toList()); + } + + /** + * Get the property name of Dubbo Protocol. + * @param protocol Dubbo Protocol + * @return non-null + */ + public String getDubboProtocolPropertyName(String protocol) { + return format(DUBBO_PROTOCOLS_PORT_PROPERTY_NAME_PATTERN, protocol); + } + + public Integer getDubboProtocolPort(ServiceInstance serviceInstance, + String protocol) { + String protocolProperty = getDubboProtocolPropertyName(protocol); + Map metadata = serviceInstance.getMetadata(); + String protocolPort = metadata.get(protocolProperty); + return hasText(protocolPort) ? Integer.valueOf(protocolPort) : null; + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/default/actuator-endpoints.properties b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/default/actuator-endpoints.properties index 19c4bb44..04d894e7 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/default/actuator-endpoints.properties +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/default/actuator-endpoints.properties @@ -1,7 +1,6 @@ # Dubbo Endpoints Default Properties is loaded by @PropertySource with low order, # Set enabled for Dubbo Endpoints -management.endpoint.dubborestmetadata.enabled = true - +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 +management.endpoints.web.path-mapping.dubborestmetadata=dubbo/rest/metadata diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/spring.factories index 5969971e..06c5b592 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/spring.factories @@ -6,12 +6,9 @@ com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationNonWebApplicationA com.alibaba.cloud.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\ com.alibaba.cloud.dubbo.autoconfigure.DubboServiceAutoConfiguration,\ com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration - org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\ com.alibaba.cloud.dubbo.actuate.DubboMetadataEndpointAutoConfiguration - org.springframework.context.ApplicationContextInitializer=\ com.alibaba.cloud.dubbo.context.DubboServiceRegistrationApplicationContextInitializer - org.springframework.boot.env.EnvironmentPostProcessor=\ com.alibaba.cloud.dubbo.env.DubboNonWebApplicationEnvironmentPostProcessor \ No newline at end of file diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/test/resources/bootstrap.yaml b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/test/resources/bootstrap.yaml index 75e9751b..9b1aad42 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/test/resources/bootstrap.yaml +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/test/resources/bootstrap.yaml @@ -3,8 +3,6 @@ spring: name: spring-cloud-alibaba-dubbo cloud: nacos: - username: nacos - password: nacos discovery: server-addr: 127.0.0.1:8848 config: