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

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git


The following commit(s) were added to refs/heads/master by this push:
     new 21268e7  [issue #67] add interface to add alias (#72)
21268e7 is described below

commit 21268e791fb9f7fd91671d07f28654dfa0df132c
Author: GuoYL <[email protected]>
AuthorDate: Mon Feb 3 09:25:30 2020 +0800

    [issue #67] add interface to add alias (#72)
    
    * add interface to add alias
    
    * delete no use code
    
    * update unit test
    
    * modify as suggestion
    
    * modify param to struct
    
    * for CI
---
 pkg/model/db_schema.go                       |  1 +
 server/resource/v1/label_resouce.go          | 81 ++++++++++++++++++++++++++++
 server/resource/v1/label_resouce_test.go     | 75 ++++++++++++++++++++++++++
 server/service/mongo/init.go                 |  2 +
 server/service/mongo/kv/kv_service.go        |  8 ++-
 server/service/mongo/label/label_dao.go      | 32 +++++++----
 server/service/mongo/label/label_dao_test.go | 11 ++--
 server/service/mongo/label/label_service.go  | 16 ++++++
 server/service/service.go                    |  6 +++
 9 files changed, 217 insertions(+), 15 deletions(-)

diff --git a/pkg/model/db_schema.go b/pkg/model/db_schema.go
index 4feaf42..535e495 100644
--- a/pkg/model/db_schema.go
+++ b/pkg/model/db_schema.go
@@ -24,6 +24,7 @@ type LabelDoc struct {
        Format  string            `bson:"format,omitempty"`
        Domain  string            `json:"domain,omitempty" 
yaml:"domain,omitempty"` //tenant info
        Project string            `json:"project,omitempty" 
yaml:"project,omitempty"`
+       Alias   string            `json:"alias,omitempty" 
yaml:"alias,omitempty"`
 }
 
 //KVDoc is database struct to store kv
diff --git a/server/resource/v1/label_resouce.go 
b/server/resource/v1/label_resouce.go
new file mode 100644
index 0000000..a29a865
--- /dev/null
+++ b/server/resource/v1/label_resouce.go
@@ -0,0 +1,81 @@
+package v1
+
+import (
+       "github.com/apache/servicecomb-kie/pkg/common"
+       "github.com/apache/servicecomb-kie/pkg/model"
+       "github.com/apache/servicecomb-kie/server/service"
+       goRestful "github.com/emicklei/go-restful"
+       "github.com/go-chassis/go-chassis/server/restful"
+       "github.com/go-mesh/openlogging"
+       "net/http"
+)
+
+//LabelResource
+type LabelResource struct {
+}
+
+//PutLabel
+// update by label_id , only can modify alias
+// create return 201 / update return 200
+func (r *LabelResource) PutLabel(context *restful.Context) {
+       var err error
+       entity := new(model.LabelDoc)
+       if err = readRequest(context, entity); err != nil {
+               WriteErrResponse(context, http.StatusBadRequest, err.Error(), 
common.ContentTypeText)
+               return
+       }
+       entity.Project = context.ReadPathParameter("project")
+       domain := ReadDomain(context)
+       if domain == nil {
+               WriteErrResponse(context, http.StatusInternalServerError, 
MsgDomainMustNotBeEmpty, common.ContentTypeText)
+               return
+       }
+       entity.Domain = domain.(string)
+       res, err := service.LabelService.CreateOrUpdate(context.Ctx, entity)
+       if err != nil {
+               if err == service.ErrRevisionNotExist {
+                       WriteErrResponse(context, http.StatusNotFound, 
err.Error(), common.ContentTypeText)
+                       return
+               }
+               WriteErrResponse(context, http.StatusInternalServerError, 
err.Error(), common.ContentTypeText)
+               return
+       }
+       if res == nil {
+               WriteErrResponse(context, http.StatusNotFound, "put alias 
fail", common.ContentTypeText)
+               return
+       }
+       if entity.ID == "" {
+               context.WriteHeader(http.StatusCreated)
+       }
+       err = writeResponse(context, res)
+       if err != nil {
+               openlogging.Error(err.Error())
+       }
+}
+
+//URLPatterns defined config operations
+func (r *LabelResource) URLPatterns() []restful.Route {
+       return []restful.Route{
+               {
+                       Method:       http.MethodPut,
+                       Path:         "/v1/{project}/kie/label",
+                       ResourceFunc: r.PutLabel,
+                       FuncDesc:     "put alias for label or create new label",
+                       Parameters: []*restful.Parameters{
+                               DocPathProject, DocPathKeyID,
+                       },
+                       Returns: []*restful.Returns{
+                               {
+                                       Code:    http.StatusOK,
+                                       Message: "update success",
+                               },
+                               {
+                                       Code:    http.StatusCreated,
+                                       Message: "create success",
+                               },
+                       },
+                       Consumes: []string{goRestful.MIME_JSON, 
common.ContentTypeYaml},
+                       Produces: []string{goRestful.MIME_JSON, 
common.ContentTypeYaml},
+               },
+       }
+}
diff --git a/server/resource/v1/label_resouce_test.go 
b/server/resource/v1/label_resouce_test.go
new file mode 100644
index 0000000..6f7a567
--- /dev/null
+++ b/server/resource/v1/label_resouce_test.go
@@ -0,0 +1,75 @@
+package v1_test
+
+import (
+       "bytes"
+       "context"
+       "encoding/json"
+       "github.com/apache/servicecomb-kie/pkg/model"
+       handler2 "github.com/apache/servicecomb-kie/server/handler"
+       v1 "github.com/apache/servicecomb-kie/server/resource/v1"
+       "github.com/apache/servicecomb-kie/server/service"
+       "github.com/go-chassis/go-chassis/core/common"
+       "github.com/go-chassis/go-chassis/core/handler"
+       "github.com/go-chassis/go-chassis/server/restful/restfultest"
+       "github.com/stretchr/testify/assert"
+       "io/ioutil"
+       "net/http"
+       "net/http/httptest"
+       "testing"
+)
+
+func TestLabelResource_PutLabel(t *testing.T) {
+       t.Run("update label alias", func(t *testing.T) {
+               kv := &model.KVDoc{
+                       Key:   "test",
+                       Value: "revisions",
+                       Labels: map[string]string{
+                               "test": "revisions",
+                       },
+                       Domain:  "default",
+                       Project: "test",
+               }
+               kv, _ = service.KVService.CreateOrUpdate(context.Background(), 
kv)
+               j := []byte("{\"alias\":\"test\",\"id\":\"" + kv.LabelID + 
"\"}")
+               r, _ := http.NewRequest("PUT", "/v1/test/kie/label", 
bytes.NewBuffer(j))
+               r.Header.Add("Content-Type", "application/json")
+               revision := &v1.LabelResource{}
+               noopH := &handler2.NoopAuthHandler{}
+               chain, _ := handler.CreateChain(common.Provider, "testchain2", 
noopH.Name())
+               c, err := restfultest.New(revision, chain)
+               assert.NoError(t, err)
+               resp := httptest.NewRecorder()
+               c.ServeHTTP(resp, r)
+               body, err := ioutil.ReadAll(resp.Body)
+               assert.NoError(t, err)
+               data := &model.LabelDoc{}
+               err = json.Unmarshal(body, &data)
+               assert.NoError(t, err)
+               assert.Equal(t, data.Alias, "test")
+       })
+       t.Run("put label", func(t *testing.T) {
+               label := &model.LabelDoc{
+                       Labels: map[string]string{
+                               "test": "revisions",
+                       },
+                       Domain:  "default",
+                       Project: "test",
+               }
+               j, _ := json.Marshal(label)
+               r, _ := http.NewRequest("PUT", "/v1/test/kie/label", 
bytes.NewBuffer(j))
+               r.Header.Add("Content-Type", "application/json")
+               revision := &v1.LabelResource{}
+               noopH := &handler2.NoopAuthHandler{}
+               chain, _ := handler.CreateChain(common.Provider, "testchain2", 
noopH.Name())
+               c, err := restfultest.New(revision, chain)
+               assert.NoError(t, err)
+               resp := httptest.NewRecorder()
+               c.ServeHTTP(resp, r)
+               body, err := ioutil.ReadAll(resp.Body)
+               assert.NoError(t, err)
+               data := &model.LabelDoc{}
+               err = json.Unmarshal(body, &data)
+               assert.NoError(t, err)
+               //      assert.NotEmpty(t, data.ID)
+       })
+}
diff --git a/server/service/mongo/init.go b/server/service/mongo/init.go
index 0b81c09..8f57b60 100644
--- a/server/service/mongo/init.go
+++ b/server/service/mongo/init.go
@@ -22,6 +22,7 @@ import (
        "github.com/apache/servicecomb-kie/server/service/mongo/counter"
        "github.com/apache/servicecomb-kie/server/service/mongo/history"
        "github.com/apache/servicecomb-kie/server/service/mongo/kv"
+       "github.com/apache/servicecomb-kie/server/service/mongo/label"
        "github.com/apache/servicecomb-kie/server/service/mongo/session"
        "github.com/go-mesh/openlogging"
 )
@@ -32,4 +33,5 @@ func init() {
        service.KVService = &kv.Service{}
        service.HistoryService = &history.Service{}
        service.RevisionService = &counter.Service{}
+       service.LabelService = &label.Service{}
 }
diff --git a/server/service/mongo/kv/kv_service.go 
b/server/service/mongo/kv/kv_service.go
index 49bd7ef..d0b3393 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -56,8 +56,12 @@ func (s *Service) CreateOrUpdate(ctx context.Context, kv 
*model.KVDoc) (*model.K
        labelID, err := label.Exist(ctx, kv.Domain, kv.Project, kv.Labels)
        if err != nil {
                if err == session.ErrLabelNotExists {
-                       var l *model.LabelDoc
-                       l, err = label.CreateLabel(ctx, kv.Domain, kv.Labels, 
kv.Project)
+                       l := &model.LabelDoc{
+                               Domain:  kv.Domain,
+                               Labels:  kv.Labels,
+                               Project: kv.Project,
+                       }
+                       l, err = label.CreateLabel(ctx, l)
                        if err != nil {
                                openlogging.Error("create label failed", 
openlogging.WithTags(openlogging.Tags{
                                        "k":      kv.Key,
diff --git a/server/service/mongo/label/label_dao.go 
b/server/service/mongo/label/label_dao.go
index 9decc40..5a75283 100644
--- a/server/service/mongo/label/label_dao.go
+++ b/server/service/mongo/label/label_dao.go
@@ -22,10 +22,12 @@ import (
        "fmt"
        "github.com/apache/servicecomb-kie/pkg/model"
        "github.com/apache/servicecomb-kie/pkg/stringutil"
+       "github.com/apache/servicecomb-kie/server/service"
        "github.com/apache/servicecomb-kie/server/service/mongo/session"
        "github.com/go-mesh/openlogging"
        uuid "github.com/satori/go.uuid"
        "go.mongodb.org/mongo-driver/bson"
+       "go.mongodb.org/mongo-driver/bson/primitive"
 )
 
 const (
@@ -84,18 +86,28 @@ func Exist(ctx context.Context, domain string, project 
string, labels map[string
 }
 
 //CreateLabel create a new label
-func CreateLabel(ctx context.Context, domain string, labels map[string]string, 
project string) (*model.LabelDoc, error) {
-       l := &model.LabelDoc{
-               Domain:  domain,
-               Labels:  labels,
-               Format:  stringutil.FormatMap(labels),
-               Project: project,
-               ID:      uuid.NewV4().String(),
-       }
+func CreateLabel(ctx context.Context, label *model.LabelDoc) (*model.LabelDoc, 
error) {
+       label.ID = uuid.NewV4().String()
+       label.Format = stringutil.FormatMap(label.Labels)
        collection := session.GetDB().Collection(session.CollectionLabel)
-       _, err := collection.InsertOne(ctx, l)
+       _, err := collection.InsertOne(ctx, label)
        if err != nil {
                return nil, err
        }
-       return l, nil
+       return label, nil
+}
+
+//UpdateLabel
+func UpdateLabel(ctx context.Context, label *model.LabelDoc) (*model.LabelDoc, 
error) {
+       collection := session.GetDB().Collection(session.CollectionLabel)
+       queryFilter := bson.M{"id": label.ID}
+       if label.Alias == "" {
+               return nil, service.ErrAliasNotGiven
+       }
+       updateFilter := bson.D{primitive.E{Key: "$set", Value: bson.M{"alias": 
label.Alias}}}
+       cur := collection.FindOneAndUpdate(ctx, queryFilter, updateFilter)
+       if cur.Err() != nil {
+               return nil, cur.Err()
+       }
+       return label, nil
 }
diff --git a/server/service/mongo/label/label_dao_test.go 
b/server/service/mongo/label/label_dao_test.go
index 4de4909..8ca80d2 100644
--- a/server/service/mongo/label/label_dao_test.go
+++ b/server/service/mongo/label/label_dao_test.go
@@ -19,6 +19,7 @@ package label_test
 
 import (
        "context"
+       "github.com/apache/servicecomb-kie/pkg/model"
        "github.com/apache/servicecomb-kie/server/config"
        "github.com/apache/servicecomb-kie/server/service/mongo/label"
        "github.com/apache/servicecomb-kie/server/service/mongo/session"
@@ -31,12 +32,16 @@ func TestCreateLabel(t *testing.T) {
        config.Configurations = &config.Config{DB: config.DB{URI: 
"mongodb://kie:[email protected]:27017/kie"}}
        err = session.Init()
        assert.NoError(t, err)
-       d, err := label.CreateLabel(context.TODO(), "default",
-               map[string]string{
+       d := &model.LabelDoc{
+               Domain: "default",
+               Labels: map[string]string{
                        "cluster":   "a",
                        "role":      "b",
                        "component": "c",
-               }, "default")
+               },
+               Project: "default",
+       }
+       d, err = label.CreateLabel(context.TODO(), d)
        assert.NoError(t, err)
        assert.NotEmpty(t, d.ID)
        assert.Equal(t, "cluster=a::component=c::role=b", d.Format)
diff --git a/server/service/mongo/label/label_service.go 
b/server/service/mongo/label/label_service.go
new file mode 100644
index 0000000..1ae2904
--- /dev/null
+++ b/server/service/mongo/label/label_service.go
@@ -0,0 +1,16 @@
+package label
+
+import (
+       "context"
+       "github.com/apache/servicecomb-kie/pkg/model"
+)
+
+type Service struct {
+}
+
+func (s *Service) CreateOrUpdate(ctx context.Context, label *model.LabelDoc) 
(*model.LabelDoc, error) {
+       if label.ID != "" {
+               return UpdateLabel(ctx, label)
+       }
+       return CreateLabel(ctx, label)
+}
diff --git a/server/service/service.go b/server/service/service.go
index 67fb9e8..60945f3 100644
--- a/server/service/service.go
+++ b/server/service/service.go
@@ -29,12 +29,14 @@ var (
        HistoryService  History
        RevisionService Revision
        DBInit          Init
+       LabelService    Label
 )
 
 //db errors
 var (
        ErrKeyNotExists     = errors.New("key with labels does not exits")
        ErrRevisionNotExist = errors.New("revision does not exist")
+       ErrAliasNotGiven    = errors.New("label alias not given")
 )
 
 //KV provide api of KV entity
@@ -55,5 +57,9 @@ type Revision interface {
        GetRevision(ctx context.Context, domain string) (int64, error)
 }
 
+type Label interface {
+       CreateOrUpdate(ctx context.Context, label *model.LabelDoc) 
(*model.LabelDoc, error)
+}
+
 //Init init db session
 type Init func() error

Reply via email to