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

xingfudeshi pushed a commit to branch gsoc-2025-meta-registry
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/gsoc-2025-meta-registry by 
this push:
     new 6d332d2dd3 optimize: metadata discovery support for zookeeper
6d332d2dd3 is described below

commit 6d332d2dd3f6481eab6fa7a144462a3bc27c0803
Author: YoWuwuuuw <[email protected]>
AuthorDate: Tue Nov 18 15:15:41 2025 +0800

    optimize: metadata discovery support for zookeeper
---
 .../registry/zk/ZookeeperRegisterServiceImpl.java  | 68 ++++++++++++++++++++--
 .../zk/ZookeeperRegisterServiceImplTest.java       |  8 ++-
 2 files changed, 69 insertions(+), 7 deletions(-)

diff --git 
a/discovery/seata-discovery-zk/src/main/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
 
b/discovery/seata-discovery-zk/src/main/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
index eaffdf85f4..83cc138eb0 100644
--- 
a/discovery/seata-discovery-zk/src/main/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
+++ 
b/discovery/seata-discovery-zk/src/main/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
@@ -91,6 +91,7 @@ public class ZookeeperRegisterServiceImpl implements 
RegistryService<CuratorCach
     private static final int REGISTERED_PATH_SET_SIZE = 1;
     private static final Set<String> REGISTERED_PATH_SET =
             Collections.synchronizedSet(new 
HashSet<>(REGISTERED_PATH_SET_SIZE));
+    private static final ConcurrentMap<String, String> 
REGISTERED_PATH_DATA_MAP = new ConcurrentHashMap<>();
 
     private String transactionServiceGroup;
 
@@ -113,6 +114,8 @@ public class ZookeeperRegisterServiceImpl implements 
RegistryService<CuratorCach
         NetUtil.validAddress(address);
 
         String path = getRegisterPathByPath(address);
+        String data = serializeMetadata(instance.getMetadata());
+        REGISTERED_PATH_DATA_MAP.put(path, data);
         doRegister(path);
     }
 
@@ -121,7 +124,8 @@ public class ZookeeperRegisterServiceImpl implements 
RegistryService<CuratorCach
             return false;
         }
         createParentIfNotPresent(path);
-        createEphemeral(path, Boolean.TRUE.toString());
+        String data = REGISTERED_PATH_DATA_MAP.getOrDefault(path, 
Boolean.TRUE.toString());
+        createEphemeral(path, data);
         REGISTERED_PATH_SET.add(path);
         return true;
     }
@@ -359,13 +363,23 @@ public class ZookeeperRegisterServiceImpl implements 
RegistryService<CuratorCach
             CLUSTER_INSTANCE_MAP.put(clusterName, newInstanceList);
             return;
         }
-        for (String path : instances) {
+        String basePath = ROOT_PATH + clusterName + ZK_PATH_SPLIT_CHAR;
+        for (String nodeName : instances) {
             try {
-                String[] ipAndPort = NetUtil.splitIPPortStr(path);
-                newInstanceList.add(
-                        new ServiceInstance(new 
InetSocketAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1]))));
+                String[] ipAndPort = NetUtil.splitIPPortStr(nodeName);
+                InetSocketAddress address = new 
InetSocketAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
+                byte[] dataBytes = null;
+                try {
+                    dataBytes = getClientInstance().getData().forPath(basePath 
+ nodeName);
+                } catch (Exception ignored) {
+                }
+                Map<String, String> metadata = parseMetadata(dataBytes);
+                ServiceInstance serviceInstance = metadata == null
+                        ? new ServiceInstance(address)
+                        : ServiceInstance.fromStringMap(address, metadata);
+                newInstanceList.add(serviceInstance);
             } catch (Exception e) {
-                LOGGER.warn("The cluster instance info is error, instance 
info:{}", path);
+                LOGGER.warn("The cluster instance info is error, instance 
info:{}", nodeName);
             }
         }
         CLUSTER_INSTANCE_MAP.put(clusterName, newInstanceList);
@@ -373,6 +387,48 @@ public class ZookeeperRegisterServiceImpl implements 
RegistryService<CuratorCach
         removeOfflineAddressesIfNecessary(transactionServiceGroup, 
clusterName, newInstanceList);
     }
 
+    private String serializeMetadata(Map<String, Object> metadata) {
+        if (metadata == null || metadata.isEmpty()) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, Object> entry : metadata.entrySet()) {
+            String key = entry.getKey() == null ? "" : entry.getKey();
+            String value = entry.getValue() == null ? "" : 
String.valueOf(entry.getValue());
+            // simple line-based format: key=value\n
+            sb.append(key.replace("\n", " "))
+                    .append("=")
+                    .append(value.replace("\n", " "))
+                    .append("\n");
+        }
+        return sb.toString();
+    }
+
+    private Map<String, String> parseMetadata(byte[] dataBytes) {
+        if (dataBytes == null || dataBytes.length == 0) {
+            return null;
+        }
+        String data = new String(dataBytes, CHARSET);
+        if (StringUtils.isBlank(data)) {
+            return null;
+        }
+        Map<String, String> map = new HashMap<>();
+        String[] lines = data.split("\n");
+        for (String line : lines) {
+            if (StringUtils.isBlank(line)) {
+                continue;
+            }
+            int idx = line.indexOf('=');
+            if (idx <= 0) {
+                continue;
+            }
+            String k = line.substring(0, idx);
+            String v = line.substring(idx + 1);
+            map.put(k, v);
+        }
+        return map.isEmpty() ? null : map;
+    }
+
     private String getClusterName() {
         String clusterConfigName =
                 String.join(FILE_CONFIG_SPLIT_CHAR, FILE_ROOT_REGISTRY, 
REGISTRY_TYPE, REGISTRY_CLUSTER);
diff --git 
a/discovery/seata-discovery-zk/src/test/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImplTest.java
 
b/discovery/seata-discovery-zk/src/test/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImplTest.java
index 8ccea8ec3c..e9ef3052ae 100644
--- 
a/discovery/seata-discovery-zk/src/test/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImplTest.java
+++ 
b/discovery/seata-discovery-zk/src/test/java/org/apache/seata/discovery/registry/zk/ZookeeperRegisterServiceImplTest.java
@@ -79,7 +79,10 @@ public class ZookeeperRegisterServiceImplTest {
 
     @Test
     public void testAll() throws Exception {
-        service.register(new ServiceInstance(new 
InetSocketAddress(NetUtil.getLocalAddress(), 33333)));
+        Map<String, Object> meta = new HashMap<>();
+        meta.put("zone", "A");
+        meta.put("version", "v1");
+        service.register(new ServiceInstance(new 
InetSocketAddress(NetUtil.getLocalAddress(), 33333), meta));
 
         Assertions.assertThrows(ConfigNotFoundException.class, new 
Executable() {
             @Override
@@ -89,6 +92,9 @@ public class ZookeeperRegisterServiceImplTest {
         });
         List<ServiceInstance> lookup2 = service.doLookup("default");
         Assertions.assertEquals(1, lookup2.size());
+        Assertions.assertNotNull(lookup2.get(0).getMetadata());
+        Assertions.assertEquals("A", lookup2.get(0).getMetadata().get("zone"));
+        Assertions.assertEquals("v1", 
lookup2.get(0).getMetadata().get("version"));
 
         final List<String> data = new ArrayList<>();
         final CountDownLatch latch = new CountDownLatch(1);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to