From edd37e30129601454e57c4d1d349a76d92bd87da Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Tue, 27 Aug 2019 02:11:26 +0800 Subject: [PATCH] Dubbo cloud native (#4949) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Polish apache/dubbo#4542 : [Enhancement] Adapt the Java standard Event/Listener mechanism * Polish apache/dubbo#4541 : [Feature] Add local File System DynamicConfigurationFactory‘s extension * Polish apache#4541 : Bugfix * Polish apache/dubbo#4541 : Optimization * Polish apache/dubbo#4541 : Add the compatibility for PollingWatchService on the some platforms * Polish apache/dubbo#4541 : Add delay publish without ThreadPoolExecutor * Polish apache/dubbo#4541 : Refactor the extension name * Polish apache/dubbo#4541 : Add remove ops * Polish apache/dubbo#4541 : Add testable constructor * Polish apache/dubbo#4541 : Add getConfigGroups method * Polish apache/dubbo#4610 : [Refactor] Refactor the bootstrap module * Polish apache/dubbo#4541 : Fix the nulling URL issue * Polish apache/dubbo#4622 : [Refactor] Refactor ConfigManager * Polish apache/dubbo#4622 : [Refactor] Refactor ConfigManager * Polish apache/dubbo#4622 : Support multiple configcenters * Polish apache/dubbo#4671 : ServiceNameMapping will not map the group, version and protocol * update referenceCount log (#4683) Add comments to support multiple shared connections * Polish /apache/dubbo#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 apache/dubbo#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 apache/dubbo#3984 : Add the implementation of Page 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 apache/dubbo#4774 : [Feature] Dubbo Cloud Native - To Support in Spring * Polish apache/dubbo#4808 : [Feature] Add the registered/unregistered event mechanism ShutdownHook * Polish apache/dubbo#4807 : [Feature] Add the callback mechanism ShutdownHook #4807 * Polish apache/dubbo#4813 : [Feature] add Prioritized implementation for ServiceInstanceCustomizer * Polish apache/dubbo#4815 : [Feature] Add the ServiceLoader for Dubbo's services or components * Polish apache/dubbo#4815 : [Feature] Add the ServiceLoader for Dubbo's services or components * Polish apache/dubbo#4813 : [Feature] add Prioritized implementation for ServiceInstanceCustomizer * Polish apache/dubbo#4807 : Add sort implementation * Refactor * Refactor * Polish apache/dubbo#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 apache/dubbo#4854 : [Feature] MetadataService supports the Dubbo protocol under auto-increased port * Polish apache/dubbo#4857 : [Enhancement] Sync the Metadata storage type into ApplicationConfig * Polish apache/dubbo#4868 : [Enhancement] Refactor ConfigChangeEvent * Polish apache/dubbo#4868 : [Enhancement] Refactor ConfigChangeEvent * Polish apache/dubbo#4873 : [Feature] Add a conditional EventListener into Event Module * Polish apache/dubbo#4875 : [Feature] Refactor ServiceInstancesChangedListener * Remove the cycle dependencies * Remove the cycle dependencies * Polish apache/dubbo#4903 : [Feature] Set source into the BeanDefinition of Dubbo Config * Polish apache/dubbo#4902 : [Feature] Dubbo Cloud Native to Spring XML scenario * Polish apache/dubbo#4713 : Initial the new module and dependencies * Polish apache/dubbo#4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions * Polish apache/dubbo#4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions * Polish apache/dubbo#4690 : AnnotatedBeanDefinitionRegistryUtils#registerBeans can't remove the duplicated bean definitions * Polish apache/dubbo#4910 : [Feature] To suppoort DubboLifecycleComponentApplicationListener in Spring XML scenario * Polish apache/dubbo#4713 : Add Service discovery implementation for Eureka #4713 * Polish apache/dubbo#4713 : Add Service registration and discovery implementation for Eureka * Polish apache/dubbo#4713 : Add Service registration and discovery implementation for Eureka * Polish apache/dubbo#4920 : [Refactor] Extract the common implementation for URLs' revision * Refactor * Polish apache/dubbo#4925 : ServiceDiscovery limits only one ServiceInstancesChangedListener each service * Polish apache/dubbo#4925 : ServiceDiscovery limits only one ServiceInstancesChangedListener each service * Remove useless classes * Bugfix & Refactor ServiceDiscoveryRegistry * Polish apache/dubbo#4937 : The calculation of Revision should add the parameters of URL * Polish apache/dubbo#4940 : NacosDynamicConfiguration supports getConfigKeys method * Polish apache/dubbo#4942 : Dubbo Cloud Native supports multiple protcols * Polish apache/dubbo#4944 : [Feature] Simplify The metadata of URL for MetadataService * Polish apache/dubbo#4947 : [Feature] Dubbo Cloud-Native supports the REST call to Non-Dubbo --- .../NacosDubboServiceConsumerBootstrap.java | 13 +-- .../client/ServiceDiscoveryRegistry.java | 67 +++++++++++--- ...RestProtocolSubscribedURLsSynthesizer.java | 91 +++++++++++++++++++ .../metadata/SubscribedURLsSynthesizer.java | 53 +++++++++++ ....client.metadata.SubscribedURLsSynthesizer | 1 + 5 files changed, 205 insertions(+), 20 deletions(-) create mode 100644 dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RestProtocolSubscribedURLsSynthesizer.java create mode 100644 dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedURLsSynthesizer.java create mode 100644 dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.metadata.SubscribedURLsSynthesizer diff --git a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/NacosDubboServiceConsumerBootstrap.java b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/NacosDubboServiceConsumerBootstrap.java index aeb8eb78356..22a2a39c865 100644 --- a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/NacosDubboServiceConsumerBootstrap.java +++ b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/NacosDubboServiceConsumerBootstrap.java @@ -35,26 +35,21 @@ public static void main(String[] args) throws Exception { // applicationConfig.setMetadataType("remote"); new DubboBootstrap() .application(applicationConfig) - // Zookeeper - .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo")) + .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=service-provider")) .metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848")) - // Nacos -// .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1")) - .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo")) .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest")) .start() .await(); ConfigManager configManager = ConfigManager.getInstance(); - ReferenceConfig referenceConfig = configManager.getReference("echo"); + ReferenceConfig referenceConfig = configManager.getReference("user"); - EchoService echoService = referenceConfig.get(); + UserService userService = referenceConfig.get(); for (int i = 0; i < 500; i++) { Thread.sleep(2000L); - System.out.println(echoService.echo("Hello,World")); + System.out.println(userService.getUser(i * 1L)); } - } } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java index 84b5a759f90..581e388c0b2 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java @@ -31,12 +31,14 @@ import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils; +import org.apache.dubbo.registry.client.metadata.SubscribedURLsSynthesizer; import org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory; import org.apache.dubbo.registry.client.selector.ServiceInstanceSelector; import org.apache.dubbo.registry.support.FailbackRegistry; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -72,6 +74,7 @@ import static org.apache.dubbo.common.function.ThrowableAction.execute; import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty; import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty; +import static org.apache.dubbo.common.utils.DubboServiceLoader.loadServices; import static org.apache.dubbo.common.utils.StringUtils.isBlank; import static org.apache.dubbo.metadata.WritableMetadataService.DEFAULT_EXTENSION; import static org.apache.dubbo.registry.client.ServiceDiscoveryFactory.getExtension; @@ -110,6 +113,8 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry { private final Set registeredListeners = new LinkedHashSet<>(); + private final List subscribedURLsSynthesizers; + /** * A cache for all URLs of services that the subscribed services exported * The key is the service name @@ -124,6 +129,7 @@ public ServiceDiscoveryRegistry(URL registryURL) { this.serviceNameMapping = ServiceNameMapping.getDefaultExtension(); String metadataStorageType = getMetadataStorageType(registryURL); this.writableMetadataService = WritableMetadataService.getExtension(metadataStorageType); + this.subscribedURLsSynthesizers = initSubscribedURLsSynthesizers(); } /** @@ -157,6 +163,10 @@ protected ServiceDiscovery createServiceDiscovery(URL registryURL) { return serviceDiscovery; } + private List initSubscribedURLsSynthesizers() { + return loadServices(SubscribedURLsSynthesizer.class, this.getClass().getClassLoader()); + } + /** * Get the instance {@link ServiceDiscovery} from the registry {@link URL} using * {@link ServiceDiscoveryFactory} SPI @@ -331,12 +341,32 @@ protected void subscribeURLs(URL subscribedURL, NotifyListener listener, String return; } - List subscribedURLs = getSubscribedURLs(subscribedURL, serviceInstances); + List subscribedURLs = new LinkedList<>(); + + /** + * Add the exported URLs from {@link MetadataService} + */ + subscribedURLs.addAll(getExportedURLs(subscribedURL, serviceInstances)); + + if (subscribedURLs.isEmpty()) { // If empty, try to synthesize + /** + * Add the subscribed URLs that were synthesized + */ + subscribedURLs.addAll(synthesizeSubscribedURLs(subscribedURL, serviceInstances)); + } listener.notify(subscribedURLs); } - private List getSubscribedURLs(URL subscribedURL, Collection instances) { + /** + * Get the exported {@link URL URLs} from the {@link MetadataService} in the specified + * {@link ServiceInstance service instances} + * + * @param subscribedURL the subscribed {@link URL url} + * @param instances {@link ServiceInstance service instances} + * @return the exported {@link URL URLs} if present, or {@link Collections#emptyList() empty list} + */ + private List getExportedURLs(URL subscribedURL, Collection instances) { // local service instances could be mutable List serviceInstances = instances.stream() @@ -356,7 +386,7 @@ private List getSubscribedURLs(URL subscribedURL, Collection subscribedURLs = cloneSubscribedURLs(subscribedURL, serviceInstances); + List subscribedURLs = cloneExportedURLs(subscribedURL, serviceInstances); // clear local service instances serviceInstances.clear(); return subscribedURLs; @@ -368,7 +398,7 @@ private void initTemplateURLs(URL subscribedURL, List serviceIn // select a instance of {@link ServiceInstance} ServiceInstance selectedInstance = selectServiceInstance(serviceInstances); // try to get the template URLs - List templateURLs = getTemplateURLs(subscribedURL, selectedInstance); + List templateURLs = getTemplateExportedURLs(subscribedURL, selectedInstance); if (isNotEmpty(templateURLs)) { // If the result is valid break; // break the loop } else { @@ -407,19 +437,19 @@ private void expungeStaleRevisionExportedURLs(List serviceInsta } } - private List cloneSubscribedURLs(URL subscribedURL, Collection serviceInstances) { + private List cloneExportedURLs(URL subscribedURL, Collection serviceInstances) { if (isEmpty(serviceInstances)) { return emptyList(); } - List clonedURLs = new LinkedList<>(); + List clonedExportedURLs = new LinkedList<>(); serviceInstances.forEach(serviceInstance -> { String host = serviceInstance.getHost(); - getTemplateURLs(subscribedURL, serviceInstance) + getTemplateExportedURLs(subscribedURL, serviceInstance) .stream() .map(templateURL -> templateURL.removeParameter(TIMESTAMP_KEY)) .map(templateURL -> templateURL.removeParameter(PID_KEY)) @@ -437,9 +467,9 @@ private List cloneSubscribedURLs(URL subscribedURL, Collection serviceInsta } /** - * Get the template {@link URL urls} from the specified {@link ServiceInstance}. + * Get the template exported {@link URL urls} from the specified {@link ServiceInstance}. *

* First, put the revision {@link ServiceInstance service instance} * associating {@link #getExportedURLs(URL, ServiceInstance) exported URLs} into cache. @@ -478,7 +508,7 @@ private ServiceInstance selectServiceInstance(List serviceInsta * associating with the {@link URL urls} * @return non-null {@link List} of {@link URL urls} */ - protected List getTemplateURLs(URL subscribedURL, ServiceInstance selectedInstance) { + private List getTemplateExportedURLs(URL subscribedURL, ServiceInstance selectedInstance) { List exportedURLs = getRevisionExportedURLs(selectedInstance); @@ -655,6 +685,21 @@ protected List getExportedURLs(URL subscribedURL, ServiceInstance providerS return exportedURLs; } + /** + * Synthesize new subscribed {@link URL URLs} from old one + * + * @param subscribedURL + * @param serviceInstances + * @return non-null + */ + private Collection synthesizeSubscribedURLs(URL subscribedURL, Collection serviceInstances) { + return subscribedURLsSynthesizers.stream() + .filter(synthesizer -> synthesizer.supports(subscribedURL)) + .map(synthesizer -> synthesizer.synthesize(subscribedURL, serviceInstances)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + protected Set getServices(URL subscribedURL) { Set serviceNames = getSubscribedServices(); diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RestProtocolSubscribedURLsSynthesizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RestProtocolSubscribedURLsSynthesizer.java new file mode 100644 index 00000000000..e37bc4f7421 --- /dev/null +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RestProtocolSubscribedURLsSynthesizer.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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 org.apache.dubbo.registry.client.metadata; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.URLBuilder; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.registry.client.ServiceInstance; +import org.apache.dubbo.rpc.Protocol; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.lang.Boolean.TRUE; +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.SIDE_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY; +import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY; +import static org.apache.dubbo.registry.Constants.REGISTER_KEY; +import static org.apache.dubbo.rpc.Constants.LAZY_CONNECT_KEY; +import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_STICKY_KEY; + +/** + * {@link SubscribedURLsSynthesizer} implementation for REST {@link Protocol protocol} + * + * @since 2.7.4 + */ +public class RestProtocolSubscribedURLsSynthesizer implements SubscribedURLsSynthesizer { + + @Override + public boolean supports(URL subscribedURL) { + return "rest".equals(subscribedURL.getProtocol()) || + "rest".equals(subscribedURL.getParameter(PROTOCOL_KEY)); + } + + @Override + public List synthesize(URL subscribedURL, Collection serviceInstances) { + + String protocol = subscribedURL.getParameter(PROTOCOL_KEY); + + Map parametersToCopy = subscribedURL.removeParameter(CATEGORY_KEY) + .removeParameter(PROTOCOL_KEY) + .removeParameter(SIDE_KEY) + .removeParameter(CLUSTER_STICKY_KEY) + .removeParameter(TIMESTAMP_KEY) + .removeParameter(PID_KEY) + .removeParameter(LAZY_CONNECT_KEY) + .getParameters(); + + return serviceInstances.stream().map(serviceInstance -> { + URLBuilder urlBuilder = new URLBuilder() + .setProtocol(protocol) + .setHost(serviceInstance.getHost()) + .setPort(serviceInstance.getPort()) + .setPath(subscribedURL.getServiceInterface()) + .addParameter(SIDE_KEY, PROVIDER) + .addParameter(REGISTER_KEY, TRUE.toString()); + + // Copy the parameters + parametersToCopy.forEach((key, value) -> { + urlBuilder.addParameter(key, value); + }); + + return urlBuilder.build(); + }).collect(Collectors.toList()); + } + + private void addParameter(URLBuilder urlBuilder, String key, String value) { + if (StringUtils.isNotEmpty(value)) { + urlBuilder.addParameter(key, value); + } + } +} diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedURLsSynthesizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedURLsSynthesizer.java new file mode 100644 index 00000000000..1873a33c089 --- /dev/null +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedURLsSynthesizer.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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 org.apache.dubbo.registry.client.metadata; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.lang.Prioritized; +import org.apache.dubbo.registry.NotifyListener; +import org.apache.dubbo.registry.Registry; +import org.apache.dubbo.registry.client.ServiceInstance; + +import java.util.Collection; +import java.util.List; + +/** + * The inteface to synthesize the subscribed {@link URL URLs} + * + * @since 2.7.4 + */ +public interface SubscribedURLsSynthesizer extends Prioritized { + + /** + * Supports the synthesis of the subscribed {@link URL URLs} or not + * + * @param subscribedURL the original subscribed {@link URL} from the execution of` + * {@link Registry#subscribe(URL, NotifyListener)} method + * @return if supports, return true, or false + */ + boolean supports(URL subscribedURL); + + /** + * synthesize the subscribed {@link URL URLs} + * + * @param subscribedURL the original subscribed {@link URL} from the execution of` + * {@link Registry#subscribe(URL, NotifyListener)} method + * @param serviceInstances + * @return + */ + List synthesize(URL subscribedURL, Collection serviceInstances); +} diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.metadata.SubscribedURLsSynthesizer b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.metadata.SubscribedURLsSynthesizer new file mode 100644 index 00000000000..d3f79efe3f0 --- /dev/null +++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.metadata.SubscribedURLsSynthesizer @@ -0,0 +1 @@ +org.apache.dubbo.registry.client.metadata.RestProtocolSubscribedURLsSynthesizer \ No newline at end of file