mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Merge pull request #1759 from mercyblitz/finchley
[CodeBase] 2.0.3.RELEASE
This commit is contained in:
commit
9fc6a1d256
1
.gitignore
vendored
1
.gitignore
vendored
@ -31,4 +31,5 @@ hs_err_pid*
|
||||
.settings
|
||||
target
|
||||
.DS_Store
|
||||
.flattened-pom.xml
|
||||
|
||||
|
2
pom.xml
2
pom.xml
@ -80,7 +80,7 @@
|
||||
|
||||
<properties>
|
||||
<!-- Project revision -->
|
||||
<revision>2.0.2.RELEASE</revision>
|
||||
<revision>2.0.3.RELEASE</revision>
|
||||
|
||||
<!-- Dependency Versions -->
|
||||
<spring-cloud-commons.version>2.0.4.RELEASE</spring-cloud-commons.version>
|
||||
|
@ -18,12 +18,13 @@
|
||||
<description>Spring Cloud Alibaba Dependencies</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.0.2.RELEASE</revision>
|
||||
<sentinel.version>1.7.1</sentinel.version>
|
||||
<seata.version>1.1.0</seata.version>
|
||||
<nacos.client.version>1.2.1</nacos.client.version>
|
||||
<revision>2.0.3.RELEASE</revision>
|
||||
|
||||
<sentinel.version>1.8.0</sentinel.version>
|
||||
<seata.version>1.3.0</seata.version>
|
||||
<nacos.client.version>1.3.3</nacos.client.version>
|
||||
<nacos.config.version>0.8.0</nacos.config.version>
|
||||
<spring.context.support.version>1.0.6</spring.context.support.version>
|
||||
<spring.context.support.version>1.0.10</spring.context.support.version>
|
||||
|
||||
<!-- Maven Plugin Versions -->
|
||||
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
|
||||
|
@ -10,7 +10,7 @@ Spring Cloud Alibaba BOM 包含了它所使用的所有依赖的版本。
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>2.0.2.RELEASE</version>
|
||||
<version>2.0.3.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
@ -8,7 +8,7 @@ If you’re a Maven Central user, add our BOM to your pom.xml <dependencyManagem
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>2.0.2.RELEASE</version>
|
||||
<version>2.0.3.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ public class NacosDataSourceFactoryBean implements FactoryBean<NacosDataSource>
|
||||
|
||||
private String serverAddr;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String groupId;
|
||||
|
||||
private String dataId;
|
||||
@ -63,6 +67,12 @@ public class NacosDataSourceFactoryBean implements FactoryBean<NacosDataSource>
|
||||
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<NacosDataSource>
|
||||
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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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<Config> 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(),
|
||||
|
@ -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;
|
||||
|
@ -34,9 +34,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
* @author <a href="mailto:lyuzb@lyuzb.com">lyuzb</a>
|
||||
*/
|
||||
@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 {
|
||||
|
@ -34,10 +34,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
* @author <a href="mailto:lyuzb@lyuzb.com">lyuzb</a>
|
||||
*/
|
||||
@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
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
||||
}
|
||||
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @author <a href="mailto:lyuzb@lyuzb.com">lyuzb</a>
|
||||
* @author <a href="mailto:78552423@qq.com">eshun</a>
|
||||
*/
|
||||
|
||||
@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, ""));
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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<String, String> metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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> taskScheduler) {
|
||||
return new NacosWatch(nacosDiscoveryProperties, taskScheduler);
|
||||
@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", matchIfMissing = true)
|
||||
public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager,
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties,
|
||||
ObjectProvider<TaskScheduler> taskExecutorObjectProvider) {
|
||||
return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties,
|
||||
taskExecutorObjectProvider);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<ServiceInstance> getInstances(String serviceId) throws NacosException {
|
||||
String group = discoveryProperties.getGroup();
|
||||
List<Instance> 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<String> getServices() throws NacosException {
|
||||
String group = discoveryProperties.getGroup();
|
||||
ListView<String> services = discoveryProperties.namingServiceInstance()
|
||||
.getServicesOfServer(1, Integer.MAX_VALUE, group);
|
||||
return services.getData();
|
||||
this.nacosServiceManager = nacosServiceManager;
|
||||
}
|
||||
|
||||
public static List<ServiceInstance> 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<ServiceInstance> getInstances(String serviceId) throws NacosException {
|
||||
String group = discoveryProperties.getGroup();
|
||||
List<Instance> 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<String> getServices() throws NacosException {
|
||||
String group = discoveryProperties.getGroup();
|
||||
ListView<String> services = namingService().getServicesOfServer(1,
|
||||
Integer.MAX_VALUE, group);
|
||||
return services.getData();
|
||||
}
|
||||
|
||||
private NamingService namingService() {
|
||||
return nacosServiceManager
|
||||
.getNamingService(discoveryProperties.getNacosProperties());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<String, EventListener> 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> 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<Instance> instances = ((NamingEvent) event)
|
||||
.getInstances();
|
||||
Optional<Instance> 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<Instance> selectCurrentInstance(List<Instance> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
* The {@link HealthIndicator} for Nacos Discovery.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 2.2.0
|
||||
* @see HealthIndicator
|
||||
*/
|
||||
public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator {
|
||||
|
@ -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 {
|
||||
|
||||
}
|
||||
|
@ -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<String, Object> result = new HashMap<>();
|
||||
result.put("NacosDiscoveryProperties", nacosDiscoveryProperties);
|
||||
|
||||
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
|
||||
NamingService namingService = nacosServiceManager
|
||||
.getNamingService(nacosDiscoveryProperties.getNacosProperties());
|
||||
List<ServiceInfo> subscribe = Collections.emptyList();
|
||||
|
||||
try {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<NacosRegistrationCustomizer> registrationCustomizers;
|
||||
|
||||
private NacosDiscoveryProperties nacosDiscoveryProperties;
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
public NacosRegistration(NacosDiscoveryProperties nacosDiscoveryProperties,
|
||||
public NacosRegistration(List<NacosRegistrationCustomizer> registrationCustomizers,
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties,
|
||||
ApplicationContext context) {
|
||||
this.registrationCustomizers = registrationCustomizers;
|
||||
this.nacosDiscoveryProperties = nacosDiscoveryProperties;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private static void customize(
|
||||
List<NacosRegistrationCustomizer> 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="
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @author <a href="mailto:78552423@qq.com">eshun</a>
|
||||
*/
|
||||
public class NacosServiceRegistry implements ServiceRegistry<Registration> {
|
||||
|
||||
@ -40,11 +45,11 @@ public class NacosServiceRegistry implements ServiceRegistry<Registration> {
|
||||
|
||||
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<Registration> {
|
||||
return;
|
||||
}
|
||||
|
||||
NamingService namingService = namingService();
|
||||
String serviceId = registration.getServiceId();
|
||||
String group = nacosDiscoveryProperties.getGroup();
|
||||
|
||||
@ -84,7 +90,7 @@ public class NacosServiceRegistry implements ServiceRegistry<Registration> {
|
||||
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<Registration> {
|
||||
|
||||
@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<Registration> {
|
||||
}
|
||||
|
||||
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<Registration> {
|
||||
|
||||
String serviceName = registration.getServiceId();
|
||||
try {
|
||||
List<Instance> instances = nacosDiscoveryProperties.namingServiceInstance()
|
||||
.getAllInstances(serviceName);
|
||||
List<Instance> 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<Registration> {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<List<NacosRegistrationCustomizer>> registrationCustomizers,
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties,
|
||||
ApplicationContext context) {
|
||||
return new NacosRegistration(nacosDiscoveryProperties, context);
|
||||
return new NacosRegistration(registrationCustomizers.getIfAvailable(),
|
||||
nacosDiscoveryProperties, context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -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<Instance> instances = namingService.selectInstances(name, true);
|
||||
NamingService namingService = nacosServiceManager
|
||||
.getNamingService(nacosDiscoveryProperties.getNacosProperties());
|
||||
List<Instance> instances = namingService.selectInstances(name, group, true);
|
||||
if (CollectionUtils.isEmpty(instances)) {
|
||||
LOGGER.warn("no instance in service {}", name);
|
||||
return null;
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -36,11 +36,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
||||
* @author <a href="mailto:lyuzb@lyuzb.com">lyuzb</a>
|
||||
*/
|
||||
@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
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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<ServiceInstance> 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<String> services = serviceDiscovery.getServices();
|
||||
|
||||
|
@ -328,4 +328,9 @@ public class MockNamingService implements NamingService {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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<String, Object> map = nacosDiscoveryEndpoint.nacosDiscovery();
|
||||
|
||||
assertThat(properties).isEqualTo(map.get("NacosDiscoveryProperties"));
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -46,6 +46,7 @@ public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy
|
||||
|
||||
private final Logger logger = LoggerFactory
|
||||
.getLogger(SeataHystrixConcurrencyStrategy.class);
|
||||
|
||||
private HystrixConcurrencyStrategy delegate;
|
||||
|
||||
public SeataHystrixConcurrencyStrategy() {
|
||||
|
@ -35,17 +35,16 @@ import org.springframework.web.client.RestTemplate;
|
||||
@Configuration
|
||||
public class SeataRestTemplateAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private Collection<RestTemplate> restTemplates;
|
||||
@Autowired
|
||||
private SeataRestTemplateInterceptor seataRestTemplateInterceptor;
|
||||
|
||||
@Bean
|
||||
public SeataRestTemplateInterceptor seataRestTemplateInterceptor() {
|
||||
return new SeataRestTemplateInterceptor();
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
private Collection<RestTemplate> restTemplates;
|
||||
|
||||
@Autowired
|
||||
private SeataRestTemplateInterceptor seataRestTemplateInterceptor;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (this.restTemplates != null) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -27,16 +27,14 @@ import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
*/
|
||||
final class BlockClassRegistry {
|
||||
|
||||
private static final Map<String, Method> FALLBACK_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Method> BLOCK_HANDLER_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Method> URL_CLEANER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private BlockClassRegistry() {
|
||||
|
||||
}
|
||||
|
||||
private static final Map<String, Method> FALLBACK_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Map<String, Method> BLOCK_HANDLER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Map<String, Method> URL_CLEANER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
static Method lookupFallback(Class<?> clazz, String name) {
|
||||
return FALLBACK_MAP.get(getKey(clazz, name));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -56,13 +56,12 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
||||
.getLogger(SentinelBeanPostProcessor.class);
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
private ConcurrentHashMap<String, SentinelRestTemplate> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public SentinelBeanPostProcessor(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
private ConcurrentHashMap<String, SentinelRestTemplate> cache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
|
||||
Class<?> beanType, String beanName) {
|
||||
|
@ -52,20 +52,13 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SentinelDataSourceHandler.class);
|
||||
|
||||
private List<String> 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<String> dataTypeList = Arrays.asList("json", "xml");
|
||||
|
||||
public SentinelDataSourceHandler(DefaultListableBeanFactory beanFactory,
|
||||
SentinelProperties sentinelProperties, Environment env) {
|
||||
|
@ -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());
|
||||
|
@ -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<Tuple2<String, Integer>> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<String, MethodMetadata> METADATA_MAP = new HashMap<>();
|
||||
private final Contract delegate;
|
||||
|
||||
public SentinelContractHolder(Contract delegate) {
|
||||
this.delegate = delegate;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -65,13 +65,23 @@ public class SentinelInvocationHandler implements InvocationHandler {
|
||||
this.dispatch = checkNotNull(dispatch, "dispatch");
|
||||
}
|
||||
|
||||
static Map<Method, Method> toFallbackMethod(Map<Method, MethodHandler> dispatch) {
|
||||
Map<Method, Method> 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<Method, Method> toFallbackMethod(Map<Method, MethodHandler> dispatch) {
|
||||
Map<Method, Method> result = new LinkedHashMap<>();
|
||||
for (Method method : dispatch.keySet()) {
|
||||
method.setAccessible(true);
|
||||
result.put(method, method);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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."
|
||||
|
@ -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 <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
// */
|
||||
//@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<FooService> {
|
||||
//
|
||||
// private FooService fooService = new FooServiceFallback();
|
||||
//
|
||||
// @Override
|
||||
// public FooService create(Throwable throwable) {
|
||||
// return fooService;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
@ -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<String, Object> 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();
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@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
|
||||
|
@ -45,8 +45,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
*/
|
||||
@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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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<String, Status> dataSourceDetailMap = (Map<String, Status>) 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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<String, SidecarInstanceCache> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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<List<ConsulRegistrationCustomizer>> 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);
|
||||
}
|
||||
|
||||
}
|
@ -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<ConsulRegistrationCustomizer> 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());
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,7 @@ import org.springframework.context.annotation.PropertySource;
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
@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 {
|
||||
|
@ -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:
|
||||
* <ol>
|
||||
* <li>{@link FeignClient @FeignClient} annotated classes: If
|
||||
* {@link DubboTransported @DubboTransported} annotated classes, the invocation of all
|
||||
* <li>{@link FeignClient @FeignClient} annotated classes:
|
||||
* <ul>
|
||||
* If {@link DubboTransported @DubboTransported} annotated classes, the invocation of all
|
||||
* methods of {@link FeignClient @FeignClient} annotated classes.
|
||||
*
|
||||
* </ul>
|
||||
* <ul>
|
||||
* If {@link DubboTransported @DubboTransported} annotated methods of
|
||||
* {@link FeignClient @FeignClient} annotated classes.</li>
|
||||
* {@link FeignClient @FeignClient} annotated classes.
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>{@link LoadBalanced @LoadBalanced} {@link RestTemplate} annotated field, method and
|
||||
* parameters</li>
|
||||
* </ol>
|
||||
|
@ -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<String, Object> dubboTranslatedAttributes) {
|
||||
|
@ -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();
|
||||
|
@ -35,8 +35,8 @@ import static com.alibaba.cloud.dubbo.autoconfigure.DubboOpenFeignAutoConfigurat
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
@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 {
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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<Predicate<HeartbeatEvent>> 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<ServiceInstance> serviceInstances) {
|
||||
if (!hasText(serviceName) || serviceInstances == null) {
|
||||
List<ServiceInstance> 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<String> 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<>();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
/**
|
||||
|
@ -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 <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
|
||||
*/
|
||||
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<URL> 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<URL> 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);
|
||||
}
|
||||
|
||||
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
@ -34,10 +34,10 @@ public class HttpRequestParamsMatcher extends AbstractHttpRequestMatcher {
|
||||
|
||||
/**
|
||||
* @param params The pattern of params :
|
||||
* <ul>
|
||||
* <li>name=value</li>
|
||||
* <li>name</li>
|
||||
* </ul>
|
||||
* <ul>
|
||||
* <li>name=value</li>
|
||||
* <li>name</li>
|
||||
* </ul>
|
||||
*/
|
||||
public HttpRequestParamsMatcher(String... params) {
|
||||
this.expressions = parseExpressions(params);
|
||||
|
@ -65,7 +65,6 @@ public class DubboProtocolConfigSupplier implements Supplier<ProtocolConfig> {
|
||||
if (protocolConfig == null) {
|
||||
protocolConfig = new ProtocolConfig();
|
||||
protocolConfig.setName(DEFAULT_PROTOCOL);
|
||||
protocolConfig.setPort(-1);
|
||||
}
|
||||
|
||||
return protocolConfig;
|
||||
|
@ -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<String> 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<String, URL> 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<String, String> metadata,
|
||||
List<URL> 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<String, String> 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<URL> findSubscribedDubboMetadataServiceURLs(String serviceName,
|
||||
String group, String version, String protocol) {
|
||||
String serviceKey = URL.buildKey(serviceName, group, version);
|
||||
|
||||
List<URL> 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<URL> getDubboMetadataServiceURLs(ServiceInstance serviceInstance) {
|
||||
Map<String, String> 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<String, String> 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<URL> 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<ServiceRestMetadata> 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<ServiceInstance> optionalServiceInstance = metadataServiceInstanceSelector
|
||||
.choose(discoveryClient.getInstances(serviceName));
|
||||
if (!((Optional) optionalServiceInstance).isPresent()) {
|
||||
return false;
|
||||
}
|
||||
ServiceInstance serviceInstance = optionalServiceInstance.get();
|
||||
if (null == serviceInstance) {
|
||||
return false;
|
||||
}
|
||||
List<URL> 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;
|
||||
}
|
||||
|
||||
}
|
||||
public List<URL> 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<ServiceInstance> serviceInstances = discoveryClient.getInstances(group);
|
||||
List<URL> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class RandomServiceInstanceSelector implements ServiceInstanceSelector {
|
||||
|
||||
@Override
|
||||
public Optional<ServiceInstance> select(List<ServiceInstance> serviceInstances) {
|
||||
if (isEmpty(serviceInstances)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
return of(serviceInstances.get(random.nextInt(serviceInstances.size())));
|
||||
}
|
||||
|
||||
}
|
@ -26,13 +26,13 @@ import org.springframework.cloud.client.ServiceInstance;
|
||||
*
|
||||
* @author <a href="mailto:liuxx-u@outlook.com">liuxx</a>
|
||||
*/
|
||||
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<ServiceInstance> choose(List<ServiceInstance> serviceInstances);
|
||||
Optional<ServiceInstance> select(List<ServiceInstance> serviceInstances);
|
||||
|
||||
}
|
@ -63,6 +63,7 @@ import static org.springframework.util.StringUtils.hasText;
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
@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<URL> urls = repository.findSubscribedDubboMetadataServiceURLs(
|
||||
serviceInterface, group, version, protocol);
|
||||
List<URL> 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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user