Use gRPC naming scheme for name server address (#408)

* Use gRPC naming scheme for name server address

* Pin bazel version to LTS 4.2.0
diff --git a/.bazelversion b/.bazelversion
new file mode 100644
index 0000000..6aba2b2
--- /dev/null
+++ b/.bazelversion
@@ -0,0 +1 @@
+4.2.0
diff --git a/example/rocketmq/ExampleProducer.cpp b/example/rocketmq/ExampleProducer.cpp
index 2fda81f..3e1cfc5 100644
--- a/example/rocketmq/ExampleProducer.cpp
+++ b/example/rocketmq/ExampleProducer.cpp
@@ -51,7 +51,7 @@
   DefaultMQProducer producer("TestGroup");
 
   const char* topic = "cpp_sdk_standard";
-  const char* name_server = "121.43.42.193:80";
+  const char* name_server = "mq-inst-1080056302921134-bxuibml7.mq.cn-hangzhou.aliyuncs.com:80";
 
   producer.setNamesrvAddr(name_server);
   producer.compressBodyThreshold(256);
diff --git a/example/rocketmq/ExamplePushConsumer.cpp b/example/rocketmq/ExamplePushConsumer.cpp
index 8a2e9a6..d45e52a 100644
--- a/example/rocketmq/ExamplePushConsumer.cpp
+++ b/example/rocketmq/ExamplePushConsumer.cpp
@@ -49,11 +49,12 @@
   const char* group_id = "GID_cpp_sdk_standard";
   const char* topic = "cpp_sdk_standard";
   const char* resource_namespace = "MQ_INST_1080056302921134_BXuIbML7";
+  const char* name_server = "mq-inst-1080056302921134-bxuibml7.mq.cn-hangzhou.aliyuncs.com:80";
 
   DefaultMQPushConsumer push_consumer(group_id);
   push_consumer.setResourceNamespace(resource_namespace);
   push_consumer.setCredentialsProvider(std::make_shared<ConfigFileCredentialsProvider>());
-  push_consumer.setNamesrvAddr("121.43.42.193:80");
+  push_consumer.setNamesrvAddr(name_server);
   MessageListener* listener = new SampleMQMessageListener;
   push_consumer.setInstanceName("instance_0");
   push_consumer.subscribe(topic, "*");
diff --git a/src/main/cpp/client/ClientManagerImpl.cpp b/src/main/cpp/client/ClientManagerImpl.cpp
index db77dc8..d8a43e5 100644
--- a/src/main/cpp/client/ClientManagerImpl.cpp
+++ b/src/main/cpp/client/ClientManagerImpl.cpp
@@ -590,7 +590,8 @@
 void ClientManagerImpl::resolveRoute(const std::string& target_host, const Metadata& metadata,
                                      const QueryRouteRequest& request, std::chrono::milliseconds timeout,
                                      const std::function<void(const std::error_code&, const TopicRouteDataPtr&)>& cb) {
-
+  SPDLOG_DEBUG("Name server connection URL: {}", target_host);
+  SPDLOG_DEBUG("Query route request: {}", request.DebugString());
   RpcClientSharedPtr client = getRpcClient(target_host, false);
   if (!client) {
     SPDLOG_WARN("Failed to create RPC client for name server[host={}]", target_host);
diff --git a/src/main/cpp/rocketmq/ClientImpl.cpp b/src/main/cpp/rocketmq/ClientImpl.cpp
index 0d22e95..9602969 100644
--- a/src/main/cpp/rocketmq/ClientImpl.cpp
+++ b/src/main/cpp/rocketmq/ClientImpl.cpp
@@ -38,6 +38,7 @@
 #include "InvocationContext.h"
 #include "LoggerImpl.h"
 #include "MessageAccessor.h"
+#include "NamingScheme.h"
 #include "Signature.h"
 #include "rocketmq/MQMessageExt.h"
 #include "rocketmq/MessageListener.h"
@@ -160,7 +161,24 @@
 void ClientImpl::setAccessPoint(rmq::Endpoints* endpoints) {
   std::vector<std::pair<std::string, std::uint16_t>> pairs;
   {
-    std::vector<std::string> name_server_list = name_server_resolver_->resolve();
+    std::string naming_address = name_server_resolver_->resolve();
+    absl::string_view host_port_csv;
+
+    if (absl::StartsWith(naming_address, NamingScheme::DnsPrefix)) {
+      endpoints->set_scheme(rmq::AddressScheme::DOMAIN_NAME);
+      host_port_csv = absl::StripPrefix(naming_address, NamingScheme::DnsPrefix);
+    } else if (absl::StartsWith(naming_address, NamingScheme::IPv4Prefix)) {
+      endpoints->set_scheme(rmq::AddressScheme::IPv4);
+      host_port_csv = absl::StripPrefix(naming_address, NamingScheme::IPv4Prefix);
+    } else if (absl::StartsWith(naming_address, NamingScheme::IPv6Prefix)) {
+      endpoints->set_scheme(rmq::AddressScheme::IPv6);
+      host_port_csv = absl::StripPrefix(naming_address, NamingScheme::IPv6Prefix);
+    } else {
+      SPDLOG_WARN("Unsupported naming scheme");
+    }
+
+    std::vector<std::string> name_server_list = absl::StrSplit(host_port_csv, ',');
+
     for (const auto& name_server_item : name_server_list) {
       std::string::size_type pos = name_server_item.rfind(':');
       if (std::string::npos == pos) {
@@ -179,20 +197,12 @@
       address->set_host(host_port.first);
       endpoints->mutable_addresses()->AddAllocated(address);
     }
-
-    if (MixAll::isIPv4(pairs.begin()->first)) {
-      endpoints->set_scheme(rmq::AddressScheme::IPv4);
-    } else if (absl::StrContains(pairs.begin()->first, ':')) {
-      endpoints->set_scheme(rmq::AddressScheme::IPv6);
-    } else {
-      endpoints->set_scheme(rmq::AddressScheme::DOMAIN_NAME);
-    }
   }
 }
 
 void ClientImpl::fetchRouteFor(const std::string& topic,
                                const std::function<void(const std::error_code&, const TopicRouteDataPtr&)>& cb) {
-  std::string name_server = name_server_resolver_->current();
+  std::string name_server = name_server_resolver_->resolve();
   if (name_server.empty()) {
     SPDLOG_WARN("No name server available");
     return;
@@ -201,7 +211,7 @@
   auto callback = [this, topic, name_server, cb](const std::error_code& ec, const TopicRouteDataPtr& route) {
     if (ec) {
       SPDLOG_WARN("Failed to resolve route for topic={} from {}", topic, name_server);
-      std::string name_server_changed = name_server_resolver_->next();
+      std::string name_server_changed = name_server_resolver_->resolve();
       if (!name_server_changed.empty()) {
         SPDLOG_INFO("Change current name server from {} to {}", name_server, name_server_changed);
       }
diff --git a/src/main/cpp/rocketmq/DynamicNameServerResolver.cpp b/src/main/cpp/rocketmq/DynamicNameServerResolver.cpp
index b1a9614..f9981bc 100644
--- a/src/main/cpp/rocketmq/DynamicNameServerResolver.cpp
+++ b/src/main/cpp/rocketmq/DynamicNameServerResolver.cpp
@@ -23,8 +23,8 @@
 #include <memory>
 
 #include "absl/strings/str_join.h"
-#include "spdlog/spdlog.h"
 
+#include "LoggerImpl.h"
 #include "SchedulerImpl.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
@@ -69,7 +69,7 @@
                                                      std::string(remains.data(), remains.length()));
 }
 
-std::vector<std::string> DynamicNameServerResolver::resolve() {
+std::string DynamicNameServerResolver::resolve() {
   bool fetch_immediately = false;
   {
     absl::MutexLock lk(&name_server_list_mtx_);
@@ -84,7 +84,7 @@
 
   {
     absl::MutexLock lk(&name_server_list_mtx_);
-    return name_server_list_;
+    return naming_scheme_.buildAddress(name_server_list_);
   }
 }
 
@@ -126,19 +126,4 @@
   scheduler_->shutdown();
 }
 
-std::string DynamicNameServerResolver::current() {
-  absl::MutexLock lk(&name_server_list_mtx_);
-  if (name_server_list_.empty()) {
-    return std::string();
-  }
-
-  std::uint32_t index = index_.load(std::memory_order_relaxed) % name_server_list_.size();
-  return name_server_list_[index];
-}
-
-std::string DynamicNameServerResolver::next() {
-  index_.fetch_add(1, std::memory_order_relaxed);
-  return current();
-}
-
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/NamingScheme.cpp b/src/main/cpp/rocketmq/NamingScheme.cpp
new file mode 100644
index 0000000..4646af9
--- /dev/null
+++ b/src/main/cpp/rocketmq/NamingScheme.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+#include "NamingScheme.h"
+
+#include <cstdint>
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/numbers.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/str_split.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+const char* NamingScheme::DnsPrefix = "dns:";
+const char* NamingScheme::IPv4Prefix = "ipv4:";
+const char* NamingScheme::IPv6Prefix = "ipv6:";
+
+const char* NamingScheme::IPv4Regex =
+    "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])";
+
+const char* NamingScheme::IPv6Regex = "((([0-9a-fA-F]){1,4})\\:){7}([0-9a-fA-F]){1,4}";
+
+NamingScheme::NamingScheme() : ipv4_pattern_(IPv4Regex), ipv6_pattern_(IPv6Regex) {
+}
+
+std::string NamingScheme::buildAddress(const std::vector<std::string>& list) {
+  absl::flat_hash_map<std::string, std::uint32_t> ipv4;
+  absl::flat_hash_map<std::string, std::uint32_t> ipv6;
+
+  for (const auto& segment : list) {
+    std::vector<std::string> host_port = absl::StrSplit(segment, ':');
+    if (2 != host_port.size()) {
+      continue;
+    }
+
+    if (re2::RE2::FullMatch(host_port[0], ipv4_pattern_)) {
+      std::uint32_t port;
+      if (absl::SimpleAtoi(host_port[1], &port)) {
+        ipv4.insert_or_assign(host_port[0], port);
+      }
+      continue;
+    }
+
+    if (re2::RE2::FullMatch(host_port[0], ipv6_pattern_)) {
+      std::uint32_t port;
+      if (absl::SimpleAtoi(host_port[1], &port)) {
+        ipv6.insert_or_assign(host_port[0], port);
+      }
+      continue;
+    }
+
+    // Once we find a domain name record, use it as the final result.
+    host_port.insert(host_port.begin(), "dns");
+    return absl::StrJoin(host_port, ":");
+  }
+
+  if (!ipv4.empty()) {
+    return "ipv4:" + absl::StrJoin(ipv4, ",", absl::PairFormatter(":"));
+  }
+
+  if (!ipv6.empty()) {
+    return "ipv6:" + absl::StrJoin(ipv4, ",", absl::PairFormatter(":"));
+  }
+  return std::string();
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/StaticNameServerResolver.cpp b/src/main/cpp/rocketmq/StaticNameServerResolver.cpp
index 85e865f..c7f0804 100644
--- a/src/main/cpp/rocketmq/StaticNameServerResolver.cpp
+++ b/src/main/cpp/rocketmq/StaticNameServerResolver.cpp
@@ -17,27 +17,22 @@
 #include "StaticNameServerResolver.h"
 
 #include "absl/strings/str_split.h"
-#include <atomic>
-#include <cstdint>
+
+#include "LoggerImpl.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
-StaticNameServerResolver::StaticNameServerResolver(absl::string_view name_server_list)
-    : name_server_list_(absl::StrSplit(name_server_list, ';')) {
+StaticNameServerResolver::StaticNameServerResolver(absl::string_view name_server_list) {
+  std::vector<std::string> segments = absl::StrSplit(name_server_list, ';');
+  name_server_address_ = naming_scheme_.buildAddress(segments);
+  if (name_server_address_.empty()) {
+    SPDLOG_WARN("Failed to create gRPC naming scheme compliant address from {}",
+                std::string(name_server_list.data(), name_server_list.length()));
+  }
 }
 
-std::string StaticNameServerResolver::current() {
-  std::uint32_t index = index_.load(std::memory_order_relaxed) % name_server_list_.size();
-  return name_server_list_[index];
-}
-
-std::string StaticNameServerResolver::next() {
-  index_.fetch_add(1, std::memory_order_relaxed);
-  return current();
-}
-
-std::vector<std::string> StaticNameServerResolver::resolve() {
-  return name_server_list_;
+std::string StaticNameServerResolver::resolve() {
+  return name_server_address_;
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/include/DynamicNameServerResolver.h b/src/main/cpp/rocketmq/include/DynamicNameServerResolver.h
index bac08bf..5bc2c53 100644
--- a/src/main/cpp/rocketmq/include/DynamicNameServerResolver.h
+++ b/src/main/cpp/rocketmq/include/DynamicNameServerResolver.h
@@ -30,6 +30,7 @@
 #include "absl/synchronization/mutex.h"
 
 #include "NameServerResolver.h"
+#include "NamingScheme.h"
 #include "Scheduler.h"
 #include "TopAddressing.h"
 
@@ -44,11 +45,7 @@
 
   void shutdown() override;
 
-  std::string current() override LOCKS_EXCLUDED(name_server_list_mtx_);
-
-  std::string next() override LOCKS_EXCLUDED(name_server_list_mtx_);
-
-  std::vector<std::string> resolve() override LOCKS_EXCLUDED(name_server_list_mtx_);
+  std::string resolve() override LOCKS_EXCLUDED(name_server_list_mtx_);
 
   void injectHttpClient(std::unique_ptr<HttpClient> http_client);
 
@@ -69,6 +66,8 @@
 
   bool ssl_{false};
   std::unique_ptr<TopAddressing> top_addressing_;
+
+  NamingScheme naming_scheme_;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/include/NameServerResolver.h b/src/main/cpp/rocketmq/include/NameServerResolver.h
index 443f360..00ec0d9 100644
--- a/src/main/cpp/rocketmq/include/NameServerResolver.h
+++ b/src/main/cpp/rocketmq/include/NameServerResolver.h
@@ -31,11 +31,7 @@
 
   virtual void shutdown() = 0;
 
-  virtual std::string next() = 0;
-
-  virtual std::string current() = 0;
-
-  virtual std::vector<std::string> resolve() = 0;
+  virtual std::string resolve() = 0;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/include/NamingScheme.h b/src/main/cpp/rocketmq/include/NamingScheme.h
new file mode 100644
index 0000000..d9b4f62
--- /dev/null
+++ b/src/main/cpp/rocketmq/include/NamingScheme.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "re2/re2.h"
+
+#include "rocketmq/RocketMQ.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class NamingScheme {
+public:
+  NamingScheme();
+
+  std::string buildAddress(const std::vector<std::string>& list);
+
+  static const char* DnsPrefix;
+  static const char* IPv4Prefix;
+  static const char* IPv6Prefix;
+
+private:
+  static const char* IPv4Regex;
+  static const char* IPv6Regex;
+
+  re2::RE2 ipv4_pattern_;
+  re2::RE2 ipv6_pattern_;
+};
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/include/StaticNameServerResolver.h b/src/main/cpp/rocketmq/include/StaticNameServerResolver.h
index 2648b4a..b38a86e 100644
--- a/src/main/cpp/rocketmq/include/StaticNameServerResolver.h
+++ b/src/main/cpp/rocketmq/include/StaticNameServerResolver.h
@@ -16,14 +16,10 @@
  */
 #pragma once
 
-#include <atomic>
-#include <cstdint>
-#include <vector>
-
 #include "absl/strings/string_view.h"
 
 #include "NameServerResolver.h"
-#include "rocketmq/RocketMQ.h"
+#include "NamingScheme.h"
 
 ROCKETMQ_NAMESPACE_BEGIN
 
@@ -37,15 +33,21 @@
   void shutdown() override {
   }
 
-  std::string current() override;
-
-  std::string next() override;
-
-  std::vector<std::string> resolve() override;
+  std::string resolve() override;
 
 private:
-  std::vector<std::string> name_server_list_;
-  std::atomic<std::uint32_t> index_{0};
+  /**
+   * @brief Name server addresses, following gRPC URI schemes described in
+   * https://github.com/grpc/grpc/blob/master/doc/naming.md
+   *
+   * Sample values are:
+   * dns:[//authority/]host[:port]
+   * ipv4:address[:port][,address[:port],...]
+   * ipv6:address[:port][,address[:port],...]
+   */
+  std::string name_server_address_;
+
+  NamingScheme naming_scheme_;
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/main/cpp/rocketmq/mocks/include/NameServerResolverMock.h b/src/main/cpp/rocketmq/mocks/include/NameServerResolverMock.h
index f572a04..4f8f7f3 100644
--- a/src/main/cpp/rocketmq/mocks/include/NameServerResolverMock.h
+++ b/src/main/cpp/rocketmq/mocks/include/NameServerResolverMock.h
@@ -27,11 +27,7 @@
 
   MOCK_METHOD(void, shutdown, (), (override));
 
-  MOCK_METHOD(std::string, next, (), (override));
-
-  MOCK_METHOD(std::string, current, (), (override));
-
-  MOCK_METHOD((std::vector<std::string>), resolve, (), (override));
+  MOCK_METHOD(std::string, resolve, (), (override));
 };
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/test/cpp/ut/rocketmq/BUILD.bazel b/src/test/cpp/ut/rocketmq/BUILD.bazel
index 0fcfa1b..205cee1 100644
--- a/src/test/cpp/ut/rocketmq/BUILD.bazel
+++ b/src/test/cpp/ut/rocketmq/BUILD.bazel
@@ -250,4 +250,15 @@
         "//src/main/cpp/rocketmq:rocketmq_library",
         "@com_google_googletest//:gtest_main",
     ],
+)
+
+cc_test(
+    name = "naming_scheme_test",
+    srcs = [
+        "NamingSchemeTest.cpp",
+    ],
+    deps = [
+        "//src/main/cpp/rocketmq:rocketmq_library",
+        "@com_google_googletest//:gtest_main",
+    ],
 )
\ No newline at end of file
diff --git a/src/test/cpp/ut/rocketmq/DynamicNameServerResolverTest.cpp b/src/test/cpp/ut/rocketmq/DynamicNameServerResolverTest.cpp
index f296f93..a693fd6 100644
--- a/src/test/cpp/ut/rocketmq/DynamicNameServerResolverTest.cpp
+++ b/src/test/cpp/ut/rocketmq/DynamicNameServerResolverTest.cpp
@@ -19,12 +19,14 @@
 #include <chrono>
 #include <map>
 #include <memory>
+#include <string>
 
 #include "absl/memory/memory.h"
 #include "absl/strings/str_join.h"
+#include "absl/strings/str_replace.h"
+#include "absl/strings/str_split.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include <string>
 
 #include "HttpClientMock.h"
 
@@ -66,15 +68,8 @@
 
 TEST_F(DynamicNameServerResolverTest, testResolve) {
   auto name_server_list = resolver_->resolve();
-  ASSERT_FALSE(name_server_list.empty());
-  std::string resolved = absl::StrJoin(name_server_list, ";");
-  ASSERT_EQ(name_server_list_, resolved);
-
-  std::string first{"10.0.0.0:9876"};
-  EXPECT_EQ(first, resolver_->current());
-
-  std::string second{"10.0.0.1:9876"};
-  EXPECT_EQ(second, resolver_->next());
+  std::string result = absl::StrReplaceAll(name_server_list_, {std::pair<std::string, std::string>(";", ",")});
+  ASSERT_EQ(name_server_list, "ipv4:" + result);
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/test/cpp/ut/rocketmq/NamingSchemeTest.cpp b/src/test/cpp/ut/rocketmq/NamingSchemeTest.cpp
new file mode 100644
index 0000000..336f702
--- /dev/null
+++ b/src/test/cpp/ut/rocketmq/NamingSchemeTest.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#include "NamingScheme.h"
+#include "rocketmq/RocketMQ.h"
+
+#include "gtest/gtest.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class NamingSchemeTest : public testing::Test {
+public:
+  void SetUp() override {
+  }
+
+  void TearDown() override {
+  }
+
+protected:
+  NamingScheme naming_scheme_;
+};
+
+TEST_F(NamingSchemeTest, testBuildAddress) {
+  std::string address = "www.baidu.com:80";
+  std::string result = naming_scheme_.buildAddress({address});
+  ASSERT_EQ("dns:www.baidu.com:80", result);
+
+  address = "8.8.8.8:1234";
+  result = naming_scheme_.buildAddress({address});
+  ASSERT_EQ("ipv4:8.8.8.8:1234", result);
+
+  result = naming_scheme_.buildAddress({address, "4.4.4.4:1234"});
+  ASSERT_EQ("ipv4:8.8.8.8:1234,4.4.4.4:1234", result);
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/src/test/cpp/ut/rocketmq/StaticNameServerResolverTest.cpp b/src/test/cpp/ut/rocketmq/StaticNameServerResolverTest.cpp
index cf16502..0bca7e4 100644
--- a/src/test/cpp/ut/rocketmq/StaticNameServerResolverTest.cpp
+++ b/src/test/cpp/ut/rocketmq/StaticNameServerResolverTest.cpp
@@ -16,6 +16,7 @@
  */
 #include "StaticNameServerResolver.h"
 
+#include "absl/strings/str_replace.h"
 #include "absl/strings/str_split.h"
 
 #include "gtest/gtest.h"
@@ -42,18 +43,9 @@
 };
 
 TEST_F(StaticNameServerResolverTest, testResolve) {
-  std::vector<std::string> segments = absl::StrSplit(name_server_list_, ';');
-  ASSERT_EQ(segments, resolver_.resolve());
-}
-
-TEST_F(StaticNameServerResolverTest, testCurrentNext) {
-  std::string&& name_server_1 = resolver_.current();
-  std::string expected = "10.0.0.1:9876";
-  EXPECT_EQ(expected, name_server_1);
-
-  expected = "10.0.0.2:9876";
-  std::string&& name_server_2 = resolver_.next();
-  EXPECT_EQ(expected, name_server_2);
+  std::string result =
+      "ipv4:" + absl::StrReplaceAll(name_server_list_, {std::pair<std::string, std::string>(";", ",")});
+  ASSERT_EQ(result, resolver_.resolve());
 }
 
 ROCKETMQ_NAMESPACE_END
\ No newline at end of file