diff --git a/network/resolver/dns/dns.go b/network/resolver/dns/dns.go new file mode 100644 index 00000000..c905df0e --- /dev/null +++ b/network/resolver/dns/dns.go @@ -0,0 +1,30 @@ +// Package dns resolves ids to dns srv records +package dns + +import ( + "fmt" + "net" + + "github.com/micro/go-micro/network/resolver" +) + +type Resolver struct{} + +// Resolve assumes ID is a domain name e.g micro.mu +func (r *Resolver) Resolve(id string) ([]*resolver.Record, error) { + _, addrs, err := net.LookupSRV("network", "udp", id) + if err != nil { + return nil, err + } + var records []*resolver.Record + for _, addr := range addrs { + address := addr.Target + if addr.Port > 0 { + address = fmt.Sprintf("%s:%d", addr.Target, addr.Port) + } + records = append(records, &resolver.Record{ + Address: address, + }) + } + return records, nil +} diff --git a/network/resolver/http/http.go b/network/resolver/http/http.go new file mode 100644 index 00000000..80ff4d61 --- /dev/null +++ b/network/resolver/http/http.go @@ -0,0 +1,59 @@ +// Package http resolves ids to network addresses using a http request +package http + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "net/url" + + "github.com/micro/go-micro/network/resolver" +) + +type Resolver struct { + // If not set, defaults to http + Proto string + + // Path sets the path to lookup. Defaults to /network + Path string +} + +// Resolve assumes ID is a domain which can be converted to a http://id/network request +func (r *Resolver) Resolve(id string) ([]*resolver.Record, error) { + proto := "http" + path := "/network" + + if len(r.Proto) > 0 { + proto = r.Proto + } + + if len(r.Path) > 0 { + path = r.Path + } + + uri := &url.URL{ + Scheme: proto, + Path: path, + Host: id, + } + + rsp, err := http.Get(uri.String()) + if err != nil { + return nil, err + } + defer rsp.Body.Close() + + b, err := ioutil.ReadAll(rsp.Body) + if err != nil { + return nil, err + } + + // encoding format is assumed to be json + var records []*resolver.Record + + if err := json.Unmarshal(b, &records); err != nil { + return nil, err + } + + return records, nil +} diff --git a/network/resolver/registry/registry.go b/network/resolver/registry/registry.go new file mode 100644 index 00000000..c7ef796a --- /dev/null +++ b/network/resolver/registry/registry.go @@ -0,0 +1,37 @@ +// Package registry resolves ids using the go-micro registry +package registry + +import ( + "github.com/micro/go-micro/network/resolver" + "github.com/micro/go-micro/registry" +) + +type Resolver struct { + // Registry is the registry to use otherwise we use the defaul + Registry registry.Registry +} + +// Resolve assumes ID is a domain name e.g micro.mu +func (r *Resolver) Resolve(id string) ([]*resolver.Record, error) { + reg := r.Registry + if reg == nil { + reg = registry.DefaultRegistry + } + + services, err := reg.GetService(id) + if err != nil { + return nil, err + } + + var records []*resolver.Record + + for _, service := range services { + for _, node := range service.Nodes { + records = append(records, &resolver.Record{ + Address: node.Address, + }) + } + } + + return records, nil +} diff --git a/network/resolver/resolver.go b/network/resolver/resolver.go new file mode 100644 index 00000000..6c54eb95 --- /dev/null +++ b/network/resolver/resolver.go @@ -0,0 +1,15 @@ +// Package resolver resolves network ids to addresses +package resolver + +// Resolver is network resolver. It's used to find network nodes +// via id to connect to. This is done based on Network.Id(). +// Before we can be part of any network, we have to connect to it. +type Resolver interface { + // Resolve returns a list of addresses for an id + Resolve(id string) ([]*Record, error) +} + +// A resolved record +type Record struct { + Address string `json:"address"` +}