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-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new 9efc568  [feat] add microservice sync func and ut when db mode is etcd 
(#1202)
9efc568 is described below

commit 9efc56892c23668fc62de911a029758fd1b1ce00
Author: robotljw <[email protected]>
AuthorDate: Tue Jan 4 17:50:23 2022 +0800

    [feat] add microservice sync func and ut when db mode is etcd (#1202)
---
 datasource/common.go       |   1 +
 datasource/etcd/ms.go      |  53 +++++++++++++++--
 datasource/etcd/ms_test.go | 144 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/datasource/common.go b/datasource/common.go
index d391864..a3b9453 100644
--- a/datasource/common.go
+++ b/datasource/common.go
@@ -35,6 +35,7 @@ const (
        ResourceAccount    = "account"
        ResourceRole       = "role"
        ResourceDependency = "dependency"
+       ResourceService    = "service"
 )
 
 // WrapErrResponse is temp func here to wait finish to refact the discosvc pkg
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index b3a24c4..2747834 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -25,6 +25,8 @@ import (
        "strconv"
        "time"
 
+       "github.com/go-chassis/cari/sync"
+
        "github.com/apache/servicecomb-service-center/datasource"
        "github.com/apache/servicecomb-service-center/datasource/etcd/cache"
        "github.com/apache/servicecomb-service-center/datasource/etcd/path"
@@ -125,6 +127,19 @@ func (ds *MetadataManager) RegisterService(ctx 
context.Context, request *pb.Crea
                failOpts = append(failOpts, 
etcdadpt.OpGet(etcdadpt.WithStrKey(alias)))
        }
 
+       if datasource.EnableSync {
+               domain := util.ParseDomain(ctx)
+               project := util.ParseProject(ctx)
+               taskOpt, err := GenTaskOpts(domain, project, sync.CreateAction, 
datasource.ResourceService, request)
+               if err != nil {
+                       log.Error("fail to create task", err)
+                       return &pb.CreateServiceResponse{
+                               Response: pb.CreateResponse(pb.ErrInternal, 
err.Error()),
+                       }, err
+               }
+               opts = append(opts, taskOpt)
+       }
+
        resp, err := etcdadpt.TxnWithCmp(ctx, opts, uniqueCmpOpts, failOpts)
        if err != nil {
                log.Error(fmt.Sprintf("create micro-service[%s] failed, 
operator: %s",
@@ -472,11 +487,24 @@ func (ds *MetadataManager) UpdateService(ctx 
context.Context, request *pb.Update
                }, err
        }
 
+       opts := []etcdadpt.OpOptions{
+               etcdadpt.OpPut(etcdadpt.WithStrKey(key), 
etcdadpt.WithValue(data)),
+       }
+       if datasource.EnableSync {
+               domain := util.ParseDomain(ctx)
+               project := util.ParseProject(ctx)
+               taskOpt, err := GenTaskOpts(domain, project, sync.UpdateAction, 
datasource.ResourceService, request)
+               if err != nil {
+                       log.Error("fail to create task", err)
+                       return &pb.UpdateServicePropsResponse{
+                               Response: pb.CreateResponse(pb.ErrInternal, 
err.Error()),
+                       }, err
+               }
+               opts = append(opts, taskOpt)
+       }
+
        // Set key file
-       resp, err := etcdadpt.TxnWithCmp(ctx,
-               etcdadpt.Ops(etcdadpt.OpPut(etcdadpt.WithStrKey(key), 
etcdadpt.WithValue(data))),
-               etcdadpt.If(etcdadpt.NotEqualVer(key, 0)),
-               nil)
+       resp, err := etcdadpt.TxnWithCmp(ctx, opts, 
etcdadpt.If(etcdadpt.NotEqualVer(key, 0)), nil)
        if err != nil {
                log.Error(fmt.Sprintf("update service[%s] properties failed, 
operator: %s", request.ServiceId, remoteIP), err)
                return &pb.UpdateServicePropsResponse{
@@ -2015,6 +2043,23 @@ func (ds *MetadataManager) DeleteServicePri(ctx 
context.Context, serviceID strin
                etcdadpt.OpDel(etcdadpt.WithStrKey(serviceIDKey)),
        }
 
+       if datasource.EnableSync {
+               domain := util.ParseDomain(ctx)
+               project := util.ParseProject(ctx)
+               taskOpt, err := GenTaskOpts(domain, project, sync.DeleteAction, 
datasource.ResourceService,
+                       &pb.DeleteServiceRequest{ServiceId: serviceID, Force: 
force})
+               if err != nil {
+                       log.Error("fail to create task", err)
+                       return pb.CreateResponse(pb.ErrInternal, err.Error()), 
err
+               }
+               tombstoneOpt, err := GenTombstoneOpts(domain, project, 
datasource.ResourceService, serviceID)
+               if err != nil {
+                       log.Error("fail to create tombstone", err)
+                       return pb.CreateResponse(pb.ErrInternal, err.Error()), 
err
+               }
+               opts = append(opts, taskOpt, tombstoneOpt)
+       }
+
        //删除依赖规则
        optDeleteDep, err := 
serviceUtil.DeleteDependencyForDeleteService(domainProject, serviceID, 
serviceKey)
        if err != nil {
diff --git a/datasource/etcd/ms_test.go b/datasource/etcd/ms_test.go
new file mode 100644
index 0000000..4c2ba35
--- /dev/null
+++ b/datasource/etcd/ms_test.go
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except request compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to request writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package etcd_test
+
+import (
+       "context"
+       "testing"
+
+       pb "github.com/go-chassis/cari/discovery"
+       "github.com/go-chassis/cari/sync"
+       "github.com/stretchr/testify/assert"
+
+       "github.com/apache/servicecomb-service-center/datasource"
+       "github.com/apache/servicecomb-service-center/eventbase/model"
+       "github.com/apache/servicecomb-service-center/eventbase/service/task"
+       
"github.com/apache/servicecomb-service-center/eventbase/service/tombstone"
+       "github.com/apache/servicecomb-service-center/pkg/util"
+)
+
+func microServiceGetContext() context.Context {
+       return util.WithNoCache(util.SetDomainProject(context.Background(), 
"sync-micro-service",
+               "sync-micro-service"))
+}
+
+func TestSyncMicroService(t *testing.T) {
+       datasource.EnableSync = true
+
+       var serviceID string
+
+       t.Run("register micro-service", func(t *testing.T) {
+               t.Run("register a micro service will create a task should 
pass", func(t *testing.T) {
+                       resp, err := 
datasource.GetMetadataManager().RegisterService(microServiceGetContext(), 
&pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       AppId:       "sync_micro_service_group",
+                                       ServiceName: "sync_micro_service",
+                                       Version:     "1.0.0",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       assert.NotNil(t, resp)
+                       assert.NoError(t, err)
+                       assert.Equal(t, pb.ResponseSuccess, 
resp.Response.GetCode())
+                       serviceID = resp.ServiceId
+                       listTaskReq := model.ListTaskRequest{
+                               Domain:       "sync-micro-service",
+                               Project:      "sync-micro-service",
+                               ResourceType: datasource.ResourceService,
+                               Action:       sync.CreateAction,
+                               Status:       sync.PendingStatus,
+                       }
+                       tasks, err := task.List(context.Background(), 
&listTaskReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 1, len(tasks))
+                       err = task.Delete(context.Background(), tasks...)
+                       assert.NoError(t, err)
+                       tasks, err = task.List(context.Background(), 
&listTaskReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 0, len(tasks))
+               })
+       })
+
+       t.Run("update micro-service", func(t *testing.T) {
+               t.Run("update a micro service setting sync-test property will 
create a task should pass", func(t *testing.T) {
+                       request := &pb.UpdateServicePropsRequest{
+                               ServiceId:  serviceID,
+                               Properties: make(map[string]string),
+                       }
+                       request.Properties["sync-test"] = "sync-test"
+                       resp, err := 
datasource.GetMetadataManager().UpdateService(microServiceGetContext(), request)
+                       assert.NoError(t, err)
+                       assert.Equal(t, pb.ResponseSuccess, 
resp.Response.GetCode())
+                       listTaskReq := model.ListTaskRequest{
+                               Domain:       "sync-micro-service",
+                               Project:      "sync-micro-service",
+                               ResourceType: datasource.ResourceService,
+                               Action:       sync.UpdateAction,
+                               Status:       sync.PendingStatus,
+                       }
+                       tasks, err := task.List(context.Background(), 
&listTaskReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 1, len(tasks))
+                       err = task.Delete(context.Background(), tasks...)
+                       assert.NoError(t, err)
+                       tasks, err = task.List(context.Background(), 
&listTaskReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 0, len(tasks))
+               })
+       })
+
+       t.Run("unregister micro-service", func(t *testing.T) {
+               t.Run("unregister a micro service will create a task and a 
tombstone should pass", func(t *testing.T) {
+                       resp, err := 
datasource.GetMetadataManager().UnregisterService(microServiceGetContext(), 
&pb.DeleteServiceRequest{
+                               ServiceId: serviceID,
+                               Force:     true,
+                       })
+                       assert.NotNil(t, resp)
+                       assert.NoError(t, err)
+                       assert.Equal(t, pb.ResponseSuccess, 
resp.Response.GetCode())
+                       listTaskReq := model.ListTaskRequest{
+                               Domain:       "sync-micro-service",
+                               Project:      "sync-micro-service",
+                               ResourceType: datasource.ResourceService,
+                               Action:       sync.DeleteAction,
+                               Status:       sync.PendingStatus,
+                       }
+                       tasks, err := task.List(context.Background(), 
&listTaskReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 1, len(tasks))
+                       err = task.Delete(context.Background(), tasks...)
+                       assert.NoError(t, err)
+                       tasks, err = task.List(context.Background(), 
&listTaskReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 0, len(tasks))
+                       tombstoneListReq := model.ListTombstoneRequest{
+                               Domain:       "sync-micro-service",
+                               Project:      "sync-micro-service",
+                               ResourceType: datasource.ResourceService,
+                       }
+                       tombstones, err := tombstone.List(context.Background(), 
&tombstoneListReq)
+                       assert.NoError(t, err)
+                       assert.Equal(t, 1, len(tombstones))
+                       err = tombstone.Delete(context.Background(), 
tombstones...)
+                       assert.NoError(t, err)
+               })
+       })
+
+       datasource.EnableSync = false
+}

Reply via email to