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 426e92a  Fix: Add Dependency API (#1151)
426e92a is described below

commit 426e92a8e96ddcdbb2a6a043862ff47759a0613d
Author: little-cui <[email protected]>
AuthorDate: Fri Sep 10 21:38:26 2021 +0800

    Fix: Add Dependency API (#1151)
---
 datasource/dep.go                                  |   3 +
 datasource/dep_test.go                             | 341 ++++++++++++++++
 datasource/dependency_util.go                      |  14 +-
 datasource/etcd/dep.go                             |  73 +++-
 datasource/etcd/event/dependency_event_handler.go  |  16 +-
 datasource/etcd/ms.go                              |   2 +-
 datasource/etcd/util/dependency_util.go            |  58 +--
 datasource/etcd/util/dependency_util_test.go       |  50 ---
 datasource/mongo/dep.go                            |  64 ++-
 integration/apis.go                                |   1 +
 integration/microservices_test.go                  | 268 +++++++++++-
 pkg/proto/service.go                               |   2 +
 server/rest/controller/v4/dependency_controller.go |  55 +++
 server/service/disco/dependency.go                 |  24 ++
 server/service/disco/dependency_test.go            | 451 +++++++++++++++++++--
 server/service/validator/dependency_validator.go   |  70 ++++
 server/service/validator/validator.go              |   4 +
 17 files changed, 1365 insertions(+), 131 deletions(-)

diff --git a/datasource/dep.go b/datasource/dep.go
index d3cee31..a8e430d 100644
--- a/datasource/dep.go
+++ b/datasource/dep.go
@@ -23,9 +23,12 @@ import (
        pb "github.com/go-chassis/cari/discovery"
 )
 
+const AllVersions = "0.0.0+"
+
 // DependencyManager contains the CRUD of microservice dependencies
 type DependencyManager interface {
        SearchProviderDependency(ctx context.Context, request 
*pb.GetDependenciesRequest) (*pb.GetProDependenciesResponse, error)
        SearchConsumerDependency(ctx context.Context, request 
*pb.GetDependenciesRequest) (*pb.GetConDependenciesResponse, error)
+       AddOrUpdateDependencies(ctx context.Context, dependencyInfos 
[]*pb.ConsumerDependency, override bool) (*pb.Response, error)
        DependencyHandle(ctx context.Context) error
 }
diff --git a/datasource/dep_test.go b/datasource/dep_test.go
index 435d881..da5daba 100644
--- a/datasource/dep_test.go
+++ b/datasource/dep_test.go
@@ -27,6 +27,292 @@ import (
        "github.com/stretchr/testify/assert"
 )
 
+func Test_Create(t *testing.T) {
+       var (
+               consumerId1 string
+               consumerId2 string
+       )
+       resp, err := 
datasource.GetMetadataManager().RegisterService(depGetContext(), 
&pb.CreateServiceRequest{
+               Service: &pb.MicroService{
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_consumer",
+                       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())
+       consumerId1 = resp.ServiceId
+       defer 
datasource.GetMetadataManager().UnregisterService(depGetContext(), 
&pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+       resp, err = 
datasource.GetMetadataManager().RegisterService(depGetContext(), 
&pb.CreateServiceRequest{
+               Service: &pb.MicroService{
+                       Environment: pb.ENV_PROD,
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_consumer",
+                       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())
+       consumerId2 = resp.ServiceId
+       defer 
datasource.GetMetadataManager().UnregisterService(depGetContext(), 
&pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+       resp, err = 
datasource.GetMetadataManager().RegisterService(depGetContext(), 
&pb.CreateServiceRequest{
+               Service: &pb.MicroService{
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_provider",
+                       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())
+       defer 
datasource.GetMetadataManager().UnregisterService(depGetContext(), 
&pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+       resp, err = 
datasource.GetMetadataManager().RegisterService(depGetContext(), 
&pb.CreateServiceRequest{
+               Service: &pb.MicroService{
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_provider",
+                       Version:     "1.0.1",
+                       Level:       "FRONT",
+                       Status:      pb.MS_UP,
+               },
+       })
+       assert.NotNil(t, resp)
+       assert.NoError(t, err)
+       assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+       defer 
datasource.GetMetadataManager().UnregisterService(depGetContext(), 
&pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+       resp, err = 
datasource.GetMetadataManager().RegisterService(depGetContext(), 
&pb.CreateServiceRequest{
+               Service: &pb.MicroService{
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_provider_other",
+                       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())
+       defer 
datasource.GetMetadataManager().UnregisterService(depGetContext(), 
&pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+       resp, err = 
datasource.GetMetadataManager().RegisterService(depGetContext(), 
&pb.CreateServiceRequest{
+               Service: &pb.MicroService{
+                       Environment: pb.ENV_PROD,
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_provider",
+                       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())
+       defer 
datasource.GetMetadataManager().UnregisterService(depGetContext(), 
&pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+       t.Run("add dep and search when request is invalid, should be failed", 
func(t *testing.T) {
+               consumer := &pb.MicroServiceKey{
+                       AppId:       "dep_create_dep_group",
+                       ServiceName: "dep_create_dep_consumer",
+                       Version:     "1.0.0",
+               }
+               providers := []*pb.MicroServiceKey{
+                       {
+                               AppId:       "dep_create_dep_group",
+                               ServiceName: "dep_create_dep_provider",
+                       },
+               }
+
+               // consumer does not exist
+               resp, err := 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer: &pb.MicroServiceKey{
+                                       AppId:       "noexistapp",
+                                       ServiceName: "noexistservice",
+                                       Version:     "1.0.0",
+                               },
+                               Providers: providers,
+                       },
+               }, false)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ErrServiceNotExists, resp.GetCode())
+
+               err = 
datasource.GetDependencyManager().DependencyHandle(getContext())
+               assert.NoError(t, err)
+
+               // provider in diff env
+               resp, err = 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer: consumer,
+                               Providers: []*pb.MicroServiceKey{
+                                       {
+                                               Environment: pb.ENV_PROD,
+                                               AppId:       
"dep_service_group_provider",
+                                               ServiceName: 
"dep_service_name_provider",
+                                       },
+                               },
+                       },
+               }, false)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ResponseSuccess, resp.GetCode())
+
+               //consumer in diff env
+               consumer.Environment = pb.ENV_PROD
+               resp, err = 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer: consumer,
+                               Providers: []*pb.MicroServiceKey{
+                                       {
+                                               AppId:       
"dep_service_group_provider",
+                                               ServiceName: 
"dep_service_name_provider",
+                                       },
+                               },
+                       },
+               }, false)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ResponseSuccess, resp.GetCode())
+
+               err = 
datasource.GetDependencyManager().DependencyHandle(getContext())
+               assert.NoError(t, err)
+
+               respCon, err := 
datasource.GetDependencyManager().SearchConsumerDependency(depGetContext(), 
&pb.GetDependenciesRequest{
+                       ServiceId: consumerId1,
+               })
+               assert.NotNil(t, respCon)
+               assert.NoError(t, err)
+               assert.Equal(t, 0, len(respCon.Providers))
+
+               respCon, err = 
datasource.GetDependencyManager().SearchConsumerDependency(depGetContext(), 
&pb.GetDependenciesRequest{
+                       ServiceId: consumerId2,
+               })
+               assert.NotNil(t, respCon)
+               assert.NoError(t, err)
+               assert.Equal(t, 0, len(respCon.Providers))
+       })
+
+       t.Run("add dep and search when request is valid, should be passed", 
func(t *testing.T) {
+               consumer := &pb.MicroServiceKey{
+                       ServiceName: "dep_create_dep_consumer",
+                       AppId:       "dep_create_dep_group",
+                       Version:     "1.0.0",
+               }
+
+               resp, err := 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer: consumer,
+                               Providers: []*pb.MicroServiceKey{
+                                       {
+                                               AppId:       
"dep_create_dep_group",
+                                               ServiceName: 
"dep_create_dep_provider",
+                                       },
+                               },
+                       },
+               }, false)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ResponseSuccess, resp.GetCode())
+
+               err = 
datasource.GetDependencyManager().DependencyHandle(getContext())
+               assert.NoError(t, err)
+
+               respPro, err := 
datasource.GetDependencyManager().SearchConsumerDependency(depGetContext(), 
&pb.GetDependenciesRequest{
+                       ServiceId: consumerId1,
+               })
+               assert.NotNil(t, respPro)
+               assert.NoError(t, err)
+               assert.Equal(t, 2, len(respPro.Providers))
+
+               // add multiple providers
+               resp, err = 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer: consumer,
+                               Providers: []*pb.MicroServiceKey{
+                                       {
+                                               AppId:       
"dep_create_dep_group",
+                                               ServiceName: 
"dep_create_dep_provider",
+                                       },
+                                       {
+                                               AppId:       
"dep_create_dep_group",
+                                               ServiceName: 
"dep_create_dep_provider_other",
+                                       },
+                               },
+                       },
+               }, false)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ResponseSuccess, resp.GetCode())
+
+               err = 
datasource.GetDependencyManager().DependencyHandle(getContext())
+               assert.NoError(t, err)
+
+               respPro, err = 
datasource.GetDependencyManager().SearchConsumerDependency(depGetContext(), 
&pb.GetDependenciesRequest{
+                       ServiceId: consumerId1,
+               })
+               assert.NotNil(t, respPro)
+               assert.NoError(t, err)
+               assert.Equal(t, 3, len(respPro.Providers))
+
+               // override
+               resp, err = 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer: consumer,
+                               Providers: []*pb.MicroServiceKey{
+                                       {
+                                               AppId:       
"dep_create_dep_group",
+                                               ServiceName: 
"dep_create_dep_provider",
+                                       },
+                               },
+                       },
+               }, true)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ResponseSuccess, resp.GetCode())
+               err = 
datasource.GetDependencyManager().DependencyHandle(getContext())
+               assert.NoError(t, err)
+
+               respPro, err = 
datasource.GetDependencyManager().SearchConsumerDependency(depGetContext(), 
&pb.GetDependenciesRequest{
+                       ServiceId: consumerId1,
+               })
+               assert.NotNil(t, respPro)
+               assert.NoError(t, err)
+               assert.Equal(t, 2, len(respPro.Providers))
+
+               // clean all
+               resp, err = 
datasource.GetDependencyManager().AddOrUpdateDependencies(depGetContext(), 
[]*pb.ConsumerDependency{
+                       {
+                               Consumer:  consumer,
+                               Providers: nil,
+                       },
+               }, true)
+               assert.NotNil(t, resp)
+               assert.NoError(t, err)
+               assert.Equal(t, pb.ResponseSuccess, resp.GetCode())
+
+               err = 
datasource.GetDependencyManager().DependencyHandle(getContext())
+               assert.NoError(t, err)
+
+               respPro, err = 
datasource.GetDependencyManager().SearchConsumerDependency(depGetContext(), 
&pb.GetDependenciesRequest{
+                       ServiceId: consumerId1,
+               })
+               assert.NotNil(t, respPro)
+               assert.NoError(t, err)
+               assert.Equal(t, 0, len(respPro.Providers))
+       })
+}
+
 func Test_Get(t *testing.T) {
        var (
                consumerId1 string
@@ -243,3 +529,58 @@ func Test_Get(t *testing.T) {
 func depGetContext() context.Context {
        return util.WithNoCache(util.SetDomainProject(context.Background(), 
"new_default", "new_default"))
 }
+
+func TestParamsChecker(t *testing.T) {
+       p := datasource.ParamsChecker(nil, nil)
+       assert.Nil(t, p)
+
+       p = datasource.ParamsChecker(&pb.MicroServiceKey{
+               AppId:       "a",
+               ServiceName: "b",
+               Version:     "1.0.0",
+       }, nil)
+       assert.Nil(t, p)
+
+       producer := &pb.MicroServiceKey{ServiceName: "*"}
+       p = datasource.ParamsChecker(&pb.MicroServiceKey{
+               AppId:       "a",
+               ServiceName: "b",
+               Version:     "1.0.0",
+       }, []*pb.MicroServiceKey{
+               producer,
+       })
+       assert.Nil(t, p)
+       assert.Equal(t, "a", producer.AppId)
+       assert.Equal(t, "0.0.0+", producer.Version)
+
+       producer.ServiceName = "a"
+       producer.Version = "1"
+       p = datasource.ParamsChecker(&pb.MicroServiceKey{
+               AppId:       "a",
+               ServiceName: "b",
+               Version:     "1.0.0",
+       }, []*pb.MicroServiceKey{
+               producer,
+       })
+       assert.Nil(t, p)
+       assert.Equal(t, "0.0.0+", producer.Version)
+
+       p = datasource.ParamsChecker(&pb.MicroServiceKey{
+               AppId:       "a",
+               ServiceName: "b",
+               Version:     "1.0.0",
+       }, []*pb.MicroServiceKey{
+               {},
+       })
+       assert.NotNil(t, p)
+
+       p = datasource.ParamsChecker(&pb.MicroServiceKey{
+               AppId:       "a",
+               ServiceName: "b",
+               Version:     "1.0.0",
+       }, []*pb.MicroServiceKey{
+               {ServiceName: "a", Version: "1"},
+               {ServiceName: "a", Version: "1"},
+       })
+       assert.NotNil(t, p)
+}
diff --git a/datasource/dependency_util.go b/datasource/dependency_util.go
index 6733fbc..f57ce4f 100644
--- a/datasource/dependency_util.go
+++ b/datasource/dependency_util.go
@@ -43,25 +43,17 @@ type Dependency struct {
 func ParamsChecker(consumerInfo *discovery.MicroServiceKey, providersInfo 
[]*discovery.MicroServiceKey) *discovery.CreateDependenciesResponse {
        flag := make(map[string]bool, len(providersInfo))
        for _, providerInfo := range providersInfo {
-               //存在带*的情况,后面的数据就不校验了
-               if providerInfo.ServiceName == "*" {
-                       break
+               if len(providerInfo.ServiceName) == 0 {
+                       return BadParamsResponse("Required provider 
serviceName")
                }
                if len(providerInfo.AppId) == 0 {
                        providerInfo.AppId = consumerInfo.AppId
                }
-
-               version := providerInfo.Version
-               if len(version) == 0 {
-                       return BadParamsResponse("Required provider version")
-               }
-
-               providerInfo.Version = ""
+               providerInfo.Version = AllVersions
                if _, ok := flag[toString(providerInfo)]; ok {
                        return BadParamsResponse("Invalid request body for 
provider info.Duplicate provider or (serviceName and appId is same).")
                }
                flag[toString(providerInfo)] = true
-               providerInfo.Version = version
        }
        return nil
 }
diff --git a/datasource/etcd/dep.go b/datasource/etcd/dep.go
index 884aedb..ba3c837 100644
--- a/datasource/etcd/dep.go
+++ b/datasource/etcd/dep.go
@@ -19,6 +19,7 @@ package etcd
 
 import (
        "context"
+       "encoding/json"
        "errors"
        "fmt"
 
@@ -104,17 +105,71 @@ func (dm *DepManager) DependencyHandle(ctx 
context.Context) error {
        if err != nil {
                return err
        }
-       for {
-               key := path.GetServiceDependencyQueueRootKey("")
-               resp, err := sd.DependencyQueue().Search(ctx,
-                       etcdadpt.WithStrKey(key), etcdadpt.WithPrefix(), 
etcdadpt.WithCountOnly())
+
+       key := path.GetServiceDependencyQueueRootKey("")
+       resp, err := sd.DependencyQueue().Search(ctx,
+               etcdadpt.WithStrKey(key), etcdadpt.WithPrefix(), 
etcdadpt.WithCountOnly())
+       if err != nil {
+               return err
+       }
+       // maintain dependency rules.
+       if resp.Count != 0 {
+               return fmt.Errorf("residual records[%d]", resp.Count)
+       }
+       return nil
+}
+
+func (dm *DepManager) AddOrUpdateDependencies(ctx context.Context, 
dependencyInfos []*pb.ConsumerDependency, override bool) (*pb.Response, error) {
+       opts := make([]etcdadpt.OpOptions, 0, len(dependencyInfos))
+       domainProject := util.ParseDomainProject(ctx)
+       for _, dependencyInfo := range dependencyInfos {
+               consumerFlag := 
util.StringJoin([]string{dependencyInfo.Consumer.Environment, 
dependencyInfo.Consumer.AppId, dependencyInfo.Consumer.ServiceName, 
dependencyInfo.Consumer.Version}, "/")
+               consumerInfo := 
pb.DependenciesToKeys([]*pb.MicroServiceKey{dependencyInfo.Consumer}, 
domainProject)[0]
+               providersInfo := 
pb.DependenciesToKeys(dependencyInfo.Providers, domainProject)
+
+               rsp := datasource.ParamsChecker(consumerInfo, providersInfo)
+               if rsp != nil {
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t, consumer is %s, %s",
+                               override, consumerFlag, 
rsp.Response.GetMessage()), nil)
+                       return rsp.Response, nil
+               }
+
+               consumerID, err := serviceUtil.GetServiceID(ctx, consumerInfo)
+               if err != nil {
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t, get consumer[%s] id failed",
+                               override, consumerFlag), err)
+                       return pb.CreateResponse(pb.ErrInternal, err.Error()), 
err
+               }
+               if len(consumerID) == 0 {
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t, consumer[%s] does not exist",
+                               override, consumerFlag), nil)
+                       return pb.CreateResponse(pb.ErrServiceNotExists, 
fmt.Sprintf("Consumer %s does not exist.", consumerFlag)), nil
+               }
+
+               dependencyInfo.Override = override
+               data, err := json.Marshal(dependencyInfo)
                if err != nil {
-                       return err
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t, marshal consumer[%s] dependency failed",
+                               override, consumerFlag), err)
+                       return pb.CreateResponse(pb.ErrInternal, err.Error()), 
err
                }
-               // maintain dependency rules.
-               if resp.Count == 0 {
-                       break
+
+               id := path.DepsQueueUUID
+               if !override {
+                       id = util.GenerateUUID()
                }
+               key := path.GenerateConsumerDependencyQueueKey(domainProject, 
consumerID, id)
+               opts = append(opts, etcdadpt.OpPut(etcdadpt.WithStrKey(key), 
etcdadpt.WithValue(data)))
        }
-       return nil
+
+       err := etcdadpt.Txn(ctx, opts)
+       if err != nil {
+               log.Error(fmt.Sprintf("put request into dependency queue 
failed, override: %t, %v",
+                       override, dependencyInfos), err)
+               return pb.CreateResponse(pb.ErrInternal, err.Error()), err
+       }
+
+       log.Info(fmt.Sprintf("put request into dependency queue successfully, 
override: %t, %v, from remote %s",
+               override, dependencyInfos, util.GetIPFromContext(ctx)))
+       return pb.CreateResponse(pb.ResponseSuccess, "Create dependency 
successfully."), nil
 }
diff --git a/datasource/etcd/event/dependency_event_handler.go 
b/datasource/etcd/event/dependency_event_handler.go
index 8a78baa..8a427d4 100644
--- a/datasource/etcd/event/dependency_event_handler.go
+++ b/datasource/etcd/event/dependency_event_handler.go
@@ -149,7 +149,10 @@ func (h *DependencyEventHandler) Handle() error {
 
        key := path.GetServiceDependencyQueueRootKey("")
        resp, err := sd.DependencyQueue().Search(context.Background(), 
etcdadpt.WithNoCache(),
-               etcdadpt.WithStrKey(key), etcdadpt.WithPrefix())
+               etcdadpt.WithStrKey(key), etcdadpt.WithPrefix(),
+               etcdadpt.WithOrderByCreate(), etcdadpt.WithAscendOrder(),
+               // get one page
+               etcdadpt.WithLimit(etcdadpt.DefaultPageCount))
        if err != nil {
                return err
        }
@@ -193,11 +196,18 @@ func (h *DependencyEventHandler) dependencyRuleHandle(res 
interface{}) error {
        consumerInfo := 
pb.DependenciesToKeys([]*pb.MicroServiceKey{r.Consumer}, domainProject)[0]
        providersInfo := pb.DependenciesToKeys(r.Providers, domainProject)
 
-       var dep serviceUtil.Dependency
+       var (
+               dep serviceUtil.Dependency
+               err error
+       )
        dep.DomainProject = domainProject
        dep.Consumer = consumerInfo
        dep.ProvidersRule = providersInfo
-       err := serviceUtil.AddDependencyRule(ctx, &dep)
+       if r.Override {
+               err = serviceUtil.CreateDependencyRule(ctx, &dep)
+       } else {
+               err = serviceUtil.AddDependencyRule(ctx, &dep)
+       }
        if err != nil {
                log.Error(fmt.Sprintf("modify dependency rule failed, override: 
%t, consumer %s", r.Override, consumerFlag), err)
                return fmt.Errorf("override: %t, consumer is %s, %s", 
r.Override, consumerFlag, err.Error())
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index ad1b78e..b2c5a4f 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -1020,7 +1020,7 @@ func (ds *MetadataManager) reshapeProviderKey(ctx 
context.Context, provider *pb.
        }
 
        provider = pb.MicroServiceToKey(provider.Tenant, providerService)
-       provider.Version = "0.0.0+" // just compatible to old version
+       provider.Version = datasource.AllVersions // just compatible to old 
version
        return provider, nil
 }
 
diff --git a/datasource/etcd/util/dependency_util.go 
b/datasource/etcd/util/dependency_util.go
index 48caebc..b03debb 100644
--- a/datasource/etcd/util/dependency_util.go
+++ b/datasource/etcd/util/dependency_util.go
@@ -201,6 +201,34 @@ func parseAddOrUpdateRules(ctx context.Context, dep 
*Dependency) (createDependen
        return
 }
 
+func parseOverrideRules(ctx context.Context, dep *Dependency) 
(createDependencyRuleList, existDependencyRuleList, deleteDependencyRuleList 
[]*pb.MicroServiceKey) {
+       conKey := path.GenerateConsumerDependencyRuleKey(dep.DomainProject, 
dep.Consumer)
+
+       oldProviderRules, err := TransferToMicroServiceDependency(ctx, conKey)
+       if err != nil {
+               log.Error(fmt.Sprintf("override dependency rule failed, get 
consumer[%s/%s/%s/%s]'s dependency rule failed",
+                       dep.Consumer.Environment, dep.Consumer.AppId, 
dep.Consumer.ServiceName, dep.Consumer.Version), err)
+               return
+       }
+
+       deleteDependencyRuleList = make([]*pb.MicroServiceKey, 0, 
len(oldProviderRules.Dependency))
+       createDependencyRuleList = make([]*pb.MicroServiceKey, 0, 
len(dep.ProvidersRule))
+       existDependencyRuleList = make([]*pb.MicroServiceKey, 0, 
len(oldProviderRules.Dependency))
+       for _, oldProviderRule := range oldProviderRules.Dependency {
+               if ok, _ := ContainServiceDependency(dep.ProvidersRule, 
oldProviderRule); !ok {
+                       deleteDependencyRuleList = 
append(deleteDependencyRuleList, oldProviderRule)
+               } else {
+                       existDependencyRuleList = 
append(existDependencyRuleList, oldProviderRule)
+               }
+       }
+       for _, tmpProviderRule := range dep.ProvidersRule {
+               if ok, _ := ContainServiceDependency(existDependencyRuleList, 
tmpProviderRule); !ok {
+                       createDependencyRuleList = 
append(createDependencyRuleList, tmpProviderRule)
+               }
+       }
+       return
+}
+
 func syncDependencyRule(ctx context.Context, dep *Dependency, filter 
func(context.Context, *Dependency) (_, _, _ []*pb.MicroServiceKey)) error {
        //更新consumer的providers的值,consumer的版本是确定的
        consumerFlag := strings.Join([]string{dep.Consumer.Environment, 
dep.Consumer.AppId, dep.Consumer.ServiceName, dep.Consumer.Version}, "/")
@@ -227,6 +255,10 @@ func AddDependencyRule(ctx context.Context, dep 
*Dependency) error {
        return syncDependencyRule(ctx, dep, parseAddOrUpdateRules)
 }
 
+func CreateDependencyRule(ctx context.Context, dep *Dependency) error {
+       return syncDependencyRule(ctx, dep, parseOverrideRules)
+}
+
 func IsNeedUpdate(services []*pb.MicroServiceKey, service *pb.MicroServiceKey) 
*pb.MicroServiceKey {
        for _, tmp := range services {
                if DiffServiceVersion(tmp, service) {
@@ -259,32 +291,6 @@ func BadParamsResponse(detailErr string) 
*pb.CreateDependenciesResponse {
        }
 }
 
-func ParamsChecker(consumerInfo *pb.MicroServiceKey, providersInfo 
[]*pb.MicroServiceKey) *pb.CreateDependenciesResponse {
-       flag := make(map[string]bool, len(providersInfo))
-       for _, providerInfo := range providersInfo {
-               //存在带*的情况,后面的数据就不校验了
-               if providerInfo.ServiceName == "*" {
-                       break
-               }
-               if len(providerInfo.AppId) == 0 {
-                       providerInfo.AppId = consumerInfo.AppId
-               }
-
-               version := providerInfo.Version
-               if len(version) == 0 {
-                       return BadParamsResponse("Required provider version")
-               }
-
-               providerInfo.Version = ""
-               if _, ok := flag[toString(providerInfo)]; ok {
-                       return BadParamsResponse("Invalid request body for 
provider info.Duplicate provider or (serviceName and appId is same).")
-               }
-               flag[toString(providerInfo)] = true
-               providerInfo.Version = version
-       }
-       return nil
-}
-
 func DeleteDependencyForDeleteService(domainProject string, serviceID string, 
service *pb.MicroServiceKey) (etcdadpt.OpOptions, error) {
        key := path.GenerateConsumerDependencyQueueKey(domainProject, 
serviceID, path.DepsQueueUUID)
        conDep := new(pb.ConsumerDependency)
diff --git a/datasource/etcd/util/dependency_util_test.go 
b/datasource/etcd/util/dependency_util_test.go
index f22f061..5e89dce 100644
--- a/datasource/etcd/util/dependency_util_test.go
+++ b/datasource/etcd/util/dependency_util_test.go
@@ -112,56 +112,6 @@ func TestDependencyRuleExistUtil(t *testing.T) {
        }
 }
 
-func TestParamsChecker(t *testing.T) {
-       p := ParamsChecker(nil, nil)
-       if p != nil {
-               t.Fatalf(`ParamsChecker invalid failed`)
-       }
-
-       p = ParamsChecker(&discovery.MicroServiceKey{
-               AppId:       "a",
-               ServiceName: "b",
-               Version:     "1.0.0",
-       }, nil)
-       if p != nil {
-               t.Fatalf(`ParamsChecker invalid failed`)
-       }
-
-       p = ParamsChecker(&discovery.MicroServiceKey{
-               AppId:       "a",
-               ServiceName: "b",
-               Version:     "1.0.0",
-       }, []*discovery.MicroServiceKey{
-               {ServiceName: "*"},
-       })
-       if p != nil {
-               t.Fatalf(`ParamsChecker * failed`)
-       }
-
-       p = ParamsChecker(&discovery.MicroServiceKey{
-               AppId:       "a",
-               ServiceName: "b",
-               Version:     "1.0.0",
-       }, []*discovery.MicroServiceKey{
-               {},
-       })
-       if p == nil {
-               t.Fatalf(`ParamsChecker invalid provider key failed`)
-       }
-
-       p = ParamsChecker(&discovery.MicroServiceKey{
-               AppId:       "a",
-               ServiceName: "b",
-               Version:     "1.0.0",
-       }, []*discovery.MicroServiceKey{
-               {ServiceName: "a", Version: "1"},
-               {ServiceName: "a", Version: "1"},
-       })
-       if p == nil {
-               t.Fatalf(`ParamsChecker duplicate provider key failed`)
-       }
-}
-
 func TestServiceDependencyRuleExist(t *testing.T) {
        _, err := DependencyRuleExist(context.Background(), 
&discovery.MicroServiceKey{}, &discovery.MicroServiceKey{})
        if err != nil {
diff --git a/datasource/mongo/dep.go b/datasource/mongo/dep.go
index d83da13..03e2202 100644
--- a/datasource/mongo/dep.go
+++ b/datasource/mongo/dep.go
@@ -110,6 +110,64 @@ func (ds *DepManager) SearchConsumerDependency(ctx 
context.Context, request *dis
        }, nil
 }
 
+func (ds *DepManager) AddOrUpdateDependencies(ctx context.Context, dependencys 
[]*discovery.ConsumerDependency, override bool) (*discovery.Response, error) {
+       domainProject := util.ParseDomainProject(ctx)
+       for _, dependency := range dependencys {
+               consumerFlag := util.StringJoin([]string{
+                       dependency.Consumer.Environment,
+                       dependency.Consumer.AppId,
+                       dependency.Consumer.ServiceName,
+                       dependency.Consumer.Version}, "/")
+               consumerInfo := 
discovery.DependenciesToKeys([]*discovery.MicroServiceKey{dependency.Consumer}, 
domainProject)[0]
+               providersInfo := 
discovery.DependenciesToKeys(dependency.Providers, domainProject)
+
+               rsp := datasource.ParamsChecker(consumerInfo, providersInfo)
+               if rsp != nil {
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t consumer is %s %s",
+                               override, consumerFlag, 
rsp.Response.GetMessage()), nil)
+                       return rsp.Response, nil
+               }
+
+               consumerID, err := GetServiceID(ctx, consumerInfo)
+               if err != nil && !errors.Is(err, datasource.ErrNoData) {
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t, get consumer %s id failed",
+                               override, consumerFlag), err)
+                       return discovery.CreateResponse(discovery.ErrInternal, 
err.Error()), err
+               }
+               if len(consumerID) == 0 {
+                       log.Error(fmt.Sprintf("put request into dependency 
queue failed, override: %t consumer %s does not exist",
+                               override, consumerFlag), err)
+                       return 
discovery.CreateResponse(discovery.ErrServiceNotExists, fmt.Sprintf("Consumer 
%s does not exist.", consumerFlag)), nil
+               }
+
+               dependency.Override = override
+               if !override {
+                       id := util.GenerateUUID()
+
+                       domain := util.ParseDomain(ctx)
+                       project := util.ParseProject(ctx)
+                       data := &model.ConsumerDep{
+                               Domain:      domain,
+                               Project:     project,
+                               ConsumerID:  consumerID,
+                               UUID:        id,
+                               ConsumerDep: dependency,
+                       }
+                       insertRes, err := client.GetMongoClient().Insert(ctx, 
model.CollectionDep, data)
+                       if err != nil {
+                               log.Error("failed to insert dep to mongodb", 
err)
+                               return 
discovery.CreateResponse(discovery.ErrInternal, err.Error()), err
+                       }
+                       log.Info(fmt.Sprintf("insert dep to mongodb success 
%s", insertRes.InsertedID))
+               }
+               err = syncDependencyRule(ctx, domainProject, dependency)
+               if err != nil {
+                       return nil, err
+               }
+       }
+       return discovery.CreateResponse(discovery.ResponseSuccess, "Create 
dependency successfully."), nil
+}
+
 func (ds *DepManager) DependencyHandle(ctx context.Context) (err error) {
        return nil
 }
@@ -130,7 +188,11 @@ func syncDependencyRule(ctx context.Context, domainProject 
string, r *discovery.
        if err != nil {
                return err
        }
-       datasource.ParseAddOrUpdateRules(ctx, &dep, oldProviderRules)
+       if r.Override {
+               datasource.ParseOverrideRules(ctx, &dep, oldProviderRules)
+       } else {
+               datasource.ParseAddOrUpdateRules(ctx, &dep, oldProviderRules)
+       }
        return updateDeps(domainProject, &dep)
 }
 
diff --git a/integration/apis.go b/integration/apis.go
index 6debf13..a1a4f2b 100644
--- a/integration/apis.go
+++ b/integration/apis.go
@@ -32,6 +32,7 @@ var UPDATESCHEMA = 
"/v4/default/registry/microservices/:serviceId/schemas/:schem
 var GETSCHEMAS = "/v4/default/registry/microservices/:serviceId/schemas"
 var UPDATESCHEMAS = "/v4/default/registry/microservices/:serviceId/schemas"
 var DELETESCHEMA = 
"/v4/default/registry/microservices/:serviceId/schemas/:schemaId"
+var CREATEDEPENDENCIES = "/v4/default/registry/dependencies"
 var GETCONPRODEPENDENCY = 
"/v4/default/registry/microservices/:consumerId/providers"
 var GETPROCONDEPENDENCY = 
"/v4/default/registry/microservices/:providerId/consumers"
 
diff --git a/integration/microservices_test.go 
b/integration/microservices_test.go
index ee3027d..a78c493 100644
--- a/integration/microservices_test.go
+++ b/integration/microservices_test.go
@@ -17,9 +17,6 @@
 package integrationtest_test
 
 import (
-       . "github.com/onsi/ginkgo"
-       . "github.com/onsi/gomega"
-
        "bytes"
        "encoding/json"
        "io/ioutil"
@@ -28,8 +25,12 @@ import (
        "strconv"
        "strings"
        "testing"
+       "time"
 
        . "github.com/apache/servicecomb-service-center/integration"
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
+
        "github.com/widuu/gojson"
 )
 
@@ -260,6 +261,267 @@ var _ = Describe("MicroService Api Test", func() {
                        })
 
                        By("Test Dependency API for Provider and Consumer", 
func() {
+                               It("test Valid dependency creation", func() {
+                                       //Register second microservice
+                                       getServiceName(serviceId)
+                                       schema := []string{"testSchema"}
+                                       properties := 
map[string]string{"attr1": "aa"}
+                                       consumerApp := 
strconv.Itoa(rand.Intn(15))
+                                       servicemap := map[string]interface{}{
+                                               "serviceName": consumerApp,
+                                               "appId":       "consumerAppId",
+                                               "version":     "2.0.0",
+                                               "description": "examples",
+                                               "level":       "FRONT",
+                                               "schemas":     schema,
+                                               "status":      "UP",
+                                               "properties":  properties,
+                                       }
+                                       bodyParams := map[string]interface{}{
+                                               "service": servicemap,
+                                       }
+                                       body, _ := json.Marshal(bodyParams)
+                                       bodyBuf := bytes.NewReader(body)
+                                       req, _ := http.NewRequest(POST, 
SCURL+REGISTERMICROSERVICE, bodyBuf)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, err := scclient.Do(req)
+                                       Expect(err).To(BeNil())
+                                       defer resp.Body.Close()
+
+                                       // Validate the service creation
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       respbody, _ := ioutil.ReadAll(resp.Body)
+                                       consumerServiceID := 
gojson.Json(string(respbody)).Get("serviceId").Tostring()
+
+                                       //Create Dependency
+                                       consumer := map[string]string{
+                                               "appId":       "consumerAppId",
+                                               "serviceName": consumerApp,
+                                               "version":     "2.0.0",
+                                       }
+                                       provider := map[string]string{
+                                               "appId":       serviceAppId,
+                                               "serviceName": serviceName,
+                                               "version":     serviceVersion,
+                                       }
+                                       providersArray := 
[]interface{}{provider}
+                                       dependency := map[string]interface{}{
+                                               "consumer":  consumer,
+                                               "providers": providersArray,
+                                       }
+                                       dependencyArray := 
[]interface{}{dependency}
+                                       bodyParams = map[string]interface{}{
+                                               "dependencies": dependencyArray,
+                                       }
+                                       body, _ = json.Marshal(bodyParams)
+                                       bodyBuf = bytes.NewReader(body)
+                                       req, _ = http.NewRequest(UPDATE, 
SCURL+CREATEDEPENDENCIES, bodyBuf)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, err = scclient.Do(req)
+                                       Expect(err).To(BeNil())
+                                       defer resp.Body.Close()
+
+                                       // Validate the dependency creation
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+                                       /*
+                                               //Now try to delete the 
provider //this will fail as consumer needs to be deleted first
+                                               url := 
strings.Replace(UNREGISTERMICROSERVICE, ":serviceId", serviceId, 1)
+                                               req, _ = 
http.NewRequest(DELETE, SCURL+url, nil)
+                                               req.Header.Set("X-Domain-Name", 
"default")
+                                               resp, _ = scclient.Do(req)
+                                               
Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))*/
+
+                                       //Now delete consumer and then provider
+
+                                       url := 
strings.Replace(UNREGISTERMICROSERVICE, ":serviceId", consumerServiceID, 1)
+                                       req, _ = http.NewRequest(DELETE, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+                                       url = 
strings.Replace(UNREGISTERMICROSERVICE, ":serviceId", serviceId, 1)
+                                       req, _ = http.NewRequest(DELETE, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       serviceId = ""
+
+                               })
+
+                               It("Get Dependencies for providers and 
consumers", func() {
+                                       getServiceName(serviceId)
+                                       schema := []string{"testSchema"}
+                                       properties := 
map[string]string{"attr1": "aa"}
+                                       consumerAppName := 
strconv.Itoa(rand.Intn(15))
+                                       servicemap := map[string]interface{}{
+                                               "serviceName": consumerAppName,
+                                               "appId":       "consumerAppId",
+                                               "version":     "2.0.0",
+                                               "description": "examples",
+                                               "level":       "FRONT",
+                                               "schemas":     schema,
+                                               "status":      "UP",
+                                               "properties":  properties,
+                                       }
+                                       bodyParams := map[string]interface{}{
+                                               "service": servicemap,
+                                       }
+                                       body, _ := json.Marshal(bodyParams)
+                                       bodyBuf := bytes.NewReader(body)
+                                       req, _ := http.NewRequest(POST, 
SCURL+REGISTERMICROSERVICE, bodyBuf)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, err := scclient.Do(req)
+                                       Expect(err).To(BeNil())
+                                       defer resp.Body.Close()
+
+                                       // Validate the service creation
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       respbody, _ := ioutil.ReadAll(resp.Body)
+                                       consumerServiceID := 
gojson.Json(string(respbody)).Get("serviceId").Tostring()
+
+                                       //Create Dependency
+                                       consumer := map[string]string{
+                                               "appId":       "consumerAppId",
+                                               "serviceName": consumerAppName,
+                                               "version":     "2.0.0",
+                                       }
+                                       provider := map[string]string{
+                                               "appId":       serviceAppId,
+                                               "serviceName": serviceName,
+                                               "version":     serviceVersion,
+                                       }
+                                       providersArray := 
[]interface{}{provider}
+                                       dependency := map[string]interface{}{
+                                               "consumer":  consumer,
+                                               "providers": providersArray,
+                                       }
+                                       dependencyArray := 
[]interface{}{dependency}
+                                       bodyParams = map[string]interface{}{
+                                               "dependencies": dependencyArray,
+                                       }
+                                       body, _ = json.Marshal(bodyParams)
+                                       bodyBuf = bytes.NewReader(body)
+                                       req, _ = http.NewRequest(UPDATE, 
SCURL+CREATEDEPENDENCIES, bodyBuf)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, err = scclient.Do(req)
+                                       Expect(err).To(BeNil())
+                                       defer resp.Body.Close()
+
+                                       // Validate the dependency creation
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+                                       // add new dependency
+                                       dependency["providers"] = 
[]interface{}{consumer}
+                                       body, _ = json.Marshal(bodyParams)
+                                       bodyBuf = bytes.NewReader(body)
+                                       req, _ = http.NewRequest(POST, 
SCURL+CREATEDEPENDENCIES, bodyBuf)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, err = scclient.Do(req)
+                                       Expect(err).To(BeNil())
+                                       defer resp.Body.Close()
+
+                                       // Validate the dependency creation
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+                                       //Get Provider by ConsumerID
+                                       <-time.After(time.Second)
+                                       url := 
strings.Replace(GETCONPRODEPENDENCY, ":consumerId", consumerServiceID, 1)
+                                       req, _ = http.NewRequest(GET, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       respbody, _ = ioutil.ReadAll(resp.Body)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       servicesStruct := 
map[string][]map[string]interface{}{}
+
+                                       json.Unmarshal(respbody, 
&servicesStruct)
+                                       foundMicroService := false
+                                       for _, services := range 
servicesStruct["providers"] {
+                                               if services["serviceName"] == 
serviceName {
+                                                       foundMicroService = true
+                                                       break
+                                               }
+                                       }
+                                       
Expect(foundMicroService).To(Equal(true))
+
+                                       //Get Consumer by ProviderID
+                                       url = 
strings.Replace(GETPROCONDEPENDENCY, ":providerId", serviceId, 1)
+                                       req, _ = http.NewRequest(GET, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       respbody, _ = ioutil.ReadAll(resp.Body)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       servicesStruct = 
map[string][]map[string]interface{}{}
+
+                                       json.Unmarshal(respbody, 
&servicesStruct)
+                                       foundMicroService = false
+                                       for _, services := range 
servicesStruct["consumers"] {
+                                               if services["serviceName"] == 
consumerAppName {
+                                                       foundMicroService = true
+                                                       break
+                                               }
+                                       }
+                                       
Expect(foundMicroService).To(Equal(true))
+
+                                       //Get new dependency by ConsumerID
+                                       url = 
strings.Replace(GETCONPRODEPENDENCY, ":consumerId", consumerServiceID, 1)
+                                       req, _ = http.NewRequest(GET, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       respbody, _ = ioutil.ReadAll(resp.Body)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       servicesStruct = 
map[string][]map[string]interface{}{}
+
+                                       json.Unmarshal(respbody, 
&servicesStruct)
+                                       foundMicroService = false
+                                       for _, services := range 
servicesStruct["providers"] {
+                                               if services["serviceName"] == 
consumerAppName {
+                                                       foundMicroService = true
+                                                       break
+                                               }
+                                       }
+                                       
Expect(foundMicroService).To(Equal(true))
+
+                                       // override the dependency
+                                       dependency["providers"] = 
[]interface{}{}
+                                       body, _ = json.Marshal(bodyParams)
+                                       bodyBuf = bytes.NewReader(body)
+                                       req, _ = http.NewRequest(UPDATE, 
SCURL+CREATEDEPENDENCIES, bodyBuf)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, err = scclient.Do(req)
+                                       Expect(err).To(BeNil())
+                                       defer resp.Body.Close()
+
+                                       // Validate the dependency creation
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+                                       //Get Provider by ConsumerID again
+                                       <-time.After(time.Second)
+                                       url = 
strings.Replace(GETCONPRODEPENDENCY, ":consumerId", consumerServiceID, 1)
+                                       req, _ = http.NewRequest(GET, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       respbody, _ = ioutil.ReadAll(resp.Body)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       servicesStruct = 
map[string][]map[string]interface{}{}
+                                       json.Unmarshal(respbody, 
&servicesStruct)
+                                       
Expect(len(servicesStruct["providers"])).To(Equal(0))
+
+                                       //Delete Consumer and Provider
+                                       url = 
strings.Replace(UNREGISTERMICROSERVICE, ":serviceId", consumerServiceID, 1)
+                                       req, _ = http.NewRequest(DELETE, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+
+                                       url = 
strings.Replace(UNREGISTERMICROSERVICE, ":serviceId", serviceId, 1)
+                                       req, _ = http.NewRequest(DELETE, 
SCURL+url, nil)
+                                       req.Header.Set("X-Domain-Name", 
"default")
+                                       resp, _ = scclient.Do(req)
+                                       
Expect(resp.StatusCode).To(Equal(http.StatusOK))
+                                       serviceId = ""
+                               })
+
                                It("Invalid scenario for GET Providers and 
Consumers", func() {
                                        //Get Provider by ConsumerID
                                        url := 
strings.Replace(GETCONPRODEPENDENCY, ":consumerId", "wrongID", 1)
diff --git a/pkg/proto/service.go b/pkg/proto/service.go
index 5767d98..1cf5faf 100644
--- a/pkg/proto/service.go
+++ b/pkg/proto/service.go
@@ -42,6 +42,8 @@ type ServiceCtrlServer interface {
        DeleteSchema(context.Context, *discovery.DeleteSchemaRequest) 
(*discovery.DeleteSchemaResponse, error)
        ModifySchema(context.Context, *discovery.ModifySchemaRequest) 
(*discovery.ModifySchemaResponse, error)
        ModifySchemas(context.Context, *discovery.ModifySchemasRequest) 
(*discovery.ModifySchemasResponse, error)
+       AddDependenciesForMicroServices(context.Context, 
*discovery.AddDependenciesRequest) (*discovery.AddDependenciesResponse, error)
+       CreateDependenciesForMicroServices(context.Context, 
*discovery.CreateDependenciesRequest) (*discovery.CreateDependenciesResponse, 
error)
        GetProviderDependencies(context.Context, 
*discovery.GetDependenciesRequest) (*discovery.GetProDependenciesResponse, 
error)
        GetConsumerDependencies(context.Context, 
*discovery.GetDependenciesRequest) (*discovery.GetConDependenciesResponse, 
error)
        DeleteServices(context.Context, *discovery.DelServicesRequest) 
(*discovery.DelServicesResponse, error)
diff --git a/server/rest/controller/v4/dependency_controller.go 
b/server/rest/controller/v4/dependency_controller.go
index d2607c4..a3791e8 100644
--- a/server/rest/controller/v4/dependency_controller.go
+++ b/server/rest/controller/v4/dependency_controller.go
@@ -18,9 +18,14 @@
 package v4
 
 import (
+       "encoding/json"
+       "fmt"
+       "io/ioutil"
        "net/http"
 
+       "github.com/apache/servicecomb-service-center/pkg/log"
        "github.com/apache/servicecomb-service-center/pkg/rest"
+       "github.com/apache/servicecomb-service-center/pkg/util"
        "github.com/apache/servicecomb-service-center/server/core"
        pb "github.com/go-chassis/cari/discovery"
 )
@@ -30,11 +35,61 @@ type DependencyService struct {
 
 func (s *DependencyService) URLPatterns() []rest.Route {
        return []rest.Route{
+               {Method: http.MethodPost, Path: 
"/v4/:project/registry/dependencies", Func: s.AddDependenciesForMicroServices},
+               {Method: http.MethodPut, Path: 
"/v4/:project/registry/dependencies", Func: 
s.CreateDependenciesForMicroServices},
                {Method: http.MethodGet, Path: 
"/v4/:project/registry/microservices/:consumerId/providers", Func: 
s.GetConProDependencies},
                {Method: http.MethodGet, Path: 
"/v4/:project/registry/microservices/:providerId/consumers", Func: 
s.GetProConDependencies},
        }
 }
 
+//Deprecated
+func (s *DependencyService) AddDependenciesForMicroServices(w 
http.ResponseWriter, r *http.Request) {
+       requestBody, err := ioutil.ReadAll(r.Body)
+       if err != nil {
+               log.Error("read body failed", err)
+               rest.WriteError(w, pb.ErrInvalidParams, err.Error())
+               return
+       }
+       request := &pb.AddDependenciesRequest{}
+       err = json.Unmarshal(requestBody, request)
+       if err != nil {
+               log.Error(fmt.Sprintf("invalid json: %s", 
util.BytesToStringWithNoCopy(requestBody)), err)
+               rest.WriteError(w, pb.ErrInvalidParams, err.Error())
+               return
+       }
+
+       resp, err := 
core.ServiceAPI.AddDependenciesForMicroServices(r.Context(), request)
+       if err != nil {
+               rest.WriteError(w, pb.ErrInternal, err.Error())
+       }
+       w.Header().Add("Deprecation", "version=\"v4\"")
+       rest.WriteResponse(w, r, resp.Response, nil)
+}
+
+//Deprecated
+func (s *DependencyService) CreateDependenciesForMicroServices(w 
http.ResponseWriter, r *http.Request) {
+       requestBody, err := ioutil.ReadAll(r.Body)
+       if err != nil {
+               log.Error("read body failed", err)
+               rest.WriteError(w, pb.ErrInvalidParams, err.Error())
+               return
+       }
+       request := &pb.CreateDependenciesRequest{}
+       err = json.Unmarshal(requestBody, request)
+       if err != nil {
+               log.Error(fmt.Sprintf("invalid json: %s", 
util.BytesToStringWithNoCopy(requestBody)), err)
+               rest.WriteError(w, pb.ErrInvalidParams, err.Error())
+               return
+       }
+
+       resp, err := 
core.ServiceAPI.CreateDependenciesForMicroServices(r.Context(), request)
+       if err != nil {
+               rest.WriteError(w, pb.ErrInternal, err.Error())
+       }
+       w.Header().Add("Deprecation", "version=\"v4\"")
+       rest.WriteResponse(w, r, resp.Response, nil)
+}
+
 func (s *DependencyService) GetConProDependencies(w http.ResponseWriter, r 
*http.Request) {
        query := r.URL.Query()
        request := &pb.GetDependenciesRequest{
diff --git a/server/service/disco/dependency.go 
b/server/service/disco/dependency.go
index ea083a6..4169829 100644
--- a/server/service/disco/dependency.go
+++ b/server/service/disco/dependency.go
@@ -26,6 +26,30 @@ import (
        pb "github.com/go-chassis/cari/discovery"
 )
 
+func (s *MicroServiceService) AddDependenciesForMicroServices(ctx 
context.Context,
+       in *pb.AddDependenciesRequest) (*pb.AddDependenciesResponse, error) {
+       if err := validator.Validate(in); err != nil {
+               return &pb.AddDependenciesResponse{
+                       Response: 
datasource.BadParamsResponse(err.Error()).Response,
+               }, nil
+       }
+
+       resp, err := 
datasource.GetDependencyManager().AddOrUpdateDependencies(ctx, in.Dependencies, 
false)
+       return &pb.AddDependenciesResponse{Response: resp}, err
+}
+
+func (s *MicroServiceService) CreateDependenciesForMicroServices(ctx 
context.Context,
+       in *pb.CreateDependenciesRequest) (*pb.CreateDependenciesResponse, 
error) {
+       if err := validator.Validate(in); err != nil {
+               return &pb.CreateDependenciesResponse{
+                       Response: 
datasource.BadParamsResponse(err.Error()).Response,
+               }, nil
+       }
+
+       resp, err := 
datasource.GetDependencyManager().AddOrUpdateDependencies(ctx, in.Dependencies, 
true)
+       return &pb.CreateDependenciesResponse{Response: resp}, err
+}
+
 func (s *MicroServiceService) GetProviderDependencies(ctx context.Context,
        in *pb.GetDependenciesRequest) (*pb.GetProDependenciesResponse, error) {
        err := validator.Validate(in)
diff --git a/server/service/disco/dependency_test.go 
b/server/service/disco/dependency_test.go
index 4bcae90..ea9a41d 100644
--- a/server/service/disco/dependency_test.go
+++ b/server/service/disco/dependency_test.go
@@ -17,21 +17,436 @@
 package disco_test
 
 import (
+       "strconv"
+
        . "github.com/onsi/ginkgo"
        . "github.com/onsi/gomega"
 
-       "github.com/apache/servicecomb-service-center/datasource/etcd/event"
-       "github.com/apache/servicecomb-service-center/datasource/etcd/path"
-       "github.com/apache/servicecomb-service-center/datasource/etcd/sd"
+       "github.com/apache/servicecomb-service-center/datasource"
        "github.com/apache/servicecomb-service-center/server/service/disco"
        pb "github.com/go-chassis/cari/discovery"
-       "github.com/go-chassis/go-archaius"
-       "github.com/little-cui/etcdadpt"
 )
 
-var deh event.DependencyEventHandler
-
 var _ = Describe("'Dependency' service", func() {
+       Describe("execute 'create' operation", func() {
+               var (
+                       consumerId1 string
+                       consumerId2 string
+               )
+
+               It("should be passed", func() {
+                       respCreateService, err := 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       AppId:       "create_dep_group",
+                                       ServiceName: "create_dep_consumer",
+                                       Version:     "1.0.0",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       Expect(err).To(BeNil())
+                       
Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                       consumerId1 = respCreateService.ServiceId
+
+                       respCreateService, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       Environment: pb.ENV_PROD,
+                                       AppId:       "create_dep_group",
+                                       ServiceName: "create_dep_consumer",
+                                       Version:     "1.0.0",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       Expect(err).To(BeNil())
+                       
Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                       consumerId2 = respCreateService.ServiceId
+
+                       respCreateService, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       AppId:       "create_dep_group",
+                                       ServiceName: "create_dep_provider",
+                                       Version:     "1.0.0",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       Expect(err).To(BeNil())
+                       
Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                       respCreateService, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       AppId:       "create_dep_group",
+                                       ServiceName: "create_dep_provider",
+                                       Version:     "1.0.1",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       Expect(err).To(BeNil())
+                       
Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                       respCreateService, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       Environment: pb.ENV_PROD,
+                                       AppId:       "create_dep_group",
+                                       ServiceName: "create_dep_provider",
+                                       Version:     "1.0.0",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       Expect(err).To(BeNil())
+                       
Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                       respCreateService, err = 
serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+                               Service: &pb.MicroService{
+                                       AppId:       "create_dep_group",
+                                       ServiceName: 
"create_dep_provider_other",
+                                       Version:     "1.0.0",
+                                       Level:       "FRONT",
+                                       Status:      pb.MS_UP,
+                               },
+                       })
+                       Expect(err).To(BeNil())
+                       
Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+               })
+
+               Context("when request is invalid", func() {
+                       It("should be failed", func() {
+                               By("dependency is nil")
+                               respCreateDependency, err := 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{})
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
+
+                               consumer := &pb.MicroServiceKey{
+                                       AppId:       "create_dep_group",
+                                       ServiceName: "create_dep_consumer",
+                                       Version:     "1.0.0",
+                               }
+                               providers := []*pb.MicroServiceKey{
+                                       {
+                                               AppId:       "create_dep_group",
+                                               ServiceName: 
"create_dep_provider",
+                                       },
+                               }
+
+                               By("consumer does not exist")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"noexistapp",
+                                                               ServiceName: 
"noexistservice",
+                                                               Version:     
"1.0.0",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
+
+                               By("provider version is invalid")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       AppId:  
     "create_dep_group",
+                                                                       
ServiceName: "",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+
+                               By("consumer version is invalid")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"create_dep_group",
+                                                               ServiceName: 
"create_dep_consumer",
+                                                               Version:     
"1.0.0+",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"create_dep_group",
+                                                               ServiceName: 
"create_dep_consumer",
+                                                               Version:     
"1.0.0-1.0.1",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"create_dep_group",
+                                                               ServiceName: 
"create_dep_consumer",
+                                                               Version:     
"latest",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"create_dep_group",
+                                                               ServiceName: 
"create_dep_consumer",
+                                                               Version:     "",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"create_dep_group",
+                                                               ServiceName: 
"create_dep_consumer",
+                                                               Version:     
"1.0.32768",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+
+                               By("consumer serviceName is invalid")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: 
&pb.MicroServiceKey{
+                                                               AppId:       
"create_dep_group",
+                                                               ServiceName: 
"*",
+                                                               Version:     
"1.0.0",
+                                                       },
+                                                       Providers: providers,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
+
+                               By("provider app is invalid")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       AppId:  
     "*",
+                                                                       
ServiceName: "service_name_provider",
+                                                                       
Version:     "2.0.0",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
+
+                               By("provider serviceName is invalid")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       AppId:  
     "service_group_provider",
+                                                                       
ServiceName: "-",
+                                                                       
Version:     "2.0.0",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
+
+                               By("provider in diff env")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       
Environment: pb.ENV_PROD,
+                                                                       AppId:  
     "service_group_provider",
+                                                                       
ServiceName: "service_name_provider",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                               By("consumer in diff env")
+                               consumer.Environment = pb.ENV_PROD
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       AppId:  
     "service_group_provider",
+                                                                       
ServiceName: "service_name_provider",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                               DependencyHandle()
+
+                               respCon, err := 
serviceResource.GetConsumerDependencies(getContext(), 
&pb.GetDependenciesRequest{
+                                       ServiceId: consumerId1,
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCon.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                               Expect(len(respCon.Providers)).To(Equal(0))
+
+                               respCon, err = 
serviceResource.GetConsumerDependencies(getContext(), 
&pb.GetDependenciesRequest{
+                                       ServiceId: consumerId2,
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCon.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                               Expect(len(respCon.Providers)).To(Equal(0))
+
+                               By("dependencies is invalid")
+                               var deps []*pb.ConsumerDependency
+                               for i := 0; i < 101; i++ {
+                                       deps = append(deps, 
&pb.ConsumerDependency{
+                                               Consumer: &pb.MicroServiceKey{
+                                                       AppId:       
"create_dep_group",
+                                                       ServiceName: 
"create_dep_consumer" + strconv.Itoa(i),
+                                                       Version:     "1.0.0",
+                                               },
+                                               Providers: 
[]*pb.MicroServiceKey{
+                                                       {
+                                                               AppId:       
"service_group_provider",
+                                                               ServiceName: 
"service_name_provider",
+                                                       },
+                                               },
+                                       })
+                               }
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: deps,
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+                       })
+               })
+
+               Context("when request is valid", func() {
+                       It("should be passed", func() {
+                               consumer := &pb.MicroServiceKey{
+                                       ServiceName: "create_dep_consumer",
+                                       AppId:       "create_dep_group",
+                                       Version:     "1.0.0",
+                               }
+
+                               respCreateDependency, err := 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       AppId:  
     "create_dep_group",
+                                                                       
ServiceName: "create_dep_provider",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                               DependencyHandle()
+
+                               respPro, err := 
serviceResource.GetConsumerDependencies(getContext(), 
&pb.GetDependenciesRequest{
+                                       ServiceId: consumerId1,
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respPro.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                               Expect(len(respPro.Providers)).To(Equal(2))
+
+                               respAddDependency, err := 
serviceResource.AddDependenciesForMicroServices(getContext(), 
&pb.AddDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer: consumer,
+                                                       Providers: 
[]*pb.MicroServiceKey{
+                                                               {
+                                                                       AppId:  
     "create_dep_group",
+                                                                       
ServiceName: "create_dep_provider_other",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respAddDependency.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                               DependencyHandle()
+
+                               respPro, err = 
serviceResource.GetConsumerDependencies(getContext(), 
&pb.GetDependenciesRequest{
+                                       ServiceId: consumerId1,
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respPro.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                               Expect(len(respPro.Providers)).To(Equal(3))
+
+                               By("clean all")
+                               respCreateDependency, err = 
serviceResource.CreateDependenciesForMicroServices(getContext(), 
&pb.CreateDependenciesRequest{
+                                       Dependencies: []*pb.ConsumerDependency{
+                                               {
+                                                       Consumer:  consumer,
+                                                       Providers: nil,
+                                               },
+                                       },
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respCreateDependency.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+
+                               DependencyHandle()
+
+                               respPro, err = 
serviceResource.GetConsumerDependencies(getContext(), 
&pb.GetDependenciesRequest{
+                                       ServiceId: consumerId1,
+                               })
+                               Expect(err).To(BeNil())
+                               
Expect(respPro.Response.GetCode()).To(Equal(pb.ResponseSuccess))
+                               Expect(len(respPro.Providers)).To(Equal(0))
+                       })
+               })
+       })
+
        Describe("execute 'get' operation", func() {
                var (
                        consumerId1 string
@@ -279,24 +694,6 @@ var _ = Describe("'Dependency' service", func() {
 })
 
 func DependencyHandle() {
-       t := archaius.Get("TEST_MODE")
-       if t == nil {
-               t = "etcd"
-       }
-       if t == "etcd" {
-               for {
-                       Expect(deh.Handle()).To(BeNil())
-
-                       key := path.GetServiceDependencyQueueRootKey("")
-                       resp, err := sd.DependencyQueue().Search(getContext(),
-                               etcdadpt.WithStrKey(key), 
etcdadpt.WithPrefix(), etcdadpt.WithCountOnly())
-
-                       Expect(err).To(BeNil())
-
-                       // maintain dependency rules.
-                       if resp.Count == 0 {
-                               break
-                       }
-               }
-       }
+       err := datasource.GetDependencyManager().DependencyHandle(getContext())
+       Expect(err).To(BeNil())
 }
diff --git a/server/service/validator/dependency_validator.go 
b/server/service/validator/dependency_validator.go
new file mode 100644
index 0000000..7a349b3
--- /dev/null
+++ b/server/service/validator/dependency_validator.go
@@ -0,0 +1,70 @@
+/*
+ * 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 in 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 in 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 validator
+
+import (
+       "regexp"
+
+       "github.com/apache/servicecomb-service-center/pkg/validate"
+)
+
+var (
+       addDependenciesReqValidator       validate.Validator
+       overwriteDependenciesReqValidator validate.Validator
+)
+
+var versionAllowEmptyRegex, _ = 
regexp.Compile(`^(^\d+(\.\d+){0,2}\+?$|^\d+(\.\d+){0,2}-\d+(\.\d+){0,2}$|^latest$)?$`)
+
+func defaultDependencyValidator() *validate.Validator {
+       appIDRule := *(MicroServiceKeyValidator().GetRule("AppId"))
+       appIDRule.Min = 0
+       versionRule := &validate.Rule{Max: 128, Regexp: 
&validate.VersionRegexp{Fuzzy: true, Regex: versionAllowEmptyRegex}}
+
+       var (
+               consumerMsValidator validate.Validator
+               providerMsValidator validate.Validator
+       )
+       consumerMsValidator.AddRules(MicroServiceKeyValidator().GetRules())
+
+       providerMsValidator.AddRules(MicroServiceKeyValidator().GetRules())
+       providerMsValidator.AddRule("AppId", &appIDRule)
+       providerMsValidator.AddRule("Version", versionRule)
+
+       var dependenciesValidator validate.Validator
+       dependenciesValidator.AddRule("Consumer", &validate.Rule{Min: 1})
+       dependenciesValidator.AddSub("Consumer", &consumerMsValidator)
+       dependenciesValidator.AddSub("Providers", &providerMsValidator)
+
+       return &dependenciesValidator
+}
+
+func AddDependenciesReqValidator() *validate.Validator {
+       return addDependenciesReqValidator.Init(func(v *validate.Validator) {
+               dep := defaultDependencyValidator()
+               dep.AddRule("Providers", &validate.Rule{Min: 1})
+               v.AddRule("Dependencies", &validate.Rule{Min: 1, Max: 100})
+               v.AddSub("Dependencies", dep)
+       })
+}
+
+func CreateDependenciesReqValidator() *validate.Validator {
+       return overwriteDependenciesReqValidator.Init(func(v 
*validate.Validator) {
+               v.AddRule("Dependencies", &validate.Rule{Min: 1, Max: 100})
+               v.AddSub("Dependencies", defaultDependencyValidator())
+       })
+}
diff --git a/server/service/validator/validator.go 
b/server/service/validator/validator.go
index 055fc24..2b1c0be 100644
--- a/server/service/validator/validator.go
+++ b/server/service/validator/validator.go
@@ -65,6 +65,10 @@ func Validate(v interface{}) error {
                *pb.DeleteServiceRequest,
                *pb.GetDependenciesRequest:
                return GetServiceReqValidator().Validate(v)
+       case *pb.CreateDependenciesRequest:
+               return CreateDependenciesReqValidator().Validate(v)
+       case *pb.AddDependenciesRequest:
+               return AddDependenciesReqValidator().Validate(v)
        case *pb.UpdateServicePropsRequest:
                return UpdateServicePropsReqValidator().Validate(v)
        case *pb.GetServiceTagsRequest:

Reply via email to