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"`)
 }

Reply via email to