This is an automated email from the ASF dual-hosted git repository.
juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new 214e41d fix: nodes format not works (#847)
214e41d is described below
commit 214e41dc4253277d714c9574af183a74af15b257
Author: nic-chen <[email protected]>
AuthorDate: Mon Nov 23 18:52:22 2020 +0800
fix: nodes format not works (#847)
* fix: nodes format not works
* test: add test cases
* test: simulate real use cases
* chore: code format according to review
* fix: remove redundant empty line.
* fix: code format
* fix: code format
---
api/internal/core/entity/entity.go | 2 +-
api/internal/core/entity/format.go | 74 +++++++++++++++++++++------------
api/internal/core/entity/format_test.go | 65 +++++++++++++++++++++++------
3 files changed, 102 insertions(+), 39 deletions(-)
diff --git a/api/internal/core/entity/entity.go
b/api/internal/core/entity/entity.go
index 93ae456..30ae2b1 100644
--- a/api/internal/core/entity/entity.go
+++ b/api/internal/core/entity/entity.go
@@ -88,7 +88,7 @@ type Timeout struct {
type Node struct {
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
- Weight int `json:"weight,omitempty"`
+ Weight int `json:"weight"`
Metadata interface{} `json:"metadata,omitempty"`
}
diff --git a/api/internal/core/entity/format.go
b/api/internal/core/entity/format.go
index a409644..a1384b4 100644
--- a/api/internal/core/entity/format.go
+++ b/api/internal/core/entity/format.go
@@ -17,51 +17,73 @@
package entity
import (
- "log"
+ "net"
"strconv"
- "strings"
+
+ "github.com/apisix/manager-api/log"
)
+func mapKV2Node(key string, val float64) (*Node, error) {
+ host, port, err := net.SplitHostPort(key)
+ if err != nil {
+ log.Warn("split host port fail: %s", err)
+ return nil, err
+ }
+
+ portInt, err := strconv.Atoi(port)
+ if err != nil {
+ log.Errorf("parse port to int fail: %s", err)
+ return nil, err
+ }
+
+ node := &Node{
+ Host: host,
+ Port: portInt,
+ Weight: int(val),
+ }
+
+ return node, nil
+}
+
func NodesFormat(obj interface{}) interface{} {
var nodes []*Node
- if value, ok := obj.(map[string]float64); ok {
- var strArr []string
+ switch objType := obj.(type) {
+ case map[string]float64:
+ log.Infof("nodes type: %v", objType)
+ value := obj.(map[string]float64)
for key, val := range value {
- node := &Node{}
- strArr = strings.Split(key, ":")
- if len(strArr) != 2 {
- log.Println("length of string array is not 2")
+ node, err := mapKV2Node(key, val)
+ if err != nil {
return obj
}
-
- port, err := strconv.Atoi(strArr[1])
+ nodes = append(nodes, node)
+ }
+ return nodes
+ case map[string]interface{}:
+ log.Infof("nodes type: %v", objType)
+ value := obj.(map[string]interface{})
+ for key, val := range value {
+ node, err := mapKV2Node(key, val.(float64))
if err != nil {
- log.Println("parse int fail:", err)
return obj
}
-
- node.Host = strArr[0]
- node.Port = port
- node.Weight = int(val)
nodes = append(nodes, node)
}
return nodes
- }
-
- if nodes, ok := obj.([]*Node); ok {
+ case []*Node:
+ log.Infof("nodes type: %v", objType)
return nodes
- }
-
- if list, ok := obj.([]interface{}); ok {
+ case []interface{}:
+ list := obj.([]interface{})
for _, v := range list {
val := v.(map[string]interface{})
- node := &Node{}
- node.Host = val["host"].(string)
- node.Port = int(val["port"].(float64))
- node.Weight = int(val["weight"].(float64))
+ node := &Node{
+ Host: val["host"].(string),
+ Port: int(val["port"].(float64)),
+ Weight: int(val["weight"].(float64)),
+ }
nodes = append(nodes, node)
}
-
return nodes
}
diff --git a/api/internal/core/entity/format_test.go
b/api/internal/core/entity/format_test.go
index 5ba5e13..ab63232 100644
--- a/api/internal/core/entity/format_test.go
+++ b/api/internal/core/entity/format_test.go
@@ -23,19 +23,60 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestConsumer(t *testing.T) {
- nodesStr := `{
- "127.0.0.1:8080": 1
- }`
- nodesMap := map[string]float64{}
- err := json.Unmarshal([]byte(nodesStr), &nodesMap)
+func TestNodesFormat(t *testing.T) {
+ // route data saved in ETCD
+ routeStr := `{
+ "uris": ["/*"],
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": [{
+ "host": "127.0.0.1",
+ "port": 80,
+ "weight": 0
+ }]
+ }
+ }`
+
+ // bind struct
+ var route Route
+ err := json.Unmarshal([]byte(routeStr), &route)
assert.Nil(t, err)
- res := NodesFormat(nodesMap)
- nodes := res.([]*Node)
+ // nodes format
+ nodes := NodesFormat(route.Upstream.Nodes)
+
+ // json encode for client
+ res, err := json.Marshal(nodes)
+ assert.Nil(t, err)
+ jsonStr := string(res)
+ assert.Contains(t, jsonStr, `"weight":0`)
+ assert.Contains(t, jsonStr, `"port":80`)
+ assert.Contains(t, jsonStr, `"host":"127.0.0.1"`)
+}
+
+func TestNodesFormat_Map(t *testing.T) {
+ // route data saved in ETCD
+ routeStr := `{
+ "uris": ["/*"],
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {"127.0.0.1:8080": 0}
+ }
+ }`
- assert.Equal(t, 1, len(nodes))
- assert.Equal(t, "127.0.0.1", nodes[0].Host)
- assert.Equal(t, 8080, nodes[0].Port)
- assert.Equal(t, 1, nodes[0].Weight)
+ // bind struct
+ var route Route
+ err := json.Unmarshal([]byte(routeStr), &route)
+ assert.Nil(t, err)
+
+ // nodes format
+ nodes := NodesFormat(route.Upstream.Nodes)
+
+ // json encode for client
+ res, err := json.Marshal(nodes)
+ assert.Nil(t, err)
+ jsonStr := string(res)
+ assert.Contains(t, jsonStr, `"weight":0`)
+ assert.Contains(t, jsonStr, `"port":8080`)
+ assert.Contains(t, jsonStr, `"host":"127.0.0.1"`)
}