This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.2 by this push:
     new be15772ec3 feat: multiple支持 service discovery模式 (#13137)
be15772ec3 is described below

commit be15772ec37ee6a3453ad7be155f9cfb1ed9ee1f
Author: zhengkaifor <[email protected]>
AuthorDate: Fri Oct 20 15:42:41 2023 +0800

    feat: multiple支持 service discovery模式 (#13137)
    
    * feat: multiple支持 service discovery模式
    
    * feat: 去除无用代码
    
    * feat: review问题修改
    
    * feat: Translate into english
    
    * feat:还原无用改动
    
    * feat:还原无用改动
    
    ---------
    
    Co-authored-by: Albumen Kevin <[email protected]>
---
 .../multiple/MultipleServiceDiscovery.java         |  39 +++++--
 .../multiple/MultipleServiceDiscoveryTest.java     | 119 +++++++++++++++++++++
 2 files changed, 147 insertions(+), 11 deletions(-)

diff --git 
a/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
 
b/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
index fcb6a168ea..d675b74cce 100644
--- 
a/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
+++ 
b/dubbo-registry/dubbo-registry-multiple/src/main/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscovery.java
@@ -16,15 +16,6 @@
  */
 package org.apache.dubbo.registry.multiple;
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Function;
-
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
@@ -36,6 +27,16 @@ import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
 import 
org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
 public class MultipleServiceDiscovery implements ServiceDiscovery {
     public static final String REGISTRY_PREFIX_KEY = "child.";
     private static final String REGISTRY_TYPE = "registry-type";
@@ -141,7 +142,15 @@ public class MultipleServiceDiscovery implements 
ServiceDiscovery {
 
     @Override
     public MetadataInfo getLocalMetadata(String revision) {
-        throw new UnsupportedOperationException("Multiple registry 
implementation does not support getLocalMetadata() method.");
+        MetadataInfo metadataInfo = MetadataInfo.EMPTY;
+        for (ServiceDiscovery serviceDiscovery : serviceDiscoveries.values()) {
+            MetadataInfo remoteMetadata = 
serviceDiscovery.getLocalMetadata(revision);
+            if (!Objects.equals(MetadataInfo.EMPTY, remoteMetadata)) {
+                metadataInfo = remoteMetadata;
+                break;
+            }
+        }
+        return metadataInfo;
     }
 
     @Override
@@ -151,7 +160,15 @@ public class MultipleServiceDiscovery implements 
ServiceDiscovery {
 
     @Override
     public MetadataInfo getRemoteMetadata(String revision, 
List<ServiceInstance> instances) {
-        throw new UnsupportedOperationException("Multiple registry 
implementation does not support getMetadata() method.");
+        MetadataInfo metadataInfo = MetadataInfo.EMPTY;
+        for (ServiceDiscovery serviceDiscovery : serviceDiscoveries.values()) {
+            MetadataInfo remoteMetadata = 
serviceDiscovery.getRemoteMetadata(revision, instances);
+            if (!Objects.equals(MetadataInfo.EMPTY, remoteMetadata)) {
+                metadataInfo = remoteMetadata;
+                break;
+            }
+        }
+        return metadataInfo;
     }
 
     @Override
diff --git 
a/dubbo-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryTest.java
 
b/dubbo-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryTest.java
new file mode 100644
index 0000000000..9d0786a77b
--- /dev/null
+++ 
b/dubbo-registry/dubbo-registry-multiple/src/test/java/org/apache/dubbo/registry/multiple/MultipleServiceDiscoveryTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.multiple;
+
+import com.google.common.collect.Sets;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.Assert;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.metadata.MetadataInfo;
+import org.apache.dubbo.registry.client.DefaultServiceInstance;
+import org.apache.dubbo.registry.client.ServiceDiscovery;
+import org.apache.dubbo.registry.client.ServiceInstance;
+import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
+import 
org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
+import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
+
+/**
+ * MultipleServiceDiscoveryTest
+ */
+public class MultipleServiceDiscoveryTest {
+
+    private static String zookeeperConnectionAddress1, 
zookeeperConnectionAddress2;
+
+    @Test
+    public void testOnEvent() {
+        try {
+            String metadata_111 = 
"{\"app\":\"app1\",\"revision\":\"111\",\"services\":{"
+                + 
"\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",
 [...]
+                + "}}";
+            MetadataInfo metadataInfo = JsonUtils.toJavaObject(metadata_111, 
MetadataInfo.class);
+            ApplicationModel applicationModel = 
ApplicationModel.defaultModel();
+            applicationModel.getApplicationConfigManager().setApplication(new 
ApplicationConfig("app2"));
+            zookeeperConnectionAddress1 = 
"multiple://127.0.0.1:2181?reference-registry=127.0.0.1:2181?enableEmptyProtection=false&child.a1=zookeeper://127.0.0.1:2181";
+            List<Object> urlsSameRevision = new ArrayList<>();
+            urlsSameRevision.add("127.0.0.1:20880?revision=111");
+            urlsSameRevision.add("127.0.0.2:20880?revision=111");
+            urlsSameRevision.add("127.0.0.3:20880?revision=111");
+            URL url = URL.valueOf(zookeeperConnectionAddress1);
+            url.setScopeModel(applicationModel);
+            MultipleServiceDiscovery multipleServiceDiscovery = new 
MultipleServiceDiscovery(url);
+            Class<MultipleServiceDiscovery> multipleServiceDiscoveryClass = 
MultipleServiceDiscovery.class;
+            Field serviceDiscoveries = 
multipleServiceDiscoveryClass.getDeclaredField("serviceDiscoveries");
+            serviceDiscoveries.setAccessible(true);
+            ServiceDiscovery serviceDiscoveryMock = 
Mockito.mock(ServiceDiscovery.class);
+            
Mockito.when(serviceDiscoveryMock.getRemoteMetadata(Mockito.anyString(), 
Mockito.anyList())).thenReturn(metadataInfo);
+            serviceDiscoveries.set(multipleServiceDiscovery, 
Collections.singletonMap("child.a1", serviceDiscoveryMock));
+            MultipleServiceDiscovery.MultiServiceInstancesChangedListener 
listener = (MultipleServiceDiscovery.MultiServiceInstancesChangedListener) 
multipleServiceDiscovery.createListener(Sets.newHashSet("app1"));
+            
multipleServiceDiscovery.addServiceInstancesChangedListener(listener);
+            MultipleServiceDiscovery.SingleServiceInstancesChangedListener 
singleServiceInstancesChangedListener = 
listener.getAndComputeIfAbsent("child.a1", (a1) -> null);
+            Assert.notNull(singleServiceInstancesChangedListener, 
"singleServiceInstancesChangedListener can not be null");
+            singleServiceInstancesChangedListener.onEvent(new 
ServiceInstancesChangedEvent("app1", buildInstances(urlsSameRevision)));
+            Mockito.verify(serviceDiscoveryMock, 
Mockito.times(1)).getRemoteMetadata(Mockito.anyString(), Mockito.anyList());
+            Field serviceUrlsField = 
ServiceInstancesChangedListener.class.getDeclaredField("serviceUrls");
+            serviceUrlsField.setAccessible(true);
+            Map<String, 
List<ServiceInstancesChangedListener.ProtocolServiceKeyWithUrls>> map= 
(Map<String, List<ServiceInstancesChangedListener.ProtocolServiceKeyWithUrls>>) 
serviceUrlsField.get(listener);
+            Assert.assertTrue(!CollectionUtils.isEmptyMap(map),"url can not be 
empty");
+        } catch (NoSuchFieldException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static List<ServiceInstance> buildInstances(List<Object> rawURls) {
+        List<ServiceInstance> instances = new ArrayList<>();
+
+        for (Object obj : rawURls) {
+            String rawURL = (String) obj;
+            DefaultServiceInstance instance = new DefaultServiceInstance();
+            final URL dubboUrl = URL.valueOf(rawURL);
+            instance.setRawAddress(rawURL);
+            instance.setHost(dubboUrl.getHost());
+            instance.setEnabled(true);
+            instance.setHealthy(true);
+            instance.setPort(dubboUrl.getPort());
+            instance.setRegistryCluster("default");
+            instance.setApplicationModel(ApplicationModel.defaultModel());
+
+            Map<String, String> metadata = new HashMap<>();
+            if (StringUtils.isNotEmpty(dubboUrl.getParameter(REVISION_KEY))) {
+                metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, 
dubboUrl.getParameter(REVISION_KEY));
+            }
+            instance.setMetadata(metadata);
+
+            instances.add(instance);
+        }
+
+        return instances;
+    }
+}

Reply via email to