This is an automated email from the ASF dual-hosted git repository.

liuxiran 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 94d952f  fix(be): Modify the upstream to use the new JSON patch 
package (#1395)
94d952f is described below

commit 94d952f9a43a9d6507b2966b58791f789e5b74a6
Author: JinChen <[email protected]>
AuthorDate: Mon Feb 1 11:26:08 2021 +0800

    fix(be): Modify the upstream to use the new JSON patch package (#1395)
    
    
    Co-authored-by: nic-chen <[email protected]>
---
 api/go.mod                                     |  2 -
 api/go.sum                                     |  4 --
 api/internal/handler/upstream/upstream.go      | 47 ++++++++-------
 api/internal/handler/upstream/upstream_test.go | 61 +++++++++++++++++++
 api/test/docker/Dockerfile-apisix              |  2 -
 api/test/e2e/base.go                           |  3 +
 api/test/e2e/upstream_test.go                  | 82 ++++++++++++++++++++++++++
 7 files changed, 169 insertions(+), 32 deletions(-)

diff --git a/api/go.mod b/api/go.mod
index e0b9457..e714d8a 100644
--- a/api/go.mod
+++ b/api/go.mod
@@ -7,8 +7,6 @@ replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
 replace github.com/coreos/bbolt => go.etcd.io/bbolt v1.3.5
 
 require (
-       github.com/api7/go-jsonpatch v0.0.0-20180223123257-a8710867776e
-       github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e // 
indirect
        github.com/coreos/bbolt v0.0.0-00010101000000-000000000000 // indirect
        github.com/coreos/etcd v3.3.25+incompatible // indirect
        github.com/coreos/go-semver v0.3.0 // indirect
diff --git a/api/go.sum b/api/go.sum
index d8234a3..5bc205f 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -16,8 +16,6 @@ github.com/alecthomas/units 
v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
 github.com/antihax/optional v1.0.0/go.mod 
h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apache/thrift v0.12.0/go.mod 
h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/apache/thrift v0.13.0/go.mod 
h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
-github.com/api7/go-jsonpatch v0.0.0-20180223123257-a8710867776e 
h1:TX/8xM53DHaIIBr4wU+ifYI8IkUzS8+HrX8kzIzaaG0=
-github.com/api7/go-jsonpatch v0.0.0-20180223123257-a8710867776e/go.mod 
h1:yc49guNPyTy2deyszk3erQN+2vO2NwLKPNicXurj7Hs=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod 
h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod 
h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod 
h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@@ -33,8 +31,6 @@ github.com/bgentry/speakeasy v0.1.0/go.mod 
h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
 github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod 
h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
 github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod 
h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
 github.com/bradleypeabody/gorilla-sessions-memcache 
v0.0.0-20181103040241-659414f458e1/go.mod 
h1:dkChI7Tbtx7H1Tj7TqGSZMOeGpMP5gLHtjroHd4agiI=
-github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e 
h1:6c3+GQuYUWljNcReOg4gxMUss9Gjll+5Y9vqDM+ILy8=
-github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e/go.mod 
h1:kdPJxKAfR3ZdD+MWYorN1oTdV9+qwJy9jO/0meJmcxU=
 github.com/casbin/casbin/v2 v2.1.2/go.mod 
h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod 
h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod 
h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
diff --git a/api/internal/handler/upstream/upstream.go 
b/api/internal/handler/upstream/upstream.go
index faab379..eb78034 100644
--- a/api/internal/handler/upstream/upstream.go
+++ b/api/internal/handler/upstream/upstream.go
@@ -17,11 +17,11 @@
 package upstream
 
 import (
+       "encoding/json"
        "net/http"
        "reflect"
        "strings"
 
-       "github.com/api7/go-jsonpatch"
        "github.com/gin-gonic/gin"
        "github.com/shiningrush/droplet"
        "github.com/shiningrush/droplet/data"
@@ -31,6 +31,7 @@ import (
        "github.com/apisix/manager-api/internal/core/entity"
        "github.com/apisix/manager-api/internal/core/store"
        "github.com/apisix/manager-api/internal/handler"
+       "github.com/apisix/manager-api/internal/utils"
        "github.com/apisix/manager-api/internal/utils/consts"
 )
 
@@ -56,7 +57,9 @@ func (h *Handler) ApplyRoute(r *gin.Engine) {
        r.PUT("/apisix/admin/upstreams/:id", wgin.Wraps(h.Update,
                wrapper.InputType(reflect.TypeOf(UpdateInput{}))))
        r.PATCH("/apisix/admin/upstreams/:id", wgin.Wraps(h.Patch,
-               wrapper.InputType(reflect.TypeOf(UpdateInput{}))))
+               wrapper.InputType(reflect.TypeOf(PatchInput{}))))
+       r.PATCH("/apisix/admin/upstreams/:id/*path", wgin.Wraps(h.Patch,
+               wrapper.InputType(reflect.TypeOf(PatchInput{}))))
        r.DELETE("/apisix/admin/upstreams/:ids", wgin.Wraps(h.BatchDelete,
                wrapper.InputType(reflect.TypeOf(BatchDelete{}))))
 
@@ -198,39 +201,35 @@ func (h *Handler) BatchDelete(c droplet.Context) 
(interface{}, error) {
        return nil, nil
 }
 
+type PatchInput struct {
+       ID      string `auto_read:"id,path"`
+       SubPath string `auto_read:"path,path"`
+       Body    []byte `auto_read:"@body"`
+}
+
 func (h *Handler) Patch(c droplet.Context) (interface{}, error) {
-       input := c.Input().(*UpdateInput)
-       arr := strings.Split(input.ID, "/")
-       var subPath string
-       if len(arr) > 1 {
-               input.ID = arr[0]
-               subPath = arr[1]
-       }
+       input := c.Input().(*PatchInput)
+       reqBody := input.Body
+       id := input.ID
+       subPath := input.SubPath
 
-       stored, err := h.upstreamStore.Get(c.Context(), input.ID)
+       stored, err := h.upstreamStore.Get(c.Context(), id)
        if err != nil {
                return handler.SpecCodeResponse(err), err
        }
 
-       var patch jsonpatch.Patch
-       if subPath != "" {
-               patch = jsonpatch.Patch{
-                       Operations: []jsonpatch.PatchOperation{
-                               {Op: jsonpatch.Replace, Path: subPath, Value: 
c.Input()},
-                       },
-               }
-       } else {
-               patch, err = jsonpatch.MakePatch(stored, input.Upstream)
-               if err != nil {
-                       return handler.SpecCodeResponse(err), err
-               }
+       res, err := utils.MergePatch(stored, subPath, reqBody)
+
+       if err != nil {
+               return handler.SpecCodeResponse(err), err
        }
 
-       if err := patch.Apply(&stored); err != nil {
+       var upstream entity.Upstream
+       if err := json.Unmarshal(res, &upstream); err != nil {
                return handler.SpecCodeResponse(err), err
        }
 
-       ret, err := h.upstreamStore.Update(c.Context(), &stored, false)
+       ret, err := h.upstreamStore.Update(c.Context(), &upstream, false)
        if err != nil {
                return handler.SpecCodeResponse(err), err
        }
diff --git a/api/internal/handler/upstream/upstream_test.go 
b/api/internal/handler/upstream/upstream_test.go
index 103fe3c..c22d99a 100644
--- a/api/internal/handler/upstream/upstream_test.go
+++ b/api/internal/handler/upstream/upstream_test.go
@@ -19,6 +19,7 @@ package upstream
 
 import (
        "encoding/json"
+       "strings"
        "testing"
        "time"
 
@@ -240,3 +241,63 @@ func TestUpstream_Pass_Host(t *testing.T) {
        assert.Nil(t, err)
 
 }
+
+func TestUpstream_Patch_Update(t *testing.T) {
+       //create
+       ctx := droplet.NewContext()
+       upstream := &entity.Upstream{}
+       reqBody := `{
+                       "id": "3",
+                       "nodes": [{
+                               "host": "172.16.238.20",
+                               "port": 1980,
+                               "weight": 1
+                       }],
+                       "type": "roundrobin"
+               }`
+       err := json.Unmarshal([]byte(reqBody), upstream)
+       assert.Nil(t, err)
+       ctx.SetInput(upstream)
+       ret, err := upstreamHandler.Create(ctx)
+       assert.Nil(t, err)
+       objRet, ok := ret.(*entity.Upstream)
+       assert.True(t, ok)
+       assert.Equal(t, "3", objRet.ID)
+
+       //sleep
+       time.Sleep(time.Duration(20) * time.Millisecond)
+
+       reqBody1 := `{
+               "nodes": [{
+                       "host": "172.16.238.20",
+                       "port": 1981,
+                       "weight": 1
+               }],
+               "type": "roundrobin"
+       }`
+       responesBody := 
`"nodes":[{"host":"172.16.238.20","port":1981,"weight":1}],"type":"roundrobin"}`
+
+       input2 := &PatchInput{}
+       input2.ID = "3"
+       input2.SubPath = ""
+       input2.Body = []byte(reqBody1)
+       ctx.SetInput(input2)
+
+       ret2, err := upstreamHandler.Patch(ctx)
+       assert.Nil(t, err)
+       _ret2, err := json.Marshal(ret2)
+       assert.Nil(t, err)
+       isContains := strings.Contains(string(_ret2), responesBody)
+       assert.True(t, isContains)
+
+       //delete test data
+       inputDel2 := &BatchDelete{}
+       reqBody = `{"ids": "3"}`
+       err = json.Unmarshal([]byte(reqBody), inputDel2)
+       assert.Nil(t, err)
+       ctx.SetInput(inputDel2)
+       _, err = upstreamHandler.BatchDelete(ctx)
+       assert.Nil(t, err)
+
+}
+
diff --git a/api/test/docker/Dockerfile-apisix 
b/api/test/docker/Dockerfile-apisix
index 5c4bd31..bd1ad0a 100644
--- a/api/test/docker/Dockerfile-apisix
+++ b/api/test/docker/Dockerfile-apisix
@@ -31,8 +31,6 @@ RUN set -x \
     git \
     && luarocks install 
https://github.com/apache/apisix/raw/master/rockspec/apisix-${APISIX_VERSION}-0.rockspec
 --tree=/usr/local/apisix/deps \
     && cp -v 
/usr/local/apisix/deps/lib/luarocks/rocks-5.1/apisix/${APISIX_VERSION}-0/bin/apisix
 /usr/bin/ \
-    && bin='#! /usr/local/openresty/luajit/bin/luajit\npackage.path = 
"/usr/local/apisix/?.lua;" .. package.path' \
-    && sed -i "1s@.*@$bin@" /usr/bin/apisix \
     && mv /usr/local/apisix/deps/share/lua/5.1/apisix /usr/local/apisix \
     && apk del .builddeps build-base make unzip
 
diff --git a/api/test/e2e/base.go b/api/test/e2e/base.go
index 0d9a333..8d3385e 100644
--- a/api/test/e2e/base.go
+++ b/api/test/e2e/base.go
@@ -147,6 +147,9 @@ func BatchTestServerPort(t *testing.T, times int) 
map[string]int {
        for i := 0; i < times; i++ {
                client = &http.Client{}
                resp, err = client.Do(req)
+               if err != nil {
+                       fmt.Printf("err: %s", err)
+               }
                assert.Nil(t, err)
 
                bodyByte, err = ioutil.ReadAll(resp.Body)
diff --git a/api/test/e2e/upstream_test.go b/api/test/e2e/upstream_test.go
index 3936c11..be2dd6f 100644
--- a/api/test/e2e/upstream_test.go
+++ b/api/test/e2e/upstream_test.go
@@ -523,3 +523,85 @@ func TestUpstream_Create_via_Post(t *testing.T) {
                testCaseCheck(tc, t)
        }
 }
+
+func TestUpstream_Update_Use_Patch_Method(t *testing.T) {
+       tests := []HttpTestCase{
+               {
+                       Desc:   "create upstream via POST",
+                       Object: ManagerApiExpect(t),
+                       Method: http.MethodPost,
+                       Path:   "/apisix/admin/upstreams",
+                       Body: `{
+                               "id": "u1",
+                               "nodes": [{
+                                       "host": "172.16.238.20",
+                                       "port": 1980,
+                                       "weight": 1
+                               }],
+                               "type": "roundrobin"
+                       }`,
+                       Headers:      map[string]string{"Authorization": token},
+                       ExpectStatus: http.StatusOK,
+                       ExpectBody:   []string{"\"id\":\"u1\"", 
"\"type\":\"roundrobin\""},
+               },
+               {
+                       Desc:   "update upstream use patch method",
+                       Object: ManagerApiExpect(t),
+                       Method: http.MethodPatch,
+                       Path:   "/apisix/admin/upstreams/u1",
+                       Body: `{
+                               "nodes": [{
+                                       "host": "172.16.238.20",
+                                       "port": 1981,
+                                       "weight": 1
+                               }],
+                               "type": "roundrobin"
+                       }`,
+                       Headers:      map[string]string{"Authorization": token},
+                       ExpectStatus: http.StatusOK,
+               },
+               {
+                       Desc:         "get upstream data",
+                       Object:       ManagerApiExpect(t),
+                       Method:       http.MethodGet,
+                       Path:         "/apisix/admin/upstreams/u1",
+                       Headers:      map[string]string{"Authorization": token},
+                       ExpectStatus: http.StatusOK,
+                       ExpectBody:   
"nodes\":[{\"host\":\"172.16.238.20\",\"port\":1981,\"weight\":1}],\"type\":\"roundrobin\"}",
+               },
+               {
+                       Desc:   "Update upstream using path parameter patch 
method",
+                       Object: ManagerApiExpect(t),
+                       Method: http.MethodPatch,
+                       Path:   "/apisix/admin/upstreams/u1/nodes",
+                       Body:   `[{"host":"172.16.238.20","port": 
1980,"weight":1}]`,
+                       Headers: map[string]string{
+                               "Authorization": token,
+                               "Content-Type":  "text/plain",
+                       },
+                       ExpectStatus: http.StatusOK,
+               },
+               {
+                       Desc:         "get upstream data",
+                       Object:       ManagerApiExpect(t),
+                       Method:       http.MethodGet,
+                       Path:         "/apisix/admin/upstreams/u1",
+                       Headers:      map[string]string{"Authorization": token},
+                       ExpectStatus: http.StatusOK,
+                       ExpectBody:   
"nodes\":[{\"host\":\"172.16.238.20\",\"port\":1980,\"weight\":1}],\"type\":\"roundrobin\"}",
+               },
+               {
+                       Desc:         "delete upstream",
+                       Object:       ManagerApiExpect(t),
+                       Method:       http.MethodDelete,
+                       Path:         "/apisix/admin/upstreams/u1",
+                       Headers:      map[string]string{"Authorization": token},
+                       ExpectStatus: http.StatusOK,
+               },
+       }
+
+       for _, tc := range tests {
+               testCaseCheck(tc, t)
+       }
+}
+

Reply via email to