[ 
https://issues.apache.org/jira/browse/SCB-901?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16608507#comment-16608507
 ] 

ASF GitHub Bot commented on SCB-901:
------------------------------------

asifdxtreme closed pull request #439: SCB-901 Making service registration api 
idempotent
URL: https://github.com/apache/incubator-servicecomb-service-center/pull/439
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/server/plugin/infra/registry/embededetcd/embededetcd.go 
b/server/plugin/infra/registry/embededetcd/embededetcd.go
index 0f408397..c0f19499 100644
--- a/server/plugin/infra/registry/embededetcd/embededetcd.go
+++ b/server/plugin/infra/registry/embededetcd/embededetcd.go
@@ -342,9 +342,21 @@ func (s *EtcdEmbed) TxnWithCmp(ctx context.Context, 
success []registry.PluginOp,
        if err != nil {
                return nil, err
        }
+
+       var rangeResponse etcdserverpb.RangeResponse
+       for _, itf := range resp.Responses {
+               if rr, ok := 
itf.Response.(*etcdserverpb.ResponseOp_ResponseRange); ok {
+                       // plz request the same type range kv in txn 
success/fail options
+                       rangeResponse.Kvs = append(rangeResponse.Kvs, 
rr.ResponseRange.Kvs...)
+                       rangeResponse.Count += rr.ResponseRange.Count
+               }
+       }
+
        return &registry.PluginResponse{
                Succeeded: resp.Succeeded,
                Revision:  resp.Header.Revision,
+               Kvs:       rangeResponse.Kvs,
+               Count:     rangeResponse.Count,
        }, nil
 }
 
diff --git a/server/plugin/infra/registry/etcd/etcd.go 
b/server/plugin/infra/registry/etcd/etcd.go
index b5674619..dbbfa12d 100644
--- a/server/plugin/infra/registry/etcd/etcd.go
+++ b/server/plugin/infra/registry/etcd/etcd.go
@@ -28,6 +28,7 @@ import (
        mgr 
"github.com/apache/incubator-servicecomb-service-center/server/plugin"
        "github.com/coreos/etcd/clientv3"
        "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
+       "github.com/coreos/etcd/etcdserver/etcdserverpb"
        "github.com/coreos/etcd/mvcc/mvccpb"
        "golang.org/x/net/context"
        "google.golang.org/grpc"
@@ -566,9 +567,21 @@ func (c *EtcdClient) TxnWithCmp(ctx context.Context, 
success []registry.PluginOp
        }
        log.LogNilOrWarnf(start, "registry client txn {if(%v): %s, then: %d, 
else: %d}, rev: %d",
                resp.Succeeded, cmps, len(success), len(fail), 
resp.Header.Revision)
+
+       var rangeResponse etcdserverpb.RangeResponse
+       for _, itf := range resp.Responses {
+               if rr, ok := 
itf.Response.(*etcdserverpb.ResponseOp_ResponseRange); ok {
+                       // plz request the same type range kv in txn 
success/fail options
+                       rangeResponse.Kvs = append(rangeResponse.Kvs, 
rr.ResponseRange.Kvs...)
+                       rangeResponse.Count += rr.ResponseRange.Count
+               }
+       }
+
        return &registry.PluginResponse{
                Succeeded: resp.Succeeded,
                Revision:  resp.Header.Revision,
+               Kvs:       rangeResponse.Kvs,
+               Count:     rangeResponse.Count,
        }, nil
 }
 
diff --git a/server/plugin/infra/registry/etcd/etcd_test.go 
b/server/plugin/infra/registry/etcd/etcd_test.go
index 067b713a..a6c7c6a1 100644
--- a/server/plugin/infra/registry/etcd/etcd_test.go
+++ b/server/plugin/infra/registry/etcd/etcd_test.go
@@ -398,6 +398,18 @@ func TestEtcdClient_Txn(t *testing.T) {
                t.Fatalf("TestEtcdClient failed, %#v", err)
        }
 
+       // case: range request
+       resp, err = etcd.TxnWithCmp(context.Background(), nil, 
[]registry.CompareOp{
+               {[]byte("/test_txn/c"), registry.CMP_VALUE, registry.CMP_EQUAL, 
"c"},
+       }, []registry.PluginOp{
+               {Action: registry.Get, Key: []byte("/test_txn/a")},
+               {Action: registry.Get, Key: []byte("/test_txn/"), Prefix: true},
+       })
+       if err != nil || resp == nil || resp.Succeeded || resp.Count != 3 { // 
a + [a,b]
+               t.Fatalf("TestEtcdClient failed, %#v", err)
+       }
+
+       // case: test key not exist
        resp, err = etcd.TxnWithCmp(context.Background(), []registry.PluginOp{
                {Action: registry.Put, Key: []byte("/test_txn/a"), Value: 
[]byte("a")},
                {Action: registry.Put, Key: []byte("/test_txn/b"), Value: 
[]byte("b")},
diff --git a/server/service/microservice.go b/server/service/microservice.go
index 389b5b9e..d93c537b 100644
--- a/server/service/microservice.go
+++ b/server/service/microservice.go
@@ -111,11 +111,10 @@ func (s *MicroServiceService) CreateServicePri(ctx 
context.Context, in *pb.Creat
        }
 
        // 产生全局service id
-       serviceId := in.Service.ServiceId
-       if len(serviceId) == 0 {
-               serviceId = plugin.Plugins().UUID().GetServiceId()
+       requestServiceId := service.ServiceId
+       if len(requestServiceId) == 0 {
+               service.ServiceId = plugin.Plugins().UUID().GetServiceId()
        }
-       service.ServiceId = serviceId
        service.Timestamp = strconv.FormatInt(time.Now().Unix(), 10)
        service.ModTimestamp = service.Timestamp
 
@@ -127,7 +126,7 @@ func (s *MicroServiceService) CreateServicePri(ctx 
context.Context, in *pb.Creat
                        Response: pb.CreateResponse(scerr.ErrInternal, 
err.Error()),
                }, err
        }
-       key := apt.GenerateServiceKey(domainProject, serviceId)
+       key := apt.GenerateServiceKey(domainProject, service.ServiceId)
        keyBytes := util.StringToBytesWithNoCopy(key)
        index := apt.GenerateServiceIndexKey(serviceKey)
        indexBytes := util.StringToBytesWithNoCopy(index)
@@ -135,20 +134,24 @@ func (s *MicroServiceService) CreateServicePri(ctx 
context.Context, in *pb.Creat
 
        opts := []registry.PluginOp{
                registry.OpPut(registry.WithKey(keyBytes), 
registry.WithValue(data)),
-               registry.OpPut(registry.WithKey(indexBytes), 
registry.WithStrValue(serviceId)),
+               registry.OpPut(registry.WithKey(indexBytes), 
registry.WithStrValue(service.ServiceId)),
        }
        uniqueCmpOpts := []registry.CompareOp{
                registry.OpCmp(registry.CmpVer(indexBytes), registry.CMP_EQUAL, 
0),
                registry.OpCmp(registry.CmpVer(keyBytes), registry.CMP_EQUAL, 
0),
        }
+       failOpts := []registry.PluginOp{
+               registry.OpGet(registry.WithKey(indexBytes)),
+       }
 
        if len(serviceKey.Alias) > 0 {
-               opts = append(opts, 
registry.OpPut(registry.WithKey(aliasBytes), registry.WithStrValue(serviceId)))
+               opts = append(opts, 
registry.OpPut(registry.WithKey(aliasBytes), 
registry.WithStrValue(service.ServiceId)))
                uniqueCmpOpts = append(uniqueCmpOpts,
                        registry.OpCmp(registry.CmpVer(aliasBytes), 
registry.CMP_EQUAL, 0))
+               failOpts = append(failOpts, 
registry.OpGet(registry.WithKey(aliasBytes)))
        }
 
-       resp, err := backend.Registry().TxnWithCmp(ctx, opts, uniqueCmpOpts, 
nil)
+       resp, err := backend.Registry().TxnWithCmp(ctx, opts, uniqueCmpOpts, 
failOpts)
        if err != nil {
                log.Errorf(err, "create micro-service failed, %s: commit data 
into etcd failed. operator: %s",
                        serviceFlag, remoteIP)
@@ -157,22 +160,33 @@ func (s *MicroServiceService) CreateServicePri(ctx 
context.Context, in *pb.Creat
                }, err
        }
        if !resp.Succeeded {
-               if s.isCreateServiceEx(in) == true {
-                       serviceIdInner, _ := serviceUtil.GetServiceId(ctx, 
serviceKey)
-                       log.Warnf("create micro-service failed, serviceId = %s 
, flag = %s: service already exists. operator: %s",
-                               serviceIdInner, serviceFlag, remoteIP)
+               if len(requestServiceId) != 0 {
+                       if len(resp.Kvs) == 0 ||
+                               requestServiceId != 
util.BytesToStringWithNoCopy(resp.Kvs[0].Value) {
+                               log.Warnf("create micro-service failed, %s: 
service already exists. operator: %s",
+                                       serviceFlag, remoteIP)
+                               return &pb.CreateServiceResponse{
+                                       Response: 
pb.CreateResponse(scerr.ErrServiceAlreadyExists,
+                                               "ServiceId conflict or found 
the same service with different id."),
+                               }, nil
+                       }
+               }
 
+               if len(resp.Kvs) == 0 {
+                       // internal error?
+                       log.Errorf(nil, "create micro-service failed, %s: 
unexpected txn response. operator: %s",
+                               serviceFlag, remoteIP)
                        return &pb.CreateServiceResponse{
-                               Response:  
pb.CreateResponse(pb.Response_SUCCESS, "register service successfully"),
-                               ServiceId: serviceIdInner,
+                               Response: pb.CreateResponse(scerr.ErrInternal, 
"Unexpected txn response."),
                        }, nil
                }
 
-               log.Warnf("create micro-service failed, %s: service already 
exists. operator: %s",
-                       serviceFlag, remoteIP)
-
+               serviceIdInner := 
util.BytesToStringWithNoCopy(resp.Kvs[0].Value)
+               log.Warnf("create micro-service failed, serviceId = %s , flag = 
%s: service already exists. operator: %s",
+                       serviceIdInner, serviceFlag, remoteIP)
                return &pb.CreateServiceResponse{
-                       Response: 
pb.CreateResponse(scerr.ErrServiceAlreadyExists, "Service already exists."),
+                       Response:  pb.CreateResponse(pb.Response_SUCCESS, 
"register service successfully"),
+                       ServiceId: serviceIdInner,
                }, nil
        }
 
@@ -184,7 +198,7 @@ func (s *MicroServiceService) CreateServicePri(ctx 
context.Context, in *pb.Creat
                serviceFlag, service.ServiceId, remoteIP)
        return &pb.CreateServiceResponse{
                Response:  pb.CreateResponse(pb.Response_SUCCESS, "Register 
service successfully."),
-               ServiceId: serviceId,
+               ServiceId: service.ServiceId,
        }, nil
 }
 
diff --git a/server/service/microservice_test.go 
b/server/service/microservice_test.go
index edbfbdf8..e9de3259 100644
--- a/server/service/microservice_test.go
+++ b/server/service/microservice_test.go
@@ -213,7 +213,8 @@ var _ = Describe("'Micro-service' service", func() {
                                        },
                                })
                                Expect(err).To(BeNil())
-                               
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceAlreadyExists))
+                               
Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(resp.ServiceId).To(Equal(sameId))
 
                                By("the same alias")
                                resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
@@ -230,9 +231,64 @@ var _ = Describe("'Micro-service' service", func() {
                                        },
                                })
                                Expect(err).To(BeNil())
-                               
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceAlreadyExists))
+                               
Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(resp.ServiceId).To(Equal(sameId))
+
+                               By("the same serviceId and the same 
serviceName")
+                               resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                                       Service: &pb.MicroService{
+                                               ServiceId:   sameId,
+                                               ServiceName: "some-relay",
+                                               Alias:       "sr1",
+                                               AppId:       "default",
+                                               Version:     "1.0.0",
+                                               Level:       "FRONT",
+                                               Schemas: []string{
+                                                       "xxxxxxxx",
+                                               },
+                                               Status: "UP",
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(resp.ServiceId).To(Equal(sameId))
+
+                               By("the same serviceId and the same alias")
+                               resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                                       Service: &pb.MicroService{
+                                               ServiceId:   sameId,
+                                               ServiceName: "some-relay1",
+                                               Alias:       "sr",
+                                               AppId:       "default",
+                                               Version:     "1.0.0",
+                                               Level:       "FRONT",
+                                               Schemas: []string{
+                                                       "xxxxxxxx",
+                                               },
+                                               Status: "UP",
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
+                               Expect(resp.ServiceId).To(Equal(sameId))
 
                                By("the same service key but with diff 
serviceId")
+                               resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                                       Service: &pb.MicroService{
+                                               ServiceId:   "customId",
+                                               ServiceName: "some-relay",
+                                               Alias:       "sr1",
+                                               AppId:       "default",
+                                               Version:     "1.0.0",
+                                               Level:       "FRONT",
+                                               Schemas: []string{
+                                                       "xxxxxxxx",
+                                               },
+                                               Status: "UP",
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceAlreadyExists))
                                resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
                                        Service: &pb.MicroService{
                                                ServiceId:   "customId",
@@ -250,12 +306,12 @@ var _ = Describe("'Micro-service' service", func() {
                                Expect(err).To(BeNil())
                                
Expect(resp.Response.Code).To(Equal(scerr.ErrServiceAlreadyExists))
 
-                               By("the same serviceId")
+                               By("the same service id but with diff key")
                                resp, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
                                        Service: &pb.MicroService{
                                                ServiceId:   sameId,
-                                               ServiceName: "some-relay1",
-                                               Alias:       "sr",
+                                               ServiceName: "some-relay2",
+                                               Alias:       "sr2",
                                                AppId:       "default",
                                                Version:     "1.0.0",
                                                Level:       "FRONT",


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Making service registration api idempotent
> ------------------------------------------
>
>                 Key: SCB-901
>                 URL: https://issues.apache.org/jira/browse/SCB-901
>             Project: Apache ServiceComb
>          Issue Type: Improvement
>          Components: Service-Center
>            Reporter: little-cui
>            Assignee: little-cui
>            Priority: Major
>             Fix For: service-center-1.1.0
>
>




--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to