Skip to content

Commit

Permalink
Dubbo cloud native (#4958)
Browse files Browse the repository at this point in the history
* Polish #4542 : [Enhancement] Adapt the Java standard Event/Listener mechanism

* Polish #4541 : [Feature] Add local File System DynamicConfigurationFactory‘s extension

* Polish #4541 : Bugfix

* Polish #4541 : Optimization

* Polish #4541 : Add the compatibility for PollingWatchService on the some platforms

* Polish #4541 : Add delay publish without ThreadPoolExecutor

* Polish #4541 : Refactor the extension name

* Polish #4541 : Add remove ops

* Polish #4541 : Add testable constructor

* Polish #4541 : Add getConfigGroups method

* Polish #4610 : [Refactor] Refactor the bootstrap module

* Polish #4541 : Fix the nulling URL issue

* Polish #4622 : [Refactor] Refactor ConfigManager

* Polish #4622 : [Refactor] Refactor ConfigManager

* Polish #4622 : Support multiple configcenters

* Polish #4671 : ServiceNameMapping will not map the group, version and protocol

* update referenceCount log (#4683)

Add comments to support multiple shared connections

* Polish /#4687 : Remove the duplicated test code in dubbo-config-spring (#4688)

* #4685  修改代码if判断false问题 if (hasException == false)修改成if (!hasException) (#4695)

* Fixed Service annotation method parameters are not in effect (#4598)

* keep demo simple, and switch to use zookeeper as registry center (#4705)

* keep demo simple, and switch to use zookeeper as registry center

* remove comment

* @reference auto-wires the instance of generic interface #4594 (#4677)

* try to shorten maven output to make travis build pass (#4710)

* use CountDownLatch to check zk registry if establish connection (#4589)

* Minor change

* Rename the extension name of WritableMetadataService

* Polish #4759 : [Refactor] Change the signature of methods of MetadataService #4759

* Merge remote-tracking branch 'upstream/master' into dubbo-cloud-native

# Conflicts:
#	dubbo-all/pom.xml
#	dubbo-bom/pom.xml
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConfigCenterConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/RegistryConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
#	dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/DynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-api/src/test/java/org/apache/dubbo/configcenter/mock/MockDynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
#	dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
#	dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
#	dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
#	dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifier.java
#	dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
#	dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifierTest.java
#	dubbo-metadata/dubbo-metadata-definition-protobuf/src/main/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilder.java
#	dubbo-metadata/dubbo-metadata-definition-protobuf/src/test/java/org/apache/dubbo/metadata/definition/protobuf/ProtobufTypeBuilderTest.java
#	dubbo-metadata/pom.xml
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
#	dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
#	dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
#	dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java

* Polish #3984 : Add the implementation of Page<ServiceInstance> getInstances(String serviceName, int offset, int pageSize, boolean healthyOnly)

* Code merge

* Fix the cases

* Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native

# Conflicts:
#	dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java
#	dubbo-metadata/dubbo-metadata-definition-protobuf/pom.xml
#	dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/support/ServiceOrientedRegistryTest.java
#	dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryFactory.java
#	dubbo-registry/dubbo-registry-etcd3/src/main/java/org/apache/dubbo/registry/etcd/EtcdServiceDiscovery.java

* Refactor ConfigManager

* Refactor ConfigManager

* Resolve the issues on ConfigManager

* Refactor and add test-cases for ConfigManager

* Polish #4774 : [Feature] Dubbo Cloud Native - To Support in Spring

* Polish #4808 : [Feature] Add the registered/unregistered event mechanism ShutdownHook

* Polish #4807 : [Feature] Add the callback mechanism ShutdownHook #4807

* Polish #4813 : [Feature] add Prioritized implementation for ServiceInstanceCustomizer

* Polish #4815 : [Feature] Add the ServiceLoader for Dubbo's services or components

* Polish #4815 : [Feature] Add the ServiceLoader for Dubbo's services or components

* Polish #4813 : [Feature] add Prioritized implementation for ServiceInstanceCustomizer

* Polish #4807 : Add sort implementation

* Refactor

* Refactor

* Polish #4845 : [Feature] Enhance the Event-Publishing feature to original ServiceDiscovery

* Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native

# Conflicts:
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceDiscoveryFactory.java
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java

* Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native

# Conflicts:
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceDiscoveryFactory.java
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java

* Polish #4854 : [Feature] MetadataService supports the Dubbo protocol under auto-increased port

* Polish #4857 : [Enhancement] Sync the Metadata storage type into ApplicationConfig

* Polish #4868 : [Enhancement] Refactor ConfigChangeEvent

* Polish #4868 : [Enhancement] Refactor ConfigChangeEvent

* Polish #4873 : [Feature] Add a conditional EventListener into Event Module

* Polish #4875 : [Feature] Refactor ServiceInstancesChangedListener

* Remove the cycle dependencies

* Remove the cycle dependencies

* Polish #4903 : [Feature] Set source into the BeanDefinition of Dubbo Config

* Polish #4902 : [Feature] Dubbo Cloud Native to Spring XML scenario

* Polish #4713 : Initial the new module and dependencies

* Polish #4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions

* Polish #4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions

* Polish #4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions

* Polish #4910 : [Feature] To suppoort DubboLifecycleComponentApplicationListener in Spring XML scenario

* Polish #4713 : Add Service discovery implementation for Eureka #4713

* Polish #4713 : Add Service registration and discovery implementation for Eureka

* Polish #4713 : Add Service registration and discovery implementation for Eureka

* Polish #4920 : [Refactor] Extract the common implementation for URLs' revision

* Refactor

* Polish #4925 : ServiceDiscovery limits only one ServiceInstancesChangedListener each service

* Polish #4925 : ServiceDiscovery limits only one ServiceInstancesChangedListener each service

* Remove useless classes

* Bugfix & Refactor ServiceDiscoveryRegistry

* Polish #4937 : The calculation of Revision should add the parameters of URL

* Polish #4940 : NacosDynamicConfiguration supports getConfigKeys method

* Polish #4942 : Dubbo Cloud Native supports multiple protcols

* Polish #4944 : [Feature] Simplify The metadata of URL for MetadataService

* Polish #4947 : [Feature] Dubbo Cloud-Native supports the REST call to Non-Dubbo

* Merge remote-tracking branch 'upstream/cloud-native' into dubbo-cloud-native

# Conflicts:
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java

* Refactor

* Update JavaDoc
  • Loading branch information
mercyblitz authored Aug 28, 2019
1 parent 79e69ad commit e2f0983
Showing 1 changed file with 94 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.DubboServiceLoader;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.ServiceNameMapping;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.store.InMemoryWritableMetadataService;
import org.apache.dubbo.metadata.store.RemoteWritableMetadataService;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
Expand Down Expand Up @@ -86,20 +86,40 @@
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getProtocolPort;

/**
* {@link ServiceDiscoveryRegistry} is the service-oriented {@link Registry} and dislike the traditional one that
* {@link #register(URL) registers} to and {@link #subscribe(URL, NotifyListener) discoveries}
* the Dubbo's {@link URL urls} from the external registry. In the {@link #register(URL) registration}
* phase, The {@link URL urls} of Dubbo services will be {@link WritableMetadataService#exportURL(URL) exported} into
* {@link WritableMetadataService} that is either {@link InMemoryWritableMetadataService in-memory} or
* {@link RemoteWritableMetadataService remote},
* Being different to the traditional registry, {@link ServiceDiscoveryRegistry} that is a new service-oriented
* {@link Registry} based on {@link ServiceDiscovery}, it will not interact in the external registry directly,
* but store the {@link URL urls} that Dubbo services exported and referenced into {@link WritableMetadataService}
* when {@link #register(URL)} and {@link #subscribe(URL, NotifyListener)} methods are executed. After that the exported
* {@link URL urls} can be get from {@link WritableMetadataService#getExportedURLs()} and its variant methods. In contrast,
* {@link WritableMetadataService#getSubscribedURLs()} method offers the subscribed {@link URL URLs}.
* <p>
* it's decided by metadata
* subscribes from the remote proxy of {@link MetadataService}
*
* Every {@link ServiceDiscoveryRegistry} object has its own {@link ServiceDiscovery} instance that was initialized
* under {@link #ServiceDiscoveryRegistry(URL) the construction}. As the primary argument of constructor , the
* {@link URL} of connection the registry decides what the kind of ServiceDiscovery is. Generally, each
* protocol associates with a kind of {@link ServiceDiscovery}'s implementation if present, or the
* {@link FileSystemServiceDiscovery} will be the default one. Obviously, it's also allowed to extend
* {@link ServiceDiscovery} using {@link SPI the Dubbo SPI}.
* <p>
* In the {@link #subscribe(URL, NotifyListener) subscription phase}, the {@link ServiceDiscovery} instance will be used
* to discovery the {@link ServiceInstance service instances} via the {@link ServiceDiscovery#getInstances(String)}.
* However, the argument of this method requires the service name that the subscribed {@link URL} can't find, thus,
* {@link ServiceNameMapping} will help to figure out one or more services that exported correlative Dubbo services. If
* the service names can be found, the exported {@link URL URLs} will be get from the remote {@link MetadataService}
* being deployed on all {@link ServiceInstance instances} of services. The whole process runs under the
* {@link #subscribeURLs(URL, NotifyListener, String, Collection)} method. It's very expensive to invoke
* {@link MetadataService} for each {@link ServiceInstance service instance}, thus {@link ServiceDiscoveryRegistry}
* introduces a cache to optimize the calculation with "revisions". If the revisions of N
* {@link ServiceInstance service instances} are same, {@link MetadataService} is invoked just only once, and then it
* does return the exported {@link URL URLs} as a template by which others are
* {@link #cloneExportedURLs(URL, Collection) cloned}.
* <p>
* In contrast, current {@link ServiceInstance service instance} will not be registered to the registry whether any
* Dubbo service is exported or not.
* <p>
*
* @see ServiceDiscovery
* @see FailbackRegistry
* @see WritableMetadataService
* @since 2.7.4
*/
public class ServiceDiscoveryRegistry extends FailbackRegistry {
Expand Down Expand Up @@ -168,6 +188,13 @@ protected ServiceDiscovery createServiceDiscovery(URL registryURL) {
return serviceDiscovery;
}

/**
* Initialize {@link SubscribedURLsSynthesizer} instances that are
* {@link DubboServiceLoader#loadServices(Class, ClassLoader) loaded} by {@link DubboServiceLoader}
*
* @return non-null {@link List}
* @see DubboServiceLoader#loadServices(Class, ClassLoader)
*/
private List<SubscribedURLsSynthesizer> initSubscribedURLsSynthesizers() {
return loadServices(SubscribedURLsSynthesizer.class, this.getClass().getClassLoader());
}
Expand Down Expand Up @@ -338,6 +365,19 @@ private String createListenerId(URL url, ServiceInstancesChangedListener listene
return listener.getServiceName() + ":" + url.toString(VERSION_KEY, GROUP_KEY, PROTOCOL_KEY);
}

/**
* Subscribe the {@link URL URLs} that the specified service exported are
* {@link #getExportedURLs(ServiceInstance) get} from {@link MetadataService} if present, or try to
* be {@link #synthesizeSubscribedURLs(URL, Collection) synthesized} by
* the instances of {@link SubscribedURLsSynthesizer}
*
* @param subscribedURL the subscribed {@link URL url}
* @param listener {@link NotifyListener}
* @param serviceName
* @param serviceInstances
* @see #getExportedURLs(URL, Collection)
* @see #synthesizeSubscribedURLs(URL, Collection)
*/
protected void subscribeURLs(URL subscribedURL, NotifyListener listener, String serviceName,
Collection<ServiceInstance> serviceInstances) {

Expand Down Expand Up @@ -418,6 +458,17 @@ private void prepareServiceRevisionExportedURLs(List<ServiceInstance> serviceIns
* Initialize the {@link URL URLs} that {@link ServiceInstance service instances} exported into
* {@link #serviceRevisionExportedURLsCache the cache}.
* <p>
* Typically, the {@link URL URLs} that one {@link ServiceInstance service instance} exported can be get from
* the same instances' {@link MetadataService}, but the cost is very expensive if there are a lot of instances
* in this service. Thus, the exported {@link URL URls} should be cached and stored into
* {@link #serviceRevisionExportedURLsCache the cache}.
* <p>
* In most cases, {@link #serviceRevisionExportedURLsCache the cache} only holds a single list of exported URLs for
* each service because there is no difference on the Dubbo services(interfaces) between the service instances.
* However, if there are one or more upgrading or increasing Dubbo services that are deploying on the some of
* instances, other instances still maintain the previous ones, in this way, there are two versions of the services,
* they are called "revisions", in other words, one revision associates a list of exported URLs that can be reused
* for other instances with same revision, and one service allows one or more revisions.
*
* @param serviceInstances {@link ServiceInstance service instances}
*/
Expand All @@ -429,7 +480,8 @@ private void initializeRevisionExportedURLs(List<ServiceInstance> serviceInstanc
}

/**
* One {@link ServiceInstance} that will be selected in order to avoid hot spot
* Initialize the {@link URL URLs} that the {@link #selectServiceInstance(List) selected service instance} exported
* into {@link #serviceRevisionExportedURLsCache the cache}.
*
* @param serviceInstances {@link ServiceInstance service instances}
*/
Expand Down Expand Up @@ -517,10 +569,12 @@ private List<URL> cloneExportedURLs(URL subscribedURL, Collection<ServiceInstanc


/**
* Select one {@link ServiceInstance} from the {@link List list}
* Select one {@link ServiceInstance} by {@link ServiceInstanceSelector the strategy} if there are more that one
* instances in order to avoid the hot spot appearing the some instance
*
* @param serviceInstances the {@link List list} of {@link ServiceInstance}
* @return <code>null</code> if <code>serviceInstances</code> is empty.
* @see ServiceInstanceSelector
*/
private ServiceInstance selectServiceInstance(List<ServiceInstance> serviceInstances) {
int size = serviceInstances.size();
Expand Down Expand Up @@ -565,20 +619,20 @@ private List<URL> getTemplateExportedURLs(URL subscribedURL, ServiceInstance sel
/**
* Initialize the URLs that the specified {@link ServiceInstance service instance} exported
*
* @param providerServiceInstance the {@link ServiceInstance} exports the Dubbo Services
* @param serviceInstance the {@link ServiceInstance} exports the Dubbo Services
* @return the {@link URL URLs} that the {@link ServiceInstance} exported, it's calculated from
* The invocation to remote {@link MetadataService}, or get from {@link #serviceRevisionExportedURLsCache cache} if
* {@link ServiceInstanceMetadataUtils#getExportedServicesRevision(ServiceInstance) revision} is hit
*/
private List<URL> initializeRevisionExportedURLs(ServiceInstance providerServiceInstance) {
private List<URL> initializeRevisionExportedURLs(ServiceInstance serviceInstance) {

if (providerServiceInstance == null) {
if (serviceInstance == null) {
return emptyList();
}

String serviceName = providerServiceInstance.getServiceName();
String serviceName = serviceInstance.getServiceName();
// get the revision from the specified {@link ServiceInstance}
String revision = getExportedServicesRevision(providerServiceInstance);
String revision = getExportedServicesRevision(serviceInstance);

Map<String, List<URL>> revisionExportedURLsMap = getRevisionExportedURLsMap(serviceName);

Expand All @@ -592,18 +646,18 @@ private List<URL> initializeRevisionExportedURLs(ServiceInstance providerService
if (logger.isWarnEnabled()) {
logger.warn(format("The ServiceInstance[id: %s, host : %s , port : %s] has different revision : %s" +
", please make sure the service [name : %s] is changing or not.",
providerServiceInstance.getId(),
providerServiceInstance.getHost(),
providerServiceInstance.getPort(),
serviceInstance.getId(),
serviceInstance.getHost(),
serviceInstance.getPort(),
revision,
providerServiceInstance.getServiceName()
serviceInstance.getServiceName()
));
}
} else { // Else, it's the first time to get the exported URLs
firstGet = true;
}

revisionExportedURLs = getExportedURLs(providerServiceInstance);
revisionExportedURLs = getExportedURLs(serviceInstance);

if (revisionExportedURLs != null) { // just allow the valid result into exportedURLsMap

Expand All @@ -613,10 +667,10 @@ private List<URL> initializeRevisionExportedURLs(ServiceInstance providerService
logger.debug(format("Get the exported URLs[size : %s, first : %s] from the target service " +
"instance [id: %s , service : %s , host : %s , port : %s , revision : %s]",
revisionExportedURLs.size(), firstGet,
providerServiceInstance.getId(),
providerServiceInstance.getServiceName(),
providerServiceInstance.getHost(),
providerServiceInstance.getPort(),
serviceInstance.getId(),
serviceInstance.getServiceName(),
serviceInstance.getHost(),
serviceInstance.getPort(),
revision
));
}
Expand All @@ -626,10 +680,10 @@ private List<URL> initializeRevisionExportedURLs(ServiceInstance providerService
logger.debug(format("Get the exported URLs[size : %s] from cache, the instance" +
"[id: %s , service : %s , host : %s , port : %s , revision : %s]",
revisionExportedURLs.size(),
providerServiceInstance.getId(),
providerServiceInstance.getServiceName(),
providerServiceInstance.getHost(),
providerServiceInstance.getPort(),
serviceInstance.getId(),
serviceInstance.getServiceName(),
serviceInstance.getHost(),
serviceInstance.getPort(),
revision
));
}
Expand All @@ -643,26 +697,20 @@ private Map<String, List<URL>> getRevisionExportedURLsMap(String serviceName) {
}

/**
* Get all services {@link URL URLs} that the specified {@link ServiceInstance service instance} exported with cache
* <p>
* Typically, the revisions of all {@link ServiceInstance instances} in one service are same. However,
* if one service is upgrading one or more Dubbo service interfaces, one of them may have the multiple declarations
* is deploying in the different {@link ServiceInstance service instances}, thus, it has to compare the interface
* contract one by one, the "revision" that is the number is introduced to identify all Dubbo exported interfaces in
* one {@link ServiceInstance service instance}.
* Get all services {@link URL URLs} that the specified {@link ServiceInstance service instance} exported from cache
*
* @param providerServiceInstance the {@link ServiceInstance} exports the Dubbo Services
* @param serviceInstance the {@link ServiceInstance} exports the Dubbo Services
* @return the same as {@link #getExportedURLs(ServiceInstance)}
*/
private List<URL> getRevisionExportedURLs(ServiceInstance providerServiceInstance) {
private List<URL> getRevisionExportedURLs(ServiceInstance serviceInstance) {

if (providerServiceInstance == null) {
if (serviceInstance == null) {
return emptyList();
}

String serviceName = providerServiceInstance.getServiceName();
String serviceName = serviceInstance.getServiceName();
// get the revision from the specified {@link ServiceInstance}
String revision = getExportedServicesRevision(providerServiceInstance);
String revision = getExportedServicesRevision(serviceInstance);

return getRevisionExportedURLs(serviceName, revision);
}
Expand All @@ -678,7 +726,7 @@ private List<URL> getRevisionExportedURLs(String serviceName, String revision) {

/**
* Get all services {@link URL URLs} that the specified {@link ServiceInstance service instance} exported
* from {@link MetadataService} proxy
* via the proxy to invoke the {@link MetadataService}
*
* @param providerServiceInstance the {@link ServiceInstance} exported the Dubbo services
* @return The possible result :
Expand All @@ -687,6 +735,8 @@ private List<URL> getRevisionExportedURLs(String serviceName, String revision) {
* <li>The empty result if the {@link ServiceInstance service instance} did not export yet</li>
* <li><code>null</code> if there is an invocation error on {@link MetadataService} proxy</li>
* </ol>
* @see MetadataServiceProxyFactory
* @see MetadataService
*/
private List<URL> getExportedURLs(ServiceInstance providerServiceInstance) {

Expand Down

0 comments on commit e2f0983

Please sign in to comment.