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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6a04d77  [SCB 2094] implement datasource/ms addTags interface (#714)
6a04d77 is described below

commit 6a04d77dfdbf21b6438479b5928dc68e002d1e2d
Author: 萝卜头LJW <[email protected]>
AuthorDate: Fri Oct 16 11:04:21 2020 +0800

    [SCB 2094] implement datasource/ms addTags interface (#714)
    
    1. implement interface
    2. finish unit test
---
 datasource/etcd/ms.go      | 62 ++++++++++++++++++++++++++++-
 datasource/etcd/ms_test.go | 98 ++++++++++++++++++++++++++++++++++++++++++++++
 datasource/ms.go           |  2 +-
 3 files changed, 159 insertions(+), 3 deletions(-)

diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index ff83d9f..8b2b41b 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -1068,8 +1068,66 @@ func (ds *DataSource) ExistSchema(ctx context.Context, 
request *pb.GetExistenceR
        }, nil
 }
 
-func (ds *DataSource) AddTag() {
-       panic("implement me")
+func (ds *DataSource) AddTags(ctx context.Context, in 
*pb.AddServiceTagsRequest) (*pb.AddServiceTagsResponse, error) {
+       remoteIP := util.GetIPFromContext(ctx)
+       domainProject := util.ParseDomainProject(ctx)
+
+       // service id存在性校验
+       if !serviceUtil.ServiceExist(ctx, domainProject, in.ServiceId) {
+               log.Errorf(nil, "add service[%s]'s tags %v failed, service does 
not exist, operator: %s",
+                       in.ServiceId, in.Tags, remoteIP)
+               return &pb.AddServiceTagsResponse{
+                       Response: 
proto.CreateResponse(scerr.ErrServiceNotExists, "Service does not exist."),
+               }, nil
+       }
+
+       addTags := in.Tags
+       res := quota.NewApplyQuotaResource(quota.TagQuotaType, domainProject, 
in.ServiceId, int64(len(addTags)))
+       rst := plugin.Plugins().Quota().Apply4Quotas(ctx, res)
+       errQuota := rst.Err
+       if errQuota != nil {
+               log.Errorf(errQuota, "add service[%s]'s tags %v failed, 
operator: %s", in.ServiceId, addTags, remoteIP)
+               response := &pb.AddServiceTagsResponse{
+                       Response: proto.CreateResponseWithSCErr(errQuota),
+               }
+               if errQuota.InternalError() {
+                       return response, errQuota
+               }
+               return response, nil
+       }
+
+       dataTags, err := serviceUtil.GetTagsUtils(ctx, domainProject, 
in.ServiceId)
+       if err != nil {
+               log.Errorf(err, "add service[%s]'s tags %v failed, get existed 
tag failed, operator: %s",
+                       in.ServiceId, addTags, remoteIP)
+               return &pb.AddServiceTagsResponse{
+                       Response: proto.CreateResponse(scerr.ErrInternal, 
err.Error()),
+               }, err
+       }
+       for key, value := range dataTags {
+               if _, ok := addTags[key]; ok {
+                       continue
+               }
+               addTags[key] = value
+       }
+       dataTags = addTags
+
+       checkErr := serviceUtil.AddTagIntoETCD(ctx, domainProject, 
in.ServiceId, dataTags)
+       if checkErr != nil {
+               log.Errorf(checkErr, "add service[%s]'s tags %v failed, 
operator: %s", in.ServiceId, in.Tags, remoteIP)
+               resp := &pb.AddServiceTagsResponse{
+                       Response: proto.CreateResponseWithSCErr(checkErr),
+               }
+               if checkErr.InternalError() {
+                       return resp, checkErr
+               }
+               return resp, nil
+       }
+
+       log.Infof("add service[%s]'s tags %v successfully, operator: %s", 
in.ServiceId, in.Tags, remoteIP)
+       return &pb.AddServiceTagsResponse{
+               Response: proto.CreateResponse(proto.Response_SUCCESS, "Add 
service tags successfully."),
+       }, nil
 }
 
 func (ds *DataSource) GetTag() {
diff --git a/datasource/etcd/ms_test.go b/datasource/etcd/ms_test.go
index 07a8465..f358f8c 100644
--- a/datasource/etcd/ms_test.go
+++ b/datasource/etcd/ms_test.go
@@ -2775,3 +2775,101 @@ func TestSchema_Exist(t *testing.T) {
                assert.Equal(t, "", resp.Summary)
        })
 }
+
+func TestTag_Add(t *testing.T) {
+       var (
+               serviceId1 string
+               serviceId2 string
+       )
+       // init
+       datasource.Install("etcd", func(opts datasource.Options) 
(datasource.DataSource, error) {
+               return NewDataSource(opts), nil
+       })
+       err := datasource.Init(datasource.Options{
+               Endpoint:       "",
+               PluginImplName: 
datasource.ImplName(archaius.GetString("servicecomb.datasource.name", "etcd")),
+       })
+       assert.NoError(t, err)
+       // create service
+       t.Run("create service", func(t *testing.T) {
+               svc1 := &pb.MicroService{
+                       AppId:       "create_tag_group",
+                       ServiceName: "create_tag_service",
+                       Version:     "1.0.0",
+                       Level:       "FRONT",
+                       Status:      pb.MS_UP,
+               }
+               resp, err := 
datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+                       Service: svc1,
+               })
+               assert.NoError(t, err)
+               assert.NotEqual(t, "", resp.ServiceId)
+               serviceId1 = resp.ServiceId
+
+               svc2 := &pb.MicroService{
+                       AppId:       "create_tag_group",
+                       ServiceName: "create_tag_service",
+                       Version:     "1.0.1",
+                       Level:       "FRONT",
+                       Status:      pb.MS_UP,
+               }
+               resp, err = datasource.Instance().RegisterService(getContext(), 
&pb.CreateServiceRequest{
+                       Service: svc2,
+               })
+               assert.NoError(t, err)
+               assert.NotNil(t, "", resp.ServiceId)
+               serviceId2 = resp.ServiceId
+       })
+
+       t.Run("the request is invalid", func(t *testing.T) {
+               log.Info("service does not exist")
+               resp, err := datasource.Instance().AddTags(getContext(), 
&pb.AddServiceTagsRequest{
+                       ServiceId: "noServiceTest",
+                       Tags: map[string]string{
+                               "a": "test",
+                       },
+               })
+               assert.NoError(t, err)
+               assert.Equal(t, scerr.ErrServiceNotExists, 
resp.Response.GetCode())
+       })
+
+       t.Run("the request is valid", func(t *testing.T) {
+               log.Info("tag quota is equal to the default value and should be 
paas")
+               defaultQuota := quota.DefaultTagQuota
+               tags := make(map[string]string, defaultQuota)
+               for i := 0; i < defaultQuota; i++ {
+                       s := "tag" + strconv.Itoa(i)
+                       tags[s] = s
+               }
+               resp, err := datasource.Instance().AddTags(getContext(), 
&pb.AddServiceTagsRequest{
+                       ServiceId: serviceId1,
+                       Tags:      tags,
+               })
+               assert.NoError(t, err)
+               assert.Equal(t, proto.Response_SUCCESS, resp.Response.GetCode())
+       })
+
+       t.Run("tag's quota exceeded", func(t *testing.T) {
+               log.Info("insufficient tag quota")
+               size := quota.DefaultTagQuota / 2
+               tags := make(map[string]string, size)
+               for i := 0; i < size; i++ {
+                       s := "tag" + strconv.Itoa(i)
+                       tags[s] = s
+               }
+               resp, err := datasource.Instance().AddTags(getContext(), 
&pb.AddServiceTagsRequest{
+                       ServiceId: serviceId2,
+                       Tags:      tags,
+               })
+               assert.NoError(t, err)
+               assert.Equal(t, proto.Response_SUCCESS, resp.Response.GetCode())
+
+               tags["out"] = "range"
+               resp, _ = datasource.Instance().AddTags(getContext(), 
&pb.AddServiceTagsRequest{
+                       ServiceId: serviceId2,
+                       Tags:      tags,
+               })
+               assert.NoError(t, err)
+               assert.Equal(t, scerr.ErrNotEnoughQuota, 
resp.Response.GetCode())
+       })
+}
diff --git a/datasource/ms.go b/datasource/ms.go
index 7db004e..8f07e30 100644
--- a/datasource/ms.go
+++ b/datasource/ms.go
@@ -54,7 +54,7 @@ type MetadataManager interface {
        GetSchema()
        DeleteSchema()
 
-       AddTag()
+       AddTags(ctx context.Context, in *pb.AddServiceTagsRequest) 
(*pb.AddServiceTagsResponse, error)
        GetTag()
        UpdateTag()
        DeleteTag()

Reply via email to