1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-01-17 17:44:30 +02:00
Benjamin 5d5aee1f08
replace ioutil with io and os (#2327)
set the go version to 1.16 in pr.yml and tests.yml, so as to be consistent with the version in go.mod.
2021-10-30 19:24:40 +01:00

254 lines
4.7 KiB
Go

// Package proxy is a registry plugin for the micro proxy
package proxy
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"go-micro.dev/v4/cmd"
"go-micro.dev/v4/registry"
)
type proxy struct {
opts registry.Options
}
func init() {
cmd.DefaultRegistries["proxy"] = NewRegistry
}
func configure(s *proxy, opts ...registry.Option) error {
for _, o := range opts {
o(&s.opts)
}
var addrs []string
for _, addr := range s.opts.Addrs {
if len(addr) > 0 {
addrs = append(addrs, addr)
}
}
if len(addrs) == 0 {
addrs = []string{"localhost:8081"}
}
registry.Addrs(addrs...)(&s.opts)
return nil
}
func newRegistry(opts ...registry.Option) registry.Registry {
s := &proxy{
opts: registry.Options{},
}
configure(s, opts...)
return s
}
func (s *proxy) Init(opts ...registry.Option) error {
return configure(s, opts...)
}
func (s *proxy) Options() registry.Options {
return s.opts
}
func (s *proxy) Register(service *registry.Service, opts ...registry.RegisterOption) error {
b, err := json.Marshal(service)
if err != nil {
return err
}
var gerr error
for _, addr := range s.opts.Addrs {
scheme := "http"
if s.opts.Secure {
scheme = "https"
}
url := fmt.Sprintf("%s://%s/registry", scheme, addr)
rsp, err := http.Post(url, "application/json", bytes.NewReader(b))
if err != nil {
gerr = err
continue
}
if rsp.StatusCode != 200 {
b, err := io.ReadAll(rsp.Body)
if err != nil {
return err
}
rsp.Body.Close()
gerr = errors.New(string(b))
continue
}
io.Copy(io.Discard, rsp.Body)
rsp.Body.Close()
return nil
}
return gerr
}
func (s *proxy) Deregister(service *registry.Service, opts ...registry.DeregisterOption) error {
b, err := json.Marshal(service)
if err != nil {
return err
}
var gerr error
for _, addr := range s.opts.Addrs {
scheme := "http"
if s.opts.Secure {
scheme = "https"
}
url := fmt.Sprintf("%s://%s/registry", scheme, addr)
req, err := http.NewRequest("DELETE", url, bytes.NewReader(b))
if err != nil {
gerr = err
continue
}
rsp, err := http.DefaultClient.Do(req)
if err != nil {
gerr = err
continue
}
if rsp.StatusCode != 200 {
b, err := io.ReadAll(rsp.Body)
if err != nil {
return err
}
rsp.Body.Close()
gerr = errors.New(string(b))
continue
}
io.Copy(io.Discard, rsp.Body)
rsp.Body.Close()
return nil
}
return gerr
}
func (s *proxy) GetService(service string, opts ...registry.GetOption) ([]*registry.Service, error) {
var gerr error
for _, addr := range s.opts.Addrs {
scheme := "http"
if s.opts.Secure {
scheme = "https"
}
url := fmt.Sprintf("%s://%s/registry?service=%s", scheme, addr, url.QueryEscape(service))
rsp, err := http.Get(url)
if err != nil {
gerr = err
continue
}
if rsp.StatusCode != 200 {
b, err := io.ReadAll(rsp.Body)
if err != nil {
return nil, err
}
rsp.Body.Close()
gerr = errors.New(string(b))
continue
}
b, err := io.ReadAll(rsp.Body)
if err != nil {
gerr = err
continue
}
rsp.Body.Close()
var services []*registry.Service
if err := json.Unmarshal(b, &services); err != nil {
gerr = err
continue
}
return services, nil
}
return nil, gerr
}
func (s *proxy) ListServices(opts ...registry.ListOption) ([]*registry.Service, error) {
var gerr error
for _, addr := range s.opts.Addrs {
scheme := "http"
if s.opts.Secure {
scheme = "https"
}
url := fmt.Sprintf("%s://%s/registry", scheme, addr)
rsp, err := http.Get(url)
if err != nil {
gerr = err
continue
}
if rsp.StatusCode != 200 {
b, err := io.ReadAll(rsp.Body)
if err != nil {
return nil, err
}
rsp.Body.Close()
gerr = errors.New(string(b))
continue
}
b, err := io.ReadAll(rsp.Body)
if err != nil {
gerr = err
continue
}
rsp.Body.Close()
var services []*registry.Service
if err := json.Unmarshal(b, &services); err != nil {
gerr = err
continue
}
return services, nil
}
return nil, gerr
}
func (s *proxy) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
var wo registry.WatchOptions
for _, o := range opts {
o(&wo)
}
watch := func(addr string) (registry.Watcher, error) {
scheme := "ws"
if s.opts.Secure {
scheme = "wss"
}
url := fmt.Sprintf("%s://%s/registry", scheme, addr)
// service filter
if len(wo.Service) > 0 {
url = url + "?service=" + wo.Service
}
return newWatcher(url)
}
var gerr error
for _, addr := range s.opts.Addrs {
w, err := watch(addr)
if err != nil {
gerr = err
continue
}
return w, nil
}
return nil, gerr
}
func (s *proxy) String() string {
return "proxy"
}
func NewRegistry(opts ...registry.Option) registry.Registry {
return newRegistry(opts...)
}