mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Polish spring-cloud-incubator/spring-cloud-alibaba#623 : Bugfix
This commit is contained in:
parent
7225f63f56
commit
9e0a5185d1
@ -19,6 +19,13 @@ package com.alibaba.cloud.dubbo.autoconfigure;
|
|||||||
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
||||||
import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
|
import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
|
||||||
import com.netflix.discovery.CacheRefreshedEvent;
|
import com.netflix.discovery.CacheRefreshedEvent;
|
||||||
|
import org.apache.curator.framework.CuratorFramework;
|
||||||
|
import org.apache.curator.framework.api.CuratorWatcher;
|
||||||
|
import org.apache.zookeeper.KeeperException;
|
||||||
|
import org.apache.zookeeper.WatchedEvent;
|
||||||
|
import org.apache.zookeeper.Watcher;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||||
@ -29,17 +36,25 @@ import org.springframework.cloud.client.ServiceInstance;
|
|||||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||||
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
|
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
|
||||||
|
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
|
||||||
|
import org.springframework.cloud.zookeeper.discovery.dependency.ZookeeperDependencies;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.CONSUL_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME;
|
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.CONSUL_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME;
|
||||||
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME;
|
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME;
|
||||||
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME;
|
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME;
|
||||||
import static org.springframework.util.CollectionUtils.isEmpty;
|
import static org.apache.zookeeper.Watcher.Event.EventType.NodeChildrenChanged;
|
||||||
|
import static org.apache.zookeeper.Watcher.Event.EventType.NodeDataChanged;
|
||||||
import static org.springframework.util.StringUtils.hasText;
|
import static org.springframework.util.StringUtils.hasText;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,19 +80,25 @@ public class DubboServiceDiscoveryAutoConfiguration {
|
|||||||
|
|
||||||
private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
|
private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
private final ApplicationEventPublisher applicationEventPublisher;
|
private final ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
private final ObjectProvider<DiscoveryClient> discoveryClient;
|
private final DiscoveryClient discoveryClient;
|
||||||
|
|
||||||
public DubboServiceDiscoveryAutoConfiguration(DubboServiceMetadataRepository dubboServiceMetadataRepository,
|
public DubboServiceDiscoveryAutoConfiguration(DubboServiceMetadataRepository dubboServiceMetadataRepository,
|
||||||
ApplicationEventPublisher applicationEventPublisher,
|
ApplicationEventPublisher applicationEventPublisher,
|
||||||
ObjectProvider<DiscoveryClient> discoveryClient) {
|
DiscoveryClient discoveryClient) {
|
||||||
this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
|
this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
|
||||||
this.applicationEventPublisher = applicationEventPublisher;
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
this.discoveryClient = discoveryClient;
|
this.discoveryClient = discoveryClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void forEachSubscribedServices(Consumer<String> serviceNameConsumer) {
|
||||||
|
dubboServiceMetadataRepository.getSubscribedServices().forEach(serviceNameConsumer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch a {@link ServiceInstancesChangedEvent}
|
* Dispatch a {@link ServiceInstancesChangedEvent}
|
||||||
*
|
*
|
||||||
@ -85,14 +106,19 @@ public class DubboServiceDiscoveryAutoConfiguration {
|
|||||||
* @param serviceInstances the {@link ServiceInstance instances} of some service
|
* @param serviceInstances the {@link ServiceInstance instances} of some service
|
||||||
* @see AbstractSpringCloudRegistry#registerServiceInstancesChangedEventListener(URL, NotifyListener)
|
* @see AbstractSpringCloudRegistry#registerServiceInstancesChangedEventListener(URL, NotifyListener)
|
||||||
*/
|
*/
|
||||||
protected void dispatchServiceInstancesChangedEvent(String serviceName, Collection<ServiceInstance> serviceInstances) {
|
private void dispatchServiceInstancesChangedEvent(String serviceName, Collection<ServiceInstance> serviceInstances) {
|
||||||
if (!hasText(serviceName) || isEmpty(serviceInstances)) {
|
if (!hasText(serviceName) || serviceInstances == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent(serviceName, serviceInstances);
|
ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent(serviceName, serviceInstances);
|
||||||
applicationEventPublisher.publishEvent(event);
|
applicationEventPublisher.publishEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ServiceInstance> getInstances(String serviceName) {
|
||||||
|
return discoveryClient.getInstances(serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnBean(name = EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME)
|
@ConditionalOnBean(name = EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME)
|
||||||
class EurekaConfiguration {
|
class EurekaConfiguration {
|
||||||
@ -109,20 +135,96 @@ public class DubboServiceDiscoveryAutoConfiguration {
|
|||||||
*/
|
*/
|
||||||
@EventListener(HeartbeatEvent.class)
|
@EventListener(HeartbeatEvent.class)
|
||||||
public void onHeartbeatEvent(HeartbeatEvent event) {
|
public void onHeartbeatEvent(HeartbeatEvent event) {
|
||||||
discoveryClient.ifAvailable(discoveryClient -> {
|
forEachSubscribedServices(serviceName -> {
|
||||||
dubboServiceMetadataRepository.getSubscribedServices().forEach(serviceName -> {
|
List<ServiceInstance> serviceInstances = getInstances(serviceName);
|
||||||
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
|
dispatchServiceInstancesChangedEvent(serviceName, serviceInstances);
|
||||||
dispatchServiceInstancesChangedEvent(serviceName, serviceInstances);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnBean(name = ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME)
|
@ConditionalOnBean(name = ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME)
|
||||||
class ZookeeperConfiguration {
|
class ZookeeperConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Key is watched Zookeeper path, the value is an instance of {@link CuratorWatcher}
|
||||||
|
*/
|
||||||
|
private final Map<String, CuratorWatcher> watcherCaches = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final ZookeeperDiscoveryProperties zookeeperDiscoveryProperties;
|
||||||
|
|
||||||
|
private final ObjectProvider<ZookeeperDependencies> zookeeperDependencies;
|
||||||
|
|
||||||
|
private final CuratorFramework curatorFramework;
|
||||||
|
|
||||||
|
private final String rootPath;
|
||||||
|
|
||||||
|
ZookeeperConfiguration(ZookeeperDiscoveryProperties zookeeperDiscoveryProperties,
|
||||||
|
ObjectProvider<ZookeeperDependencies> zookeeperDependencies,
|
||||||
|
CuratorFramework curatorFramework) {
|
||||||
|
this.zookeeperDiscoveryProperties = zookeeperDiscoveryProperties;
|
||||||
|
this.zookeeperDependencies = zookeeperDependencies;
|
||||||
|
this.curatorFramework = curatorFramework;
|
||||||
|
this.rootPath = zookeeperDiscoveryProperties.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener(ContextRefreshedEvent.class)
|
||||||
|
public void onContextRefreshedEvent(ContextRefreshedEvent event) {
|
||||||
|
forEachSubscribedServices(this::registerServiceWatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerServiceWatcher(String serviceName) {
|
||||||
|
|
||||||
|
String servicePath = buildServicePath(serviceName);
|
||||||
|
|
||||||
|
CuratorWatcher watcher = watcherCaches.computeIfAbsent(servicePath,
|
||||||
|
path -> new ServiceInstancesChangedWatcher(serviceName));
|
||||||
|
|
||||||
|
try {
|
||||||
|
curatorFramework.getChildren().usingWatcher(watcher).forPath(servicePath);
|
||||||
|
} catch (KeeperException.NoNodeException e) {
|
||||||
|
// ignored
|
||||||
|
if (logger.isErrorEnabled()) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceInstancesChangedWatcher implements CuratorWatcher {
|
||||||
|
|
||||||
|
private final String serviceName;
|
||||||
|
|
||||||
|
ServiceInstancesChangedWatcher(String serviceName) {
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(WatchedEvent event) throws Exception {
|
||||||
|
|
||||||
|
Watcher.Event.EventType eventType = event.getType();
|
||||||
|
|
||||||
|
if (NodeChildrenChanged.equals(eventType) || NodeDataChanged.equals(eventType)) {
|
||||||
|
dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-register again
|
||||||
|
registerServiceWatcher(serviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildServicePath(String serviceName) {
|
||||||
|
return rootPath + "/" + serviceRelativePath(serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String serviceRelativePath(String serviceName) {
|
||||||
|
return Optional.ofNullable(zookeeperDependencies.getIfAvailable())
|
||||||
|
.map(z -> z.getAliasForPath(serviceName))
|
||||||
|
.orElse(serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@ -46,7 +46,7 @@ public class DubboMetadataInitializerInterceptor implements ClientHttpRequestInt
|
|||||||
|
|
||||||
String serviceName = originalUri.getHost();
|
String serviceName = originalUri.getHost();
|
||||||
|
|
||||||
repository.initialize(serviceName);
|
repository.initializeMetadata(serviceName);
|
||||||
|
|
||||||
// Execute next
|
// Execute next
|
||||||
return execution.execute(request, body);
|
return execution.execute(request, body);
|
||||||
|
@ -31,6 +31,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
@ -38,12 +39,10 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
|
|||||||
import org.springframework.cloud.commons.util.InetUtils;
|
import org.springframework.cloud.commons.util.InetUtils;
|
||||||
import org.springframework.http.HttpRequest;
|
import org.springframework.http.HttpRequest;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -74,7 +73,7 @@ import static org.springframework.util.StringUtils.hasText;
|
|||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public class DubboServiceMetadataRepository {
|
public class DubboServiceMetadataRepository implements SmartInitializingSingleton {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The prefix of {@link DubboMetadataService} : "dubbo.metadata-service."
|
* The prefix of {@link DubboMetadataService} : "dubbo.metadata-service."
|
||||||
@ -95,6 +94,16 @@ public class DubboServiceMetadataRepository {
|
|||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor object for synchronization
|
||||||
|
*/
|
||||||
|
private final Object monitor = new Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Set} of service names that had been initialized
|
||||||
|
*/
|
||||||
|
private final Set<String> initializedServices = new LinkedHashSet<>();
|
||||||
|
|
||||||
// =================================== Registration =================================== //
|
// =================================== Registration =================================== //
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +117,7 @@ public class DubboServiceMetadataRepository {
|
|||||||
|
|
||||||
// =================================== Subscription =================================== //
|
// =================================== Subscription =================================== //
|
||||||
|
|
||||||
private Set<String> subscribedServices;
|
private Set<String> subscribedServices = emptySet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The subscribed {@link URL urls} {@link Map} of {@link DubboMetadataService},
|
* The subscribed {@link URL urls} {@link Map} of {@link DubboMetadataService},
|
||||||
@ -162,13 +171,47 @@ public class DubboServiceMetadataRepository {
|
|||||||
|
|
||||||
// ==================================================================================== //
|
// ==================================================================================== //
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
// Keep the order in following invocations
|
|
||||||
initSubscribedServices();
|
initSubscribedServices();
|
||||||
initSubscribedDubboMetadataServices();
|
}
|
||||||
initDubboRestServiceMetadataRepository();
|
|
||||||
|
@Override
|
||||||
|
public void afterSingletonsInstantiated() {
|
||||||
|
initializeMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the metadata
|
||||||
|
*/
|
||||||
|
private void initializeMetadata() {
|
||||||
|
subscribedServices.forEach(this::initializeMetadata);
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("The metadata of Dubbo services has been initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the metadata of Dubbo Services
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the order in following invocations
|
||||||
|
initSubscribedDubboMetadataService(serviceName);
|
||||||
|
initDubboRestServiceMetadataRepository(serviceName);
|
||||||
|
// mark this service name having been initialized
|
||||||
|
initializedServices.add(serviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -245,19 +288,15 @@ public class DubboServiceMetadataRepository {
|
|||||||
return unmodifiableSet(serviceRestMetadata);
|
return unmodifiableSet(serviceRestMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Get The subscribed {@link DubboMetadataService}'s {@link URL URLs}
|
|
||||||
// *
|
|
||||||
// * @return non-null read-only {@link List}
|
|
||||||
// */
|
|
||||||
// public List<URL> getSubscribedDubboMetadataServiceURLs() {
|
|
||||||
// return Collections.unmodifiableList(subscribedDubboMetadataServiceURLs);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public List<URL> findSubscribedDubboMetadataServiceURLs(String serviceName, String group, String version,
|
public List<URL> findSubscribedDubboMetadataServiceURLs(String serviceName, String group, String version,
|
||||||
String protocol) {
|
String protocol) {
|
||||||
String serviceKey = URL.buildKey(serviceName, group, version);
|
String serviceKey = URL.buildKey(serviceName, group, version);
|
||||||
List<URL> urls = subscribedDubboMetadataServiceURLs.get(serviceKey);
|
|
||||||
|
List<URL> urls = null;
|
||||||
|
|
||||||
|
synchronized (monitor) {
|
||||||
|
urls = subscribedDubboMetadataServiceURLs.get(serviceKey);
|
||||||
|
}
|
||||||
|
|
||||||
if (isEmpty(urls)) {
|
if (isEmpty(urls)) {
|
||||||
return emptyList();
|
return emptyList();
|
||||||
@ -348,7 +387,7 @@ public class DubboServiceMetadataRepository {
|
|||||||
*
|
*
|
||||||
* @param serviceName the service name
|
* @param serviceName the service name
|
||||||
*/
|
*/
|
||||||
public void initialize(String serviceName) {
|
protected void initDubboRestServiceMetadataRepository(String serviceName) {
|
||||||
|
|
||||||
if (dubboRestServiceMetadataRepository.containsKey(serviceName)) {
|
if (dubboRestServiceMetadataRepository.containsKey(serviceName)) {
|
||||||
return;
|
return;
|
||||||
@ -501,23 +540,26 @@ public class DubboServiceMetadataRepository {
|
|||||||
subscribedServices.remove(currentApplicationName);
|
subscribedServices.remove(currentApplicationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSubscribedDubboMetadataServices() {
|
protected void initSubscribedDubboMetadataService(String serviceName) {
|
||||||
// clear subscribedDubboMetadataServiceURLs
|
discoveryClient.getInstances(serviceName)
|
||||||
subscribedDubboMetadataServiceURLs.clear();
|
.stream()
|
||||||
|
.findAny()
|
||||||
subscribedServices.stream()
|
.map(this::getDubboMetadataServiceURLs)
|
||||||
.map(discoveryClient::getInstances)
|
.ifPresent(dubboMetadataServiceURLs -> {
|
||||||
.filter(this::isNotEmpty)
|
dubboMetadataServiceURLs.forEach(dubboMetadataServiceURL -> {
|
||||||
.forEach(serviceInstances -> {
|
try {
|
||||||
ServiceInstance serviceInstance = serviceInstances.get(0);
|
initSubscribedDubboMetadataServiceURL(dubboMetadataServiceURL);
|
||||||
getDubboMetadataServiceURLs(serviceInstance).forEach(dubboMetadataServiceURL -> {
|
initDubboMetadataServiceProxy(dubboMetadataServiceURL);
|
||||||
initSubscribedDubboMetadataServiceURLs(dubboMetadataServiceURL);
|
} catch (Throwable e) {
|
||||||
initDubboMetadataServiceProxy(dubboMetadataServiceURL);
|
if (logger.isErrorEnabled()) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSubscribedDubboMetadataServiceURLs(URL dubboMetadataServiceURL) {
|
private void initSubscribedDubboMetadataServiceURL(URL dubboMetadataServiceURL) {
|
||||||
// add subscriptions
|
// add subscriptions
|
||||||
String serviceKey = dubboMetadataServiceURL.getServiceKey();
|
String serviceKey = dubboMetadataServiceURL.getServiceKey();
|
||||||
subscribedDubboMetadataServiceURLs.add(serviceKey, dubboMetadataServiceURL);
|
subscribedDubboMetadataServiceURLs.add(serviceKey, dubboMetadataServiceURL);
|
||||||
@ -529,12 +571,4 @@ public class DubboServiceMetadataRepository {
|
|||||||
// Initialize DubboMetadataService with right version
|
// Initialize DubboMetadataService with right version
|
||||||
dubboMetadataConfigServiceProxy.initProxy(serviceName, version);
|
dubboMetadataConfigServiceProxy.initProxy(serviceName, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDubboRestServiceMetadataRepository() {
|
|
||||||
subscribedServices.forEach(this::initialize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isNotEmpty(Collection collection) {
|
|
||||||
return !CollectionUtils.isEmpty(collection);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,6 @@ package com.alibaba.cloud.dubbo.openfeign;
|
|||||||
|
|
||||||
import org.apache.dubbo.rpc.service.GenericService;
|
import org.apache.dubbo.rpc.service.GenericService;
|
||||||
|
|
||||||
import feign.Contract;
|
|
||||||
import feign.Target;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import com.alibaba.cloud.dubbo.annotation.DubboTransported;
|
import com.alibaba.cloud.dubbo.annotation.DubboTransported;
|
||||||
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
|
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
|
||||||
import com.alibaba.cloud.dubbo.metadata.DubboTransportedMethodMetadata;
|
import com.alibaba.cloud.dubbo.metadata.DubboTransportedMethodMetadata;
|
||||||
@ -33,6 +29,10 @@ import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepositor
|
|||||||
import com.alibaba.cloud.dubbo.metadata.resolver.DubboTransportedMethodMetadataResolver;
|
import com.alibaba.cloud.dubbo.metadata.resolver.DubboTransportedMethodMetadataResolver;
|
||||||
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||||
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
|
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
|
||||||
|
import feign.Contract;
|
||||||
|
import feign.Target;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.cloud.openfeign.FeignContext;
|
import org.springframework.cloud.openfeign.FeignContext;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ class TargeterInvocationHandler implements InvocationHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update Metadata
|
// Update Metadata
|
||||||
repository.initialize(serviceName);
|
repository.initializeMetadata(serviceName);
|
||||||
|
|
||||||
Map<Method, FeignMethodMetadata> feignMethodMetadataMap = getFeignMethodMetadataMap(serviceName, feignRestMethodMetadataMap);
|
Map<Method, FeignMethodMetadata> feignMethodMetadataMap = getFeignMethodMetadataMap(serviceName, feignRestMethodMetadataMap);
|
||||||
|
|
||||||
|
@ -37,8 +37,6 @@ import java.util.Collection;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -178,7 +176,12 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
|||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(ServiceInstancesChangedEvent event) {
|
public void onApplicationEvent(ServiceInstancesChangedEvent event) {
|
||||||
String serviceName = event.getServiceName();
|
String serviceName = event.getServiceName();
|
||||||
subscribeDubboServiceURLs(url, listener, serviceName, s -> event.getServiceInstances());
|
Collection<ServiceInstance> serviceInstances = event.getServiceInstances();
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("The event of the service instances[name : {} , size: {}] changed has been arrived",
|
||||||
|
serviceName, serviceInstances.size());
|
||||||
|
}
|
||||||
|
subscribeDubboServiceURLs(url, listener, serviceName, s -> serviceInstances);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -193,39 +196,54 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
|||||||
|
|
||||||
protected void subscribeDubboServiceURLs(URL url, NotifyListener listener, String serviceName,
|
protected void subscribeDubboServiceURLs(URL url, NotifyListener listener, String serviceName,
|
||||||
Function<String, Collection<ServiceInstance>> serviceInstancesFunction) {
|
Function<String, Collection<ServiceInstance>> serviceInstancesFunction) {
|
||||||
Optional.ofNullable(serviceName)
|
|
||||||
.map(dubboMetadataConfigServiceProxy::getProxy)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.ifPresent(dubboMetadataService -> {
|
|
||||||
List<URL> exportedURLs = getExportedURLs(dubboMetadataService, url);
|
|
||||||
List<URL> allSubscribedURLs = new LinkedList<>();
|
|
||||||
for (URL exportedURL : exportedURLs) {
|
|
||||||
Collection<ServiceInstance> serviceInstances = serviceInstancesFunction.apply(serviceName);
|
|
||||||
String protocol = exportedURL.getProtocol();
|
|
||||||
List<URL> subscribedURLs = new LinkedList<>();
|
|
||||||
serviceInstances.forEach(serviceInstance -> {
|
|
||||||
Integer port = repository.getDubboProtocolPort(serviceInstance, protocol);
|
|
||||||
String host = serviceInstance.getHost();
|
|
||||||
if (port == null) {
|
|
||||||
if (logger.isWarnEnabled()) {
|
|
||||||
logger.warn("The protocol[{}] port of Dubbo service instance[host : {}] " +
|
|
||||||
"can't be resolved", protocol, host);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
URL subscribedURL = new URL(protocol, host, port, exportedURL.getParameters());
|
|
||||||
subscribedURLs.add(subscribedURL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy.getProxy(serviceName);
|
||||||
logger.debug("The subscribed URL[{}] will notify all URLs : {}", url, subscribedURLs);
|
|
||||||
}
|
|
||||||
|
|
||||||
allSubscribedURLs.addAll(subscribedURLs);
|
if (dubboMetadataService == null) { // If not found, try to initialize
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("The metadata of Dubbo service[key : {}] can't be found when the subscribed service[name : {}], " +
|
||||||
|
"and then try to initialize it", url.getServiceKey(), serviceName);
|
||||||
|
}
|
||||||
|
repository.initializeMetadata(serviceName);
|
||||||
|
dubboMetadataService = dubboMetadataConfigServiceProxy.getProxy(serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dubboMetadataService == null) { // It makes sure not-found, return immediately
|
||||||
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("The metadata of Dubbo service[key : {}] still can't be found, it could effect the further " +
|
||||||
|
"Dubbo service invocation", url.getServiceKey());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<URL> exportedURLs = getExportedURLs(dubboMetadataService, url);
|
||||||
|
List<URL> allSubscribedURLs = new LinkedList<>();
|
||||||
|
for (URL exportedURL : exportedURLs) {
|
||||||
|
Collection<ServiceInstance> serviceInstances = serviceInstancesFunction.apply(serviceName);
|
||||||
|
String protocol = exportedURL.getProtocol();
|
||||||
|
List<URL> subscribedURLs = new LinkedList<>();
|
||||||
|
serviceInstances.forEach(serviceInstance -> {
|
||||||
|
Integer port = repository.getDubboProtocolPort(serviceInstance, protocol);
|
||||||
|
String host = serviceInstance.getHost();
|
||||||
|
if (port == null) {
|
||||||
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("The protocol[{}] port of Dubbo service instance[host : {}] " +
|
||||||
|
"can't be resolved", protocol, host);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
URL subscribedURL = new URL(protocol, host, port, exportedURL.getParameters());
|
||||||
|
subscribedURLs.add(subscribedURL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
listener.notify(allSubscribedURLs);
|
if (logger.isDebugEnabled()) {
|
||||||
});
|
logger.debug("The subscribed URL[{}] will notify all URLs : {}", url, subscribedURLs);
|
||||||
|
}
|
||||||
|
|
||||||
|
allSubscribedURLs.addAll(subscribedURLs);
|
||||||
|
}
|
||||||
|
|
||||||
|
listener.notify(allSubscribedURLs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ServiceInstance> getServiceInstances(String serviceName) {
|
private List<ServiceInstance> getServiceInstances(String serviceName) {
|
||||||
@ -286,5 +304,4 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
|
|||||||
protected boolean isDubboMetadataServiceURL(URL url) {
|
protected boolean isDubboMetadataServiceURL(URL url) {
|
||||||
return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
|
return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.cloud.dubbo.bootstrap;
|
package com.alibaba.cloud.dubbo.bootstrap;
|
||||||
|
|
||||||
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.dubbo.config.annotation.Reference;
|
import org.apache.dubbo.config.annotation.Reference;
|
||||||
|
|
||||||
|
import com.alibaba.cloud.dubbo.annotation.DubboTransported;
|
||||||
|
import com.alibaba.cloud.dubbo.service.RestService;
|
||||||
|
import com.alibaba.cloud.dubbo.service.User;
|
||||||
|
import com.alibaba.cloud.dubbo.service.UserService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
@ -41,10 +41,10 @@ import org.springframework.web.bind.annotation.RequestHeader;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import com.alibaba.cloud.dubbo.annotation.DubboTransported;
|
import java.util.HashMap;
|
||||||
import com.alibaba.cloud.dubbo.service.RestService;
|
import java.util.Map;
|
||||||
import com.alibaba.cloud.dubbo.service.User;
|
|
||||||
import com.alibaba.cloud.dubbo.service.UserService;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dubbo Spring Cloud Consumer Bootstrap
|
* Dubbo Spring Cloud Consumer Bootstrap
|
||||||
@ -172,7 +172,7 @@ public class DubboSpringCloudConsumerBootstrap {
|
|||||||
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
||||||
System.out.println(dubboFeignRestService.pathVariables("c", "b", "a"));
|
System.out.println(dubboFeignRestService.pathVariables("c", "b", "a"));
|
||||||
// Spring Cloud Open Feign REST Call
|
// Spring Cloud Open Feign REST Call
|
||||||
System.out.println(feignRestService.pathVariables("b", "a", "c"));
|
// System.out.println(feignRestService.pathVariables("b", "a", "c"));
|
||||||
|
|
||||||
// RestTemplate call
|
// RestTemplate call
|
||||||
System.out.println(restTemplate.getForEntity(
|
System.out.println(restTemplate.getForEntity(
|
||||||
@ -186,7 +186,7 @@ public class DubboSpringCloudConsumerBootstrap {
|
|||||||
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
||||||
System.out.println(dubboFeignRestService.headers("b", 10, "a"));
|
System.out.println(dubboFeignRestService.headers("b", 10, "a"));
|
||||||
// Spring Cloud Open Feign REST Call
|
// Spring Cloud Open Feign REST Call
|
||||||
System.out.println(feignRestService.headers("b", "a", 10));
|
// System.out.println(feignRestService.headers("b", "a", 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void callParam() {
|
private void callParam() {
|
||||||
@ -195,7 +195,7 @@ public class DubboSpringCloudConsumerBootstrap {
|
|||||||
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
||||||
System.out.println(dubboFeignRestService.param("mercyblitz"));
|
System.out.println(dubboFeignRestService.param("mercyblitz"));
|
||||||
// Spring Cloud Open Feign REST Call
|
// Spring Cloud Open Feign REST Call
|
||||||
System.out.println(feignRestService.param("mercyblitz"));
|
// System.out.println(feignRestService.param("mercyblitz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void callParams() {
|
private void callParams() {
|
||||||
@ -204,7 +204,7 @@ public class DubboSpringCloudConsumerBootstrap {
|
|||||||
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
||||||
System.out.println(dubboFeignRestService.params("1", 1));
|
System.out.println(dubboFeignRestService.params("1", 1));
|
||||||
// Spring Cloud Open Feign REST Call
|
// Spring Cloud Open Feign REST Call
|
||||||
System.out.println(feignRestService.params("1", 1));
|
// System.out.println(feignRestService.params("1", 1));
|
||||||
|
|
||||||
// RestTemplate call
|
// RestTemplate call
|
||||||
System.out.println(restTemplate.getForEntity(
|
System.out.println(restTemplate.getForEntity(
|
||||||
@ -223,7 +223,7 @@ public class DubboSpringCloudConsumerBootstrap {
|
|||||||
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
// Spring Cloud Open Feign REST Call (Dubbo Transported)
|
||||||
System.out.println(dubboFeignRestService.requestBody("Hello,World", data));
|
System.out.println(dubboFeignRestService.requestBody("Hello,World", data));
|
||||||
// Spring Cloud Open Feign REST Call
|
// Spring Cloud Open Feign REST Call
|
||||||
System.out.println(feignRestService.requestBody("Hello,World", data));
|
// System.out.println(feignRestService.requestBody("Hello,World", data));
|
||||||
|
|
||||||
// RestTemplate call
|
// RestTemplate call
|
||||||
System.out.println(restTemplate.postForObject(
|
System.out.println(restTemplate.postForObject(
|
||||||
|
@ -1,9 +1,29 @@
|
|||||||
package com.alibaba.cloud.dubbo.gateway;
|
package com.alibaba.cloud.dubbo.gateway;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.substringAfter;
|
import org.apache.dubbo.rpc.service.GenericException;
|
||||||
import static org.apache.commons.lang3.StringUtils.substringBetween;
|
import org.apache.dubbo.rpc.service.GenericService;
|
||||||
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
|
|
||||||
|
|
||||||
|
import com.alibaba.cloud.dubbo.http.MutableHttpServerRequest;
|
||||||
|
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
|
||||||
|
import com.alibaba.cloud.dubbo.metadata.RequestMetadata;
|
||||||
|
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
|
||||||
|
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
||||||
|
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContext;
|
||||||
|
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||||
|
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpRequest;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
|
import org.springframework.util.StreamUtils;
|
||||||
|
import org.springframework.web.servlet.HttpServletBean;
|
||||||
|
import org.springframework.web.util.UriComponents;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
@ -15,30 +35,9 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import static org.apache.commons.lang3.StringUtils.substringAfter;
|
||||||
import javax.servlet.ServletInputStream;
|
import static org.apache.commons.lang3.StringUtils.substringBetween;
|
||||||
import javax.servlet.annotation.WebServlet;
|
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.dubbo.rpc.service.GenericException;
|
|
||||||
import org.apache.dubbo.rpc.service.GenericService;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpRequest;
|
|
||||||
import org.springframework.util.AntPathMatcher;
|
|
||||||
import org.springframework.util.PathMatcher;
|
|
||||||
import org.springframework.util.StreamUtils;
|
|
||||||
import org.springframework.web.servlet.HttpServletBean;
|
|
||||||
import org.springframework.web.util.UriComponents;
|
|
||||||
|
|
||||||
import com.alibaba.cloud.dubbo.http.MutableHttpServerRequest;
|
|
||||||
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
|
|
||||||
import com.alibaba.cloud.dubbo.metadata.RequestMetadata;
|
|
||||||
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
|
|
||||||
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
|
||||||
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContext;
|
|
||||||
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
|
||||||
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
|
|
||||||
|
|
||||||
@WebServlet(urlPatterns = "/dsc/*")
|
@WebServlet(urlPatterns = "/dsc/*")
|
||||||
public class DubboGatewayServlet extends HttpServletBean {
|
public class DubboGatewayServlet extends HttpServletBean {
|
||||||
@ -86,7 +85,7 @@ public class DubboGatewayServlet extends HttpServletBean {
|
|||||||
String restPath = substringAfter(request.getRequestURI(), serviceName);
|
String restPath = substringAfter(request.getRequestURI(), serviceName);
|
||||||
|
|
||||||
// 初始化 serviceName 的 REST 请求元数据
|
// 初始化 serviceName 的 REST 请求元数据
|
||||||
repository.initialize(serviceName);
|
repository.initializeMetadata(serviceName);
|
||||||
// 将 HttpServletRequest 转化为 RequestMetadata
|
// 将 HttpServletRequest 转化为 RequestMetadata
|
||||||
RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);
|
RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user