Merge remote-tracking branch 'origin/master' into config
# Conflicts: # spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.javapull/1531/head
commit
359b3ea522
@ -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(proxyBeanMethods = false)
|
||||
@ConditionalOnDiscoveryEnabled
|
||||
@ConditionalOnNacosDiscoveryEnabled
|
||||
public class NacosServiceAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public NacosServiceManager nacosServiceManager() {
|
||||
return new NacosServiceManager();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration;
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.api.support.MethodProxy;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
/**
|
||||
* @author L.cm
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockIgnore("javax.management.*")
|
||||
@PowerMockRunnerDelegate(SpringRunner.class)
|
||||
@PrepareForTest({ NacosFactory.class })
|
||||
@SpringBootTest(classes = NacosRegistrationCustomizerTest.TestConfig.class,
|
||||
properties = { "spring.application.name=myTestService1",
|
||||
"spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848" },
|
||||
webEnvironment = RANDOM_PORT)
|
||||
public class NacosRegistrationCustomizerTest {
|
||||
|
||||
@Autowired
|
||||
private NacosAutoServiceRegistration nacosAutoServiceRegistration;
|
||||
|
||||
static {
|
||||
try {
|
||||
Method method = PowerMockito.method(NacosFactory.class, "createNamingService",
|
||||
Properties.class);
|
||||
MethodProxy.proxy(method, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
return new MockNamingService();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoads() throws Exception {
|
||||
NacosRegistration registration = nacosAutoServiceRegistration.getRegistration();
|
||||
Map<String, String> metadata = registration.getMetadata();
|
||||
Assert.assertEquals("test1", metadata.get("test1"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class,
|
||||
NacosDiscoveryClientConfiguration.class,
|
||||
NacosServiceRegistryAutoConfiguration.class })
|
||||
public static class TestConfig {
|
||||
|
||||
@Bean
|
||||
public NacosRegistrationCustomizer nacosRegistrationCustomizer() {
|
||||
return registration -> {
|
||||
Map<String, String> metadata = registration.getMetadata();
|
||||
metadata.put("test1", "test1");
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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())));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,511 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.dubbo.registry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
||||
import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
|
||||
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
|
||||
import com.alibaba.cloud.dubbo.service.DubboMetadataService;
|
||||
import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy;
|
||||
import com.alibaba.cloud.dubbo.util.DubboMetadataUtils;
|
||||
import com.alibaba.cloud.dubbo.util.JSONUtils;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.URLBuilder;
|
||||
import org.apache.dubbo.registry.NotifyListener;
|
||||
import org.apache.dubbo.registry.support.FailbackRegistry;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.stream.StreamSupport.stream;
|
||||
import static org.apache.dubbo.common.URLBuilder.from;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
|
||||
import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL;
|
||||
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
/**
|
||||
* Dubbo Cloud {@link FailbackRegistry} is based on Spring Cloud {@link DiscoveryClient}.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class DubboCloudRegistry extends FailbackRegistry {
|
||||
|
||||
/**
|
||||
* The parameter name of {@link #servicesLookupInterval}.
|
||||
*/
|
||||
public static final String SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.services.lookup.interval";
|
||||
|
||||
protected static final String DUBBO_METADATA_SERVICE_CLASS_NAME = DubboMetadataService.class
|
||||
.getName();
|
||||
|
||||
/**
|
||||
* Caches the IDs of {@link ApplicationListener}.
|
||||
*/
|
||||
private static final Set<String> registerListeners = new HashSet<>();
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final DiscoveryClient discoveryClient;
|
||||
|
||||
private final DubboServiceMetadataRepository repository;
|
||||
|
||||
private final DubboMetadataServiceProxy dubboMetadataConfigServiceProxy;
|
||||
|
||||
private final JSONUtils jsonUtils;
|
||||
|
||||
private final DubboGenericServiceFactory dubboGenericServiceFactory;
|
||||
|
||||
private final DubboMetadataUtils dubboMetadataUtils;
|
||||
|
||||
/**
|
||||
* The interval in second of lookup service names(only for Dubbo-OPS).
|
||||
*/
|
||||
private final long servicesLookupInterval;
|
||||
|
||||
private final ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private final String currentApplicationName;
|
||||
|
||||
public DubboCloudRegistry(URL url, DiscoveryClient discoveryClient,
|
||||
DubboServiceMetadataRepository repository,
|
||||
DubboMetadataServiceProxy dubboMetadataConfigServiceProxy,
|
||||
JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory,
|
||||
ConfigurableApplicationContext applicationContext) {
|
||||
|
||||
super(url);
|
||||
this.servicesLookupInterval = url
|
||||
.getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L);
|
||||
this.discoveryClient = discoveryClient;
|
||||
this.repository = repository;
|
||||
this.dubboMetadataConfigServiceProxy = dubboMetadataConfigServiceProxy;
|
||||
this.jsonUtils = jsonUtils;
|
||||
this.dubboGenericServiceFactory = dubboGenericServiceFactory;
|
||||
this.applicationContext = applicationContext;
|
||||
this.dubboMetadataUtils = getBean(DubboMetadataUtils.class);
|
||||
this.currentApplicationName = dubboMetadataUtils.getCurrentApplicationName();
|
||||
}
|
||||
|
||||
private <T> T getBean(Class<T> beanClass) {
|
||||
return this.applicationContext.getBean(beanClass);
|
||||
}
|
||||
|
||||
protected boolean shouldRegister(URL url) {
|
||||
String side = url.getParameter(SIDE_KEY);
|
||||
|
||||
boolean should = PROVIDER_SIDE.equals(side); // Only register the Provider.
|
||||
|
||||
if (!should) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The URL[{}] should not be registered.", url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return should;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void doRegister(URL url) {
|
||||
if (!shouldRegister(url)) {
|
||||
return;
|
||||
}
|
||||
repository.exportURL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void doUnregister(URL url) {
|
||||
if (!shouldRegister(url)) {
|
||||
return;
|
||||
}
|
||||
repository.unexportURL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void doSubscribe(URL url, NotifyListener listener) {
|
||||
|
||||
if (isAdminURL(url)) {
|
||||
// TODO in future
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("This feature about admin will be supported in the future.");
|
||||
}
|
||||
}
|
||||
else if (isDubboMetadataServiceURL(url)) { // for DubboMetadataService
|
||||
subscribeDubboMetadataServiceURLs(url, listener);
|
||||
}
|
||||
else { // for general Dubbo Services
|
||||
subscribeURLs(url, listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void subscribeURLs(URL url, NotifyListener listener) {
|
||||
|
||||
// Sync subscription
|
||||
subscribeURLs(url, getServices(url), listener);
|
||||
|
||||
// Async subscription
|
||||
registerServiceInstancesChangedListener(url, event -> {
|
||||
|
||||
Set<String> serviceNames = getServices(url);
|
||||
|
||||
String serviceName = event.getServiceName();
|
||||
|
||||
if (serviceNames.contains(serviceName)) {
|
||||
subscribeURLs(url, serviceNames, listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void subscribeURLs(URL url, Set<String> serviceNames,
|
||||
NotifyListener listener) {
|
||||
|
||||
List<URL> subscribedURLs = new LinkedList<>();
|
||||
|
||||
serviceNames.forEach(serviceName -> {
|
||||
|
||||
subscribeURLs(url, subscribedURLs, serviceName,
|
||||
() -> getServiceInstances(serviceName));
|
||||
|
||||
});
|
||||
|
||||
// Notify all
|
||||
notifyAllSubscribedURLs(url, subscribedURLs, listener);
|
||||
}
|
||||
|
||||
private void registerServiceInstancesChangedListener(URL url,
|
||||
ApplicationListener<ServiceInstancesChangedEvent> listener) {
|
||||
String listenerId = generateId(url);
|
||||
if (registerListeners.add(listenerId)) {
|
||||
applicationContext.addApplicationListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void subscribeURLs(URL subscribedURL, List<URL> subscribedURLs,
|
||||
String serviceName,
|
||||
Supplier<List<ServiceInstance>> serviceInstancesSupplier) {
|
||||
List<ServiceInstance> serviceInstances = serviceInstancesSupplier.get();
|
||||
subscribeURLs(subscribedURL, subscribedURLs, serviceName, serviceInstances);
|
||||
}
|
||||
|
||||
private void subscribeURLs(URL subscribedURL, List<URL> subscribedURLs,
|
||||
String serviceName, List<ServiceInstance> serviceInstances) {
|
||||
|
||||
if (CollectionUtils.isEmpty(serviceInstances)) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(format("There is no instance in service[name : %s]",
|
||||
serviceName));
|
||||
}
|
||||
}
|
||||
|
||||
List<URL> exportedURLs = getExportedURLs(subscribedURL, serviceName,
|
||||
serviceInstances);
|
||||
|
||||
/**
|
||||
* Add the exported URLs from {@link MetadataService}
|
||||
*/
|
||||
subscribedURLs.addAll(exportedURLs);
|
||||
}
|
||||
|
||||
private List<URL> getExportedURLs(URL subscribedURL, String serviceName,
|
||||
List<ServiceInstance> serviceInstances) {
|
||||
|
||||
List<ServiceInstance> validServiceInstances = filter(serviceInstances);
|
||||
|
||||
// If there is no valid ServiceInstance, return empty result
|
||||
if (isEmpty(validServiceInstances)) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"There is no instance from service[name : {}], and then Dubbo Service[key : {}] will not be "
|
||||
+ "available , please make sure the further impact",
|
||||
serviceName, subscribedURL.getServiceKey());
|
||||
}
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
List<URL> subscribedURLs = cloneExportedURLs(subscribedURL, serviceInstances);
|
||||
|
||||
// clear local service instances, help GC
|
||||
validServiceInstances.clear();
|
||||
|
||||
return subscribedURLs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the subscribed URLs based on the template URLs.
|
||||
* @param subscribedURL the URL to be subscribed
|
||||
* @param serviceInstances the list of {@link ServiceInstance service instances}
|
||||
* @return non-null
|
||||
*/
|
||||
private List<URL> cloneExportedURLs(URL subscribedURL,
|
||||
List<ServiceInstance> serviceInstances) {
|
||||
|
||||
List<URL> clonedExportedURLs = new LinkedList<>();
|
||||
|
||||
serviceInstances.forEach(serviceInstance -> {
|
||||
|
||||
String host = serviceInstance.getHost();
|
||||
|
||||
getTemplateExportedURLs(subscribedURL, serviceInstances).stream()
|
||||
.map(templateURL -> templateURL.removeParameter(TIMESTAMP_KEY))
|
||||
.map(templateURL -> templateURL.removeParameter(PID_KEY))
|
||||
.map(templateURL -> {
|
||||
String protocol = templateURL.getProtocol();
|
||||
int port = repository.getDubboProtocolPort(serviceInstance,
|
||||
protocol);
|
||||
if (Objects.equals(templateURL.getHost(), host)
|
||||
&& Objects.equals(templateURL.getPort(), port)) { // use
|
||||
// templateURL
|
||||
// if
|
||||
// equals
|
||||
return templateURL;
|
||||
}
|
||||
|
||||
URLBuilder clonedURLBuilder = from(templateURL) // remove the
|
||||
// parameters from
|
||||
// the template
|
||||
// URL
|
||||
.setHost(host) // reset the host
|
||||
.setPort(port); // reset the port
|
||||
|
||||
return clonedURLBuilder.build();
|
||||
}).forEach(clonedExportedURLs::add);
|
||||
});
|
||||
return clonedExportedURLs;
|
||||
}
|
||||
|
||||
private List<URL> getTemplateExportedURLs(URL subscribedURL,
|
||||
List<ServiceInstance> serviceInstances) {
|
||||
|
||||
DubboMetadataService dubboMetadataService = getProxy(serviceInstances);
|
||||
|
||||
List<URL> templateExportedURLs = emptyList();
|
||||
|
||||
if (dubboMetadataService != null) {
|
||||
templateExportedURLs = getExportedURLs(dubboMetadataService, subscribedURL);
|
||||
}
|
||||
else {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"The metadata of Dubbo service[key : {}] still can't be found, it could effect the further "
|
||||
+ "Dubbo service invocation",
|
||||
subscribedURL.getServiceKey());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return templateExportedURLs;
|
||||
}
|
||||
|
||||
private DubboMetadataService getProxy(List<ServiceInstance> serviceInstances) {
|
||||
return dubboMetadataConfigServiceProxy.getProxy(serviceInstances);
|
||||
}
|
||||
|
||||
private List<ServiceInstance> filter(Collection<ServiceInstance> serviceInstances) {
|
||||
return serviceInstances.stream().filter(this::isDubboServiceInstance)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean isDubboServiceInstance(ServiceInstance serviceInstance) {
|
||||
Map<String, String> metadata = serviceInstance.getMetadata();
|
||||
return metadata.containsKey(METADATA_SERVICE_URLS_PROPERTY_NAME);
|
||||
}
|
||||
|
||||
private Set<String> getServices(URL url) {
|
||||
Set<String> subscribedServices = repository.getSubscribedServices();
|
||||
// TODO Add the filter feature
|
||||
return subscribedServices;
|
||||
}
|
||||
|
||||
private void notifyAllSubscribedURLs(URL url, List<URL> subscribedURLs,
|
||||
NotifyListener listener) {
|
||||
|
||||
if (isEmpty(subscribedURLs)) {
|
||||
// Add the EMPTY_PROTOCOL URL
|
||||
subscribedURLs.add(emptyURL(url));
|
||||
|
||||
if (isDubboMetadataServiceURL(url)) {
|
||||
// if meta service change, and serviceInstances is zero, will clean up
|
||||
// information about this client
|
||||
String serviceName = url.getParameter(GROUP_KEY);
|
||||
repository.removeMetadataAndInitializedService(serviceName, url);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The subscribed URL[{}] will notify all URLs : {}", url,
|
||||
subscribedURLs);
|
||||
}
|
||||
|
||||
// Notify all
|
||||
listener.notify(subscribedURLs);
|
||||
}
|
||||
|
||||
private List<ServiceInstance> getServiceInstances(Iterable<String> serviceNames) {
|
||||
return stream(serviceNames.spliterator(), false).map(this::getServiceInstances)
|
||||
.flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ServiceInstance> getServiceInstances(String serviceName) {
|
||||
return hasText(serviceName) ? doGetServiceInstances(serviceName) : emptyList();
|
||||
}
|
||||
|
||||
private List<ServiceInstance> doGetServiceInstances(String serviceName) {
|
||||
List<ServiceInstance> serviceInstances = emptyList();
|
||||
try {
|
||||
serviceInstances = discoveryClient.getInstances(serviceName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return serviceInstances;
|
||||
}
|
||||
|
||||
private String generateId(URL url) {
|
||||
return url.getServiceKey();
|
||||
}
|
||||
|
||||
private URL emptyURL(URL url) {
|
||||
// issue : When the last service provider is closed, the client still periodically
|
||||
// connects to the last provider.n
|
||||
// fix https://github.com/alibaba/spring-cloud-alibaba/issues/1259
|
||||
return from(url).setProtocol(EMPTY_PROTOCOL).removeParameter(CATEGORY_KEY)
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<URL> getExportedURLs(DubboMetadataService dubboMetadataService,
|
||||
URL subscribedURL) {
|
||||
String serviceInterface = subscribedURL.getServiceInterface();
|
||||
String group = subscribedURL.getParameter(GROUP_KEY);
|
||||
String version = subscribedURL.getParameter(VERSION_KEY);
|
||||
// The subscribed protocol may be null
|
||||
String subscribedProtocol = subscribedURL.getParameter(PROTOCOL_KEY);
|
||||
String exportedURLsJSON = dubboMetadataService.getExportedURLs(serviceInterface,
|
||||
group, version);
|
||||
return jsonUtils.toURLs(exportedURLsJSON).stream()
|
||||
.filter(exportedURL -> subscribedProtocol == null
|
||||
|| subscribedProtocol.equalsIgnoreCase(exportedURL.getProtocol()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
|
||||
NotifyListener listener) {
|
||||
|
||||
// Sync subscription
|
||||
subscribeDubboMetadataServiceURLs(subscribedURL, listener,
|
||||
getServiceName(subscribedURL));
|
||||
|
||||
// Sync subscription
|
||||
if (containsProviderCategory(subscribedURL)) {
|
||||
registerServiceInstancesChangedListener(subscribedURL, event -> {
|
||||
|
||||
String sourceServiceName = event.getServiceName();
|
||||
String serviceName = getServiceName(subscribedURL);
|
||||
|
||||
if (Objects.equals(sourceServiceName, serviceName)) {
|
||||
subscribeDubboMetadataServiceURLs(subscribedURL, listener,
|
||||
sourceServiceName);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String getServiceName(URL subscribedURL) {
|
||||
return subscribedURL.getParameter(GROUP_KEY);
|
||||
}
|
||||
|
||||
private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
|
||||
NotifyListener listener, String serviceName) {
|
||||
|
||||
String serviceInterface = subscribedURL.getServiceInterface();
|
||||
String version = subscribedURL.getParameter(VERSION_KEY);
|
||||
String protocol = subscribedURL.getParameter(PROTOCOL_KEY);
|
||||
|
||||
List<ServiceInstance> serviceInstances = getServiceInstances(serviceName);
|
||||
|
||||
List<URL> urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances,
|
||||
serviceInterface, version, protocol);
|
||||
|
||||
notifyAllSubscribedURLs(subscribedURL, urls, listener);
|
||||
}
|
||||
|
||||
// private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
|
||||
// NotifyListener listener, Set<String> serviceNames) {
|
||||
//
|
||||
// String serviceInterface = subscribedURL.getServiceInterface();
|
||||
// String version = subscribedURL.getParameter(VERSION_KEY);
|
||||
// String protocol = subscribedURL.getParameter(PROTOCOL_KEY);
|
||||
//
|
||||
// List<ServiceInstance> serviceInstances = getServiceInstances(serviceNames);
|
||||
//
|
||||
// List<URL> urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances,
|
||||
// serviceInterface, version, protocol);
|
||||
//
|
||||
// notifyAllSubscribedURLs(subscribedURL, urls, listener);
|
||||
// }
|
||||
|
||||
private boolean containsProviderCategory(URL subscribedURL) {
|
||||
String category = subscribedURL.getParameter(CATEGORY_KEY);
|
||||
return category == null ? false : category.contains(PROVIDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void doUnsubscribe(URL url, NotifyListener listener) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !discoveryClient.getServices().isEmpty();
|
||||
}
|
||||
|
||||
protected boolean isAdminURL(URL url) {
|
||||
return ADMIN_PROTOCOL.equals(url.getProtocol());
|
||||
}
|
||||
|
||||
protected boolean isDubboMetadataServiceURL(URL url) {
|
||||
return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.dubbo.util;
|
||||
|
||||
/**
|
||||
* The constants for Dubbo Spring Cloud.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public final class DubboCloudConstants {
|
||||
|
||||
/**
|
||||
* The property prefix of Configuration.
|
||||
*/
|
||||
public static final String CONFIG_PROPERTY_PREFIX = "dubbo.cloud";
|
||||
|
||||
/**
|
||||
* The property name of Registry type.
|
||||
*/
|
||||
public static final String REGISTRY_TYPE_PROPERTY_NAME = CONFIG_PROPERTY_PREFIX
|
||||
+ ".registry-type";
|
||||
|
||||
/**
|
||||
* The property value of Spring Cloud Registry.
|
||||
*/
|
||||
public static final String SPRING_CLOUD_REGISTRY_PROPERTY_VALUE = "spring-cloud";
|
||||
|
||||
/**
|
||||
* The property value of Dubbo Cloud Registry.
|
||||
*/
|
||||
public static final String DUBBO_CLOUD_REGISTRY_PROPERTY_VALUE = "dubbo-cloud";
|
||||
|
||||
private DubboCloudConstants() {
|
||||
throw new AssertionError("Must not instantiate constant utility class");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.dubbo.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.cloud.dubbo.service.DubboMetadataService;
|
||||
import org.apache.dubbo.common.URL;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
/**
|
||||
* The utilities class of Dubbo Metadata.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class DubboMetadataUtils {
|
||||
|
||||
/**
|
||||
* The {@link String#format(String, Object...) pattern} of dubbo protocols port.
|
||||
*/
|
||||
public static final String DUBBO_PROTOCOLS_PORT_PROPERTY_NAME_PATTERN = "dubbo.protocols.%s.port";
|
||||
|
||||
private final JSONUtils jsonUtils;
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
private final String currentApplicationName;
|
||||
|
||||
public DubboMetadataUtils(JSONUtils jsonUtils, Environment environment) {
|
||||
this.jsonUtils = jsonUtils;
|
||||
this.environment = environment;
|
||||
this.currentApplicationName = environment.getProperty("spring.application.name",
|
||||
environment.getProperty("dubbo.application.name", "application"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current application name.
|
||||
* @return non-null
|
||||
*/
|
||||
public String getCurrentApplicationName() {
|
||||
return currentApplicationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link URL urls} that {@link DubboMetadataService} exported by the
|
||||
* specified {@link ServiceInstance}.
|
||||
* @param serviceInstance {@link ServiceInstance}
|
||||
* @return the mutable {@link URL urls}
|
||||
*/
|
||||
public List<URL> getDubboMetadataServiceURLs(ServiceInstance serviceInstance) {
|
||||
Map<String, String> metadata = serviceInstance.getMetadata();
|
||||
String dubboURLsJSON = metadata.get(METADATA_SERVICE_URLS_PROPERTY_NAME);
|
||||
return jsonUtils.toURLs(dubboURLsJSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link URL urls} that {@link DubboMetadataService} exported by the
|
||||
* specified {@link ServiceInstance ServiceInstances}.
|
||||
* @param serviceInstances the list of {@link ServiceInstance ServiceInstances}
|
||||
* @param serviceInterface the interface name of Dubbo service
|
||||
* @param version the version of Dubbo service
|
||||
* @param protocol the protocol that Dubbo Service exports
|
||||
* @return the mutable {@link URL urls}
|
||||
*/
|
||||
public List<URL> getDubboMetadataServiceURLs(List<ServiceInstance> serviceInstances,
|
||||
String serviceInterface, String version, String protocol) {
|
||||
return serviceInstances.stream().map(this::getDubboMetadataServiceURLs)
|
||||
.flatMap(List::stream)
|
||||
.filter(url -> protocol == null
|
||||
|| Objects.equals(protocol, url.getProtocol()))
|
||||
.filter(url -> Objects.equals(serviceInterface,
|
||||
url.getServiceInterface()))
|
||||
.filter(url -> Objects.equals(version, url.getParameter(VERSION_KEY)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property name of Dubbo Protocol.
|
||||
* @param protocol Dubbo Protocol
|
||||
* @return non-null
|
||||
*/
|
||||
public String getDubboProtocolPropertyName(String protocol) {
|
||||
return format(DUBBO_PROTOCOLS_PORT_PROPERTY_NAME_PATTERN, protocol);
|
||||
}
|
||||
|
||||
public Integer getDubboProtocolPort(ServiceInstance serviceInstance,
|
||||
String protocol) {
|
||||
String protocolProperty = getDubboProtocolPropertyName(protocol);
|
||||
Map<String, String> metadata = serviceInstance.getMetadata();
|
||||
String protocolPort = metadata.get(protocolProperty);
|
||||
return hasText(protocolPort) ? Integer.valueOf(protocolPort) : null;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
# Dubbo Endpoints Default Properties is loaded by @PropertySource with low order,
|
||||
# Set enabled for Dubbo Endpoints
|
||||
management.endpoint.dubborestmetadata.enabled = true
|
||||
|
||||
management.endpoint.dubborestmetadata.enabled=true
|
||||
# "management.endpoints.web.base-path" should not be configured in this file
|
||||
# Re-defines path-mapping of Dubbo Web Endpoints
|
||||
management.endpoints.web.path-mapping.dubborestmetadata = dubbo/rest/metadata
|
||||
management.endpoints.web.path-mapping.dubborestmetadata=dubbo/rest/metadata
|
||||
|
Loading…
Reference in New Issue