Merge pull request #552 from vearne/feat/resolver

Feat/resolver

> ok xujianhai666 <notifications@github.com> 于2020年11月26日周四 下午2:21写道:
> […](#)
> fmt before pr agian. @vearne <https://github.com/vearne> — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <[#552 (comment)](https://github.com/apache/rocketmq-client-go/pull/552#issuecomment-734099572)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AB6GYNDWZ5FBOPX4OPLEXSTSRXXW7ANCNFSM4TMFX72A> .

format pr info, refer by "https://github.com/apache/rocketmq/wiki/RIP-14-RocketMQ-Community-Operation-Conventions", we will merge ur pr after change.  
diff --git a/primitive/nsresolver.go b/primitive/nsresolver.go
index d844373..a0ab830 100644
--- a/primitive/nsresolver.go
+++ b/primitive/nsresolver.go
@@ -19,6 +19,7 @@
 import (
 	"fmt"
 	"io/ioutil"
+	"net"
 	"net/http"
 	"os"
 	"os/user"
@@ -82,6 +83,44 @@
 	return fmt.Sprintf("passthrough resolver of %v", p.addr)
 }
 
+type dnsResolver struct {
+	addrs    []string
+	failback NsResolver
+}
+
+func NewDNSResolver(addrs []string) *dnsResolver {
+	return &dnsResolver{
+		addrs:    addrs,
+		failback: NewEnvResolver(),
+	}
+}
+
+func (p *dnsResolver) Resolve() []string {
+	finalAddrs := make([]string, 0, len(p.addrs))
+	for _, addr := range p.addrs {
+		// example.com:9876
+		domainPort := strings.Split(addr, ":")
+		if len(domainPort) != 2 {
+			continue
+		}
+		ns, err := net.LookupHost(domainPort[0])
+		if err != nil {
+			continue
+		}
+		for _, host := range ns {
+			finalAddrs = append(finalAddrs, host+":"+domainPort[1])
+		}
+	}
+	if len(finalAddrs) > 0 {
+		return finalAddrs
+	}
+	return p.failback.Resolve()
+}
+
+func (p *dnsResolver) Description() string {
+	return fmt.Sprintf("dns resolver of %v", p.addrs)
+}
+
 const (
 	DEFAULT_NAMESRV_ADDR = "http://jmenv.tbsite.net:8080/rocketmq/nsaddr"
 )
diff --git a/primitive/nsresolver_test.go b/primitive/nsresolver_test.go
index 98d839a..68bb955 100644
--- a/primitive/nsresolver_test.go
+++ b/primitive/nsresolver_test.go
@@ -131,3 +131,21 @@
 		So(Diff(addrs1, srvs), ShouldBeFalse)
 	})
 }
+
+func TestDNSResolver(t *testing.T) {
+	Convey("Test UpdateNameServerAddress Use DNS", t, func() {
+		srvs := []string{
+			"examples.com:9876",
+		}
+
+		hosts, _ := net.LookupHost("examples.com")
+		expectedHosts := make([]string, 0)
+		for _, host := range hosts {
+			expectedHosts = append(expectedHosts, host+":9876")
+		}
+		resolver := NewDNSResolver(srvs)
+		addrs := resolver.Resolve()
+
+		So(Diff(expectedHosts, addrs), ShouldBeFalse)
+	})
+}