123 lines
2.9 KiB
Go
123 lines
2.9 KiB
Go
package nacosx
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
Server string
|
|
NamespaceID string
|
|
BindIP string
|
|
Timeout time.Duration
|
|
}
|
|
|
|
type Client struct {
|
|
baseURL string
|
|
namespaceID string
|
|
bindIP string
|
|
client *http.Client
|
|
}
|
|
|
|
func New(cfg Config) *Client {
|
|
timeout := cfg.Timeout
|
|
if timeout == 0 {
|
|
timeout = 15 * time.Second
|
|
}
|
|
return &Client{
|
|
baseURL: strings.TrimRight(cfg.Server, "/"),
|
|
namespaceID: cfg.NamespaceID,
|
|
bindIP: cfg.BindIP,
|
|
client: &http.Client{Timeout: timeout},
|
|
}
|
|
}
|
|
|
|
func (c *Client) BaseURL() string {
|
|
return c.baseURL
|
|
}
|
|
|
|
func (c *Client) BindIP() string {
|
|
return c.bindIP
|
|
}
|
|
|
|
func (c *Client) ConfigJSON(dataID string, dst any) error {
|
|
body, err := c.GetConfig(dataID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(body, dst)
|
|
}
|
|
|
|
func (c *Client) GetConfig(dataID string) ([]byte, error) {
|
|
u, _ := url.Parse(c.baseURL + "/nacos/v1/cs/configs")
|
|
q := u.Query()
|
|
q.Set("dataId", dataID)
|
|
q.Set("group", "DEFAULT_GROUP")
|
|
q.Set("tenant", c.namespaceID)
|
|
u.RawQuery = q.Encode()
|
|
|
|
resp, err := c.client.Get(u.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
body, _ := io.ReadAll(resp.Body)
|
|
if resp.StatusCode >= http.StatusMultipleChoices {
|
|
return nil, fmt.Errorf("nacos config %s status=%d body=%s", dataID, resp.StatusCode, string(body))
|
|
}
|
|
return body, nil
|
|
}
|
|
|
|
func (c *Client) Register(serviceName string, port int) error {
|
|
values := url.Values{}
|
|
values.Set("serviceName", serviceName)
|
|
values.Set("ip", c.bindIP)
|
|
values.Set("port", strconv.Itoa(port))
|
|
values.Set("namespaceId", c.namespaceID)
|
|
values.Set("ephemeral", "true")
|
|
resp, err := c.client.PostForm(c.baseURL+"/nacos/v1/ns/instance", values)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode >= http.StatusMultipleChoices {
|
|
body, _ := io.ReadAll(resp.Body)
|
|
return fmt.Errorf("status=%d body=%s", resp.StatusCode, string(body))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Client) Heartbeat(serviceName string, port int) {
|
|
ticker := time.NewTicker(5 * time.Second)
|
|
defer ticker.Stop()
|
|
for range ticker.C {
|
|
beat, _ := json.Marshal(map[string]any{"serviceName": serviceName, "ip": c.bindIP, "port": port, "ephemeral": true})
|
|
u, _ := url.Parse(c.baseURL + "/nacos/v1/ns/instance/beat")
|
|
q := u.Query()
|
|
q.Set("serviceName", serviceName)
|
|
q.Set("ip", c.bindIP)
|
|
q.Set("port", strconv.Itoa(port))
|
|
q.Set("namespaceId", c.namespaceID)
|
|
q.Set("beat", string(beat))
|
|
u.RawQuery = q.Encode()
|
|
req, _ := http.NewRequest(http.MethodPut, u.String(), nil)
|
|
resp, err := c.client.Do(req)
|
|
if err != nil {
|
|
log.Printf("nacos heartbeat failed: %v", err)
|
|
continue
|
|
}
|
|
io.Copy(io.Discard, resp.Body)
|
|
resp.Body.Close()
|
|
if resp.StatusCode >= http.StatusMultipleChoices {
|
|
log.Printf("nacos heartbeat status=%d", resp.StatusCode)
|
|
}
|
|
}
|
|
}
|