package registry import ( "bytes" "context" "encoding/json" "errors" "io" "net" "net/http" "time" ) type ( Discovery struct { baseUrl string } discoveryResponse struct { Code int `json:"errno"` Message string `json:"errmsg"` Data json.RawMessage `json:"result"` } ) func (r *Discovery) sendRequest(ctx context.Context, method, path string, body io.Reader, data interface{}) (err error) { var ( req *http.Request res *http.Response ) if req, err = http.NewRequest(method, r.baseUrl+path, body); err != nil { return } if body != nil { req.Header.Set("Content-Type", "application/json") } if res, err = http.DefaultClient.Do(req.WithContext(ctx)); err != nil { return } defer func() { _ = res.Body.Close() }() rv := &discoveryResponse{} if err = json.NewDecoder(res.Body).Decode(rv); err == nil { if rv.Code == 0 { if data != nil { err = json.Unmarshal(rv.Data, data) } } else { err = errors.New(rv.Message) } } return } func (r *Discovery) Register(instance *ServiceNode) (err error) { var ( buf []byte ) if buf, err = json.Marshal(instance); err != nil { return } ctx, _ := context.WithTimeout(context.Background(), time.Second*2) return r.sendRequest(ctx, "POST", "/register", bytes.NewReader(buf), nil) } func (r *Discovery) Deregister(instance *ServiceNode) (err error) { ctx, _ := context.WithTimeout(context.Background(), time.Second*2) return r.sendRequest(ctx, "DELETE", "/deregister/"+instance.ID, nil, nil) } func (r *Discovery) Get(name string) (instances []*ServiceNode, err error) { instances = make([]*ServiceNode, 0) ctx, _ := context.WithTimeout(context.Background(), time.Second*2) err = r.sendRequest(ctx, "GET", "/service?name="+name, nil, &instances) return } func (r *Discovery) Fetch() (instances []*ServiceNode, err error) { instances = make([]*ServiceNode, 0) ctx, _ := context.WithTimeout(context.Background(), time.Second*2) err = r.sendRequest(ctx, "GET", "/services", nil, &instances) return } func NewDiscovery(uri string) *Discovery { if uri == "" { if c, err := net.DialTimeout("tcp", "10.1.100.108:80", time.Millisecond*200); err == nil { uri = "http://10.1.100.108" c.Close() } else { uri = "https://discovery.nspix.com" } } return &Discovery{ baseUrl: uri, } }